Skip to content
Snippets Groups Projects
Commit e5134f40 authored by Per's avatar Per
Browse files

more examples

parent 7af0b044
No related branches found
No related tags found
No related merge requests found
......@@ -4,11 +4,16 @@
"version": "2.0.0",
"tasks": [
{
"type": "cargo",
"subcommand": "build",
"type": "shell",
"label": "cargo check --example main_span_expr",
"command": "cargo check --example main_span_expr",
"problemMatcher": [
"$rustc"
]
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
\ No newline at end of file
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "bytecount"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.9"
......@@ -10,6 +15,7 @@ name = "first"
version = "0.1.0"
dependencies = [
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -39,6 +45,16 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nom_locate"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
......@@ -98,10 +114,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum lexical-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b0f90c979adde96d19eb10eb6431ba0c441e2f9e9bdff868b2f6f5114ff519"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca"
"checksum nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f932834fd8e391fc7710e2ba17e8f9f8645d846b55aa63207e17e110a1e1ce35"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
......
......@@ -26,12 +26,14 @@ pub enum Expr<'a> {
BinOp(Span<'a>, Box<Expr<'a>>, Op, Box<Expr<'a>>),
}
// this is the definititon of IResult
// type IResult<I, O, E = u32> = Result<(I, O), Err<I, E>>;
pub fn parse_i32(i: Span) -> IResult<Span, Expr> {
map(digit1, |digit_str: Span| {
Expr::Num(digit_str, digit_str.fragment.parse::<i32>().unwrap())
})(i)
// below is just an exapmle on howto generate an Error explicitly
// Err(Err::Error((i, ErrorKind::Alpha)))
}
......
extern crate nom;
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::{digit1, multispace0},
combinator::map,
sequence::{preceded, tuple},
IResult,
};
use nom_locate::LocatedSpan;
type Span<'a> = LocatedSpan<&'a str>;
#[derive(Debug, PartialEq)]
pub enum Op {
Add,
Sub,
}
type SpanOp<'a> = (Span<'a>, Op);
fn parse_op(i: Span) -> IResult<Span, SpanOp> {
alt((
map(tag("+"), |s| (s, Op::Add)),
map(tag("-"), |s| (s, Op::Sub)),
))(i)
}
#[derive(Debug, PartialEq)]
pub enum Expr<'a> {
Num(i32),
BinOp(Box<SpanExpr<'a>>, SpanOp<'a>, Box<SpanExpr<'a>>),
}
type SpanExpr<'a> = (Span<'a>, Expr<'a>);
pub fn parse_i32(i: Span) -> IResult<Span, SpanExpr> {
map(digit1, |digit_str: Span| {
(
digit_str,
Expr::Num(digit_str.fragment.parse::<i32>().unwrap()),
)
})(i)
}
fn parse_expr(i: Span) -> IResult<Span, SpanExpr> {
alt((
map(
tuple((parse_i32, preceded(multispace0, parse_op), parse_expr_ms)),
|(l, op, r)| (i, Expr::BinOp(Box::new(l), op, Box::new(r))),
),
parse_i32,
))(i)
}
fn parse_expr_ms(i: Span) -> IResult<Span, SpanExpr> {
preceded(multispace0, parse_expr)(i)
}
// dumps a Span into a String
fn dump_span(s: &Span) -> String {
format!(
"[line :{:?}, col:{:?}, {:?}]",
s.line,
s.get_column(),
s.fragment
)
}
// dumps a SpanExpr into a String
fn dump_expr(se: &SpanExpr) -> String {
let (s, e) = se;
match e {
Expr::Num(_) => dump_span(s),
Expr::BinOp(l, (sop, _), r) => {
format!("<{} {} {}>", dump_expr(l), dump_span(sop), dump_expr(r))
}
}
}
fn main() {
let (_, (s, e)) = parse_expr_ms(Span::new("\n 1+2 - \n3")).unwrap();
println!(
"span for the whole,expression: {:?}, \nline: {:?}, \ncolumn: {:?}",
s,
s.line,
s.get_column()
);
println!("raw e: {:?}", &e);
println!("pretty e {}", dump_expr(&(s, e)));
}
//
// In this example, we have a `parse_expr_ms` is the "top" level parser.
// It consumes white spaces, allowing the location information to reflect the exact
// positions in the input file.
//
// The dump_expr will create a pretty printing of the expression with spans for
// each terminal. This will be useful for later for precise type error reporting.
//
// The exrtra field is not used, it can be used for metadata, such as filename.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment