116 lines
4.1 KiB
Text
116 lines
4.1 KiB
Text
use crate::ast::{SimplExpr::{self, *}, BinOp::*, UnaryOp::*};
|
|
use eww_shared_util::{Span, VarName};
|
|
use crate::parser::lexer::{Token, LexicalError, StrLitSegment, Sp};
|
|
use crate::parser::lalrpop_helpers::*;
|
|
|
|
|
|
grammar(fid: usize);
|
|
|
|
extern {
|
|
type Location = usize;
|
|
type Error = LexicalError;
|
|
|
|
enum Token {
|
|
"+" => Token::Plus,
|
|
"-" => Token::Minus,
|
|
"*" => Token::Times,
|
|
"/" => Token::Div,
|
|
"%" => Token::Mod,
|
|
"==" => Token::Equals,
|
|
"!=" => Token::NotEquals,
|
|
"&&" => Token::And,
|
|
"||" => Token::Or,
|
|
">" => Token::GT,
|
|
"<" => Token::LT,
|
|
"?:" => Token::Elvis,
|
|
"=~" => Token::RegexMatch,
|
|
|
|
"!" => Token::Not,
|
|
|
|
"," => Token::Comma,
|
|
"?" => Token::Question,
|
|
":" => Token::Colon,
|
|
"(" => Token::LPren,
|
|
")" => Token::RPren,
|
|
"[" => Token::LBrack,
|
|
"]" => Token::RBrack,
|
|
"{" => Token::LCurl,
|
|
"}" => Token::RCurl,
|
|
"." => Token::Dot,
|
|
|
|
"true" => Token::True,
|
|
"false" => Token::False,
|
|
|
|
"identifier" => Token::Ident(<String>),
|
|
"number" => Token::NumLit(<String>),
|
|
"string" => Token::StringLit(<Vec<Sp<StrLitSegment>>>),
|
|
|
|
}
|
|
}
|
|
|
|
Comma<T>: Vec<T> = {
|
|
<mut v:(<T> ",")*> <e:T?> => match e {
|
|
None => v,
|
|
Some(e) => {
|
|
v.push(e);
|
|
v
|
|
}
|
|
}
|
|
};
|
|
|
|
pub Expr: SimplExpr = {
|
|
|
|
#[precedence(level="0")]
|
|
<l:@L> <x:"string"> <r:@R> =>? parse_stringlit(Span(l, r, fid), x),
|
|
<l:@L> <x:"number"> <r:@R> => SimplExpr::literal(Span(l, r, fid), x),
|
|
<l:@L> "true" <r:@R> => SimplExpr::literal(Span(l, r, fid), "true".into()),
|
|
<l:@L> "false" <r:@R> => SimplExpr::literal(Span(l, r, fid), "false".into()),
|
|
|
|
<l:@L> <ident:"identifier"> <r:@R> => VarRef(Span(l, r, fid), VarName(ident.to_string())),
|
|
"(" <ExprReset> ")",
|
|
<l:@L> "[" <values: Comma<ExprReset>> "]" <r:@R> => SimplExpr::JsonArray(Span(l, r, fid), values),
|
|
<l:@L> "{" <values: Comma<JsonKeyValue>> "}" <r:@R> => SimplExpr::JsonObject(Span(l, r, fid), values),
|
|
|
|
#[precedence(level="1")] #[assoc(side="right")]
|
|
<l:@L> <ident:"identifier"> "(" <args: Comma<ExprReset>> ")" <r:@R> => FunctionCall(Span(l, r, fid), ident, args),
|
|
<l:@L> <value:Expr> "[" <index: ExprReset> "]" <r:@R> => JsonAccess(Span(l, r, fid), b(value), b(index)),
|
|
|
|
<l:@L> <value:Expr> "." <lit_l:@L> <index:"identifier"> <r:@R> => {
|
|
JsonAccess(Span(l, r, fid), b(value), b(Literal(index.into())))
|
|
},
|
|
|
|
#[precedence(level="2")] #[assoc(side="right")]
|
|
<l:@L> "!" <e:Expr> <r:@R> => UnaryOp(Span(l, r, fid), Not, b(e)),
|
|
|
|
#[precedence(level="3")] #[assoc(side="left")]
|
|
<l:@L> <le:Expr> "*" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Times, b(re)),
|
|
<l:@L> <le:Expr> "/" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Div, b(re)),
|
|
<l:@L> <le:Expr> "%" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Mod, b(re)),
|
|
|
|
#[precedence(level="4")] #[assoc(side="left")]
|
|
<l:@L> <le:Expr> "+" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Plus, b(re)),
|
|
<l:@L> <le:Expr> "-" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Minus, b(re)),
|
|
|
|
#[precedence(level="5")] #[assoc(side="left")]
|
|
<l:@L> <le:Expr> "==" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Equals, b(re)),
|
|
<l:@L> <le:Expr> "!=" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), NotEquals, b(re)),
|
|
<l:@L> <le:Expr> ">" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), GT, b(re)),
|
|
<l:@L> <le:Expr> "<" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), LT, b(re)),
|
|
<l:@L> <le:Expr> "=~" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), RegexMatch, b(re)),
|
|
|
|
#[precedence(level="6")] #[assoc(side="left")]
|
|
<l:@L> <le:Expr> "&&" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), And, b(re)),
|
|
<l:@L> <le:Expr> "||" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Or, b(re)),
|
|
<l:@L> <le:Expr> "?:" <re:Expr> <r:@R> => BinOp(Span(l, r, fid), b(le), Elvis, b(re)),
|
|
|
|
#[precedence(level="7")] #[assoc(side="right")]
|
|
<l:@L> <cond:Expr> "?" <then:ExprReset> ":" <els:Expr> <r:@R> => {
|
|
IfElse(Span(l, r, fid), b(cond), b(then), b(els))
|
|
},
|
|
};
|
|
|
|
ExprReset = <Expr>;
|
|
|
|
|
|
JsonKeyValue = <Expr> ":" <Expr>;
|
|
|