Select Git revision
parse.rs 10.34 KiB
extern crate nom;
use std::iter::Peekable;
use std::slice::Iter;
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::{
alpha1, alphanumeric0, char, digit1, multispace0, multispace1,
},
combinator::{cut, map, opt},
error::ParseError,
multi::{many1, separated_list},
sequence::{delimited, preceded, terminated, tuple},
IResult,
};
use crate::ast::{
Block, Cmd, Expr, Func, Item, Mutability, Op, Prog, Span, SpanCmd,
SpanExpr, SpanId, Type,
};
pub fn parse_i32(i: Span) -> IResult<Span, (Span, i32)> {
map(digit1, |digit_str: Span| {
(digit_str, digit_str.fragment.parse::<i32>().unwrap())
})(i)
}
fn parse_op(i: Span) -> IResult<Span, (Span, Op)> {
alt((
map(tag("=="), |s| (s, Op::Eq)),
map(tag("!="), |s| (s, Op::Neq)),
map(tag("**"), |s| (s, Op::Pow)),
map(tag("&&"), |s| (s, Op::And)),
map(tag("||"), |s| (s, Op::Or)),
map(tag("+"), |s| (s, Op::Add)),
map(tag("-"), |s| (s, Op::Sub)),
map(tag("*"), |s| (s, Op::Mul)),
map(tag("/"), |s| (s, Op::Div)),
map(tag("!"), |s| (s, Op::Not)),
))(i)
}
#[derive(Debug, Clone, PartialEq)]
pub enum Token<'a> {
Num(i32),
Bool(bool),
Id(String),
Call(String, Vec<(Span<'a>, Vec<SpanToken<'a>>)>),
Par(Vec<SpanToken<'a>>),
Op(Op),
}
type SpanToken<'a> = (Span<'a>, Token<'a>);
pub fn parse_id(i: Span) -> IResult<Span, Span> {
// an identifier needs to start with one or more alphas (head)
// followed by zero or more alphanumerics (tail)
map(
preceded(multispace0, tuple((alpha1, alphanumeric0, tag("")))),
// we concatenate the head and tail into a single String
|(_, _, end): (Span, Span, Span)| {
let mut res = i;
res.fragment = &i.fragment[..(end.offset - i.offset)];
res
},
)(i)
}