59 lines
1.4 KiB
Plaintext
59 lines
1.4 KiB
Plaintext
//! Serene's grammer based on LALRPOP which is a LR(1) parser.
|
|
use std::str::FromStr;
|
|
use crate::ast;
|
|
|
|
grammar;
|
|
|
|
// A collection of Expr objects is simply a sequence of parsed AST objects.
|
|
pub Exprs: Vec<ast::Expr> = {
|
|
<v:(<Expr>)*> => v,
|
|
};
|
|
|
|
// Parse an AST expression.
|
|
Expr: ast::Expr = {
|
|
// Matches a list
|
|
"(" <Exprs> ")" => ast::Expr::List(<>),
|
|
|
|
// Matches a vector
|
|
// "[" <Exprs> "]" => Ast::Vector(<>),
|
|
|
|
// Match the literal value "nil".
|
|
// "nil" => Ast::Nil,
|
|
// Match a Num term.
|
|
Float => ast::Expr::Num(ast::Number::Float(<>)),
|
|
Decimal => ast::Expr::Num(ast::Number::Integer(<>)),
|
|
|
|
// Matches a string.
|
|
r#""(?:[^"\\]|\\.)*""# => {
|
|
let val = <>;
|
|
ast::Expr::Str(val[1..val.len() - 1].to_owned())
|
|
},
|
|
|
|
// Matches a quoted expr
|
|
"'" <Expr> => ast::Expr::Quote(Box::new(<>)),
|
|
|
|
// Match any token and treat it as an atom.
|
|
Symbol => ast::Expr::Symbol(<>),
|
|
! => ast::Expr::Error(format!("{:?}", <>)),
|
|
};
|
|
|
|
// Match any sequence of token characters.
|
|
Symbol: String = {
|
|
r#"[A-Za-z_?+*/=<>-]+[0-9A-Za-z_?+*/=<>-]*"# => (<>).to_owned()
|
|
};
|
|
|
|
// Match any valid integer value and treat it as a 32-bit signed integer.
|
|
Decimal: i32 = {
|
|
r"[0-9]+" => i32::from_str(<>).unwrap()
|
|
};
|
|
|
|
Float: f32 = {
|
|
r"[0-9]*\.[0-9]+" => f32::from_str(<>).unwrap()
|
|
};
|
|
|
|
match {
|
|
r"\s*" => { },
|
|
r";[^\n\r]*[\n\r]*" => { },
|
|
_
|
|
}
|