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

more examples

parent 7af0b044
Branches
No related tags found
No related merge requests found
...@@ -4,11 +4,16 @@ ...@@ -4,11 +4,16 @@
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "cargo", "type": "shell",
"subcommand": "build", "label": "cargo check --example main_span_expr",
"command": "cargo check --example main_span_expr",
"problemMatcher": [ "problemMatcher": [
"$rustc" "$rustc"
] ],
"group": {
"kind": "build",
"isDefault": true
}
} }
] ]
} }
\ No newline at end of file
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # 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]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.9" version = "0.1.9"
...@@ -10,6 +15,7 @@ name = "first" ...@@ -10,6 +15,7 @@ name = "first"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
...@@ -39,6 +45,16 @@ dependencies = [ ...@@ -39,6 +45,16 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
...@@ -98,10 +114,12 @@ version = "1.0.2" ...@@ -98,10 +114,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [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 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 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 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 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 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 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" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
......
...@@ -26,12 +26,14 @@ pub enum Expr<'a> { ...@@ -26,12 +26,14 @@ pub enum Expr<'a> {
BinOp(Span<'a>, Box<Expr<'a>>, Op, Box<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>>; // type IResult<I, O, E = u32> = Result<(I, O), Err<I, E>>;
pub fn parse_i32(i: Span) -> IResult<Span, Expr> { pub fn parse_i32(i: Span) -> IResult<Span, Expr> {
map(digit1, |digit_str: Span| { map(digit1, |digit_str: Span| {
Expr::Num(digit_str, digit_str.fragment.parse::<i32>().unwrap()) Expr::Num(digit_str, digit_str.fragment.parse::<i32>().unwrap())
})(i) })(i)
// below is just an exapmle on howto generate an Error explicitly
// Err(Err::Error((i, ErrorKind::Alpha))) // 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