Newer
Older
%expect-unused Unmatched 'UNMATCHED'
%left '\\'
%left '|'
%left '&'
%left '.' '@'
Schedule -> OperationList
: { OperationList::NilStmt() }
| Expr { OperationList::FinalExpr($1) }
| Stmt Schedule { OperationList::ConsStmt($1, Box::new($2)) }
;
Stmt -> Stmt
: 'let' 'ID' '=' Expr ';'
{ Stmt::LetStmt { span: $span, var: span_of_tok($2), expr: $4 } }
| 'let' '(' Ids ')' '=' Expr ';'
{ Stmt::LetsStmt { span: $span, vars: rev($3), expr: $6 } }
| 'ID' '=' Expr ';'
{ Stmt::AssignStmt { span: $span, var: span_of_tok($1), rhs: $3 } }
| Expr ';'
{ Stmt::ExprStmt { span: $span, exp: $1 } }
| 'fixpoint' FixpointLimit '{' Schedule '}'
{ Stmt::Fixpoint { span: $span, limit: $2, body: Box::new($4) } }
| MacroDecl
{ Stmt::MacroDecl { span: $span, def: $1 } }
FixpointLimit -> FixpointLimit
: { FixpointLimit::NoLimit { span: $span } }
| 'stop_after' 'INT'
{ FixpointLimit::StopAfter { span: $span, limit: span_of_tok($2) } }
| 'panic_after' 'INT'
{ FixpointLimit::PanicAfter { span: $span, limit: span_of_tok($2) } }
| 'print_iter'
{ FixpointLimit::PrintIter { span: $span } }
;
Expr -> Expr
: 'ID' Args Selector
{ Expr::Function { span: $span, name: span_of_tok($1), args: $2, selection: $3 } }
| 'MACRO' Args Selector
{ Expr::Macro { span: $span, name: span_of_tok($1), args: $2, selection: $3 } }
| 'ID'
{ Expr::Variable { span: span_of_tok($1) } }
| 'INT'
{ Expr::Integer { span: span_of_tok($1) } }
| 'true'
{ Expr::Boolean { span: $span, val: true } }
| 'false'
{ Expr::Boolean { span: $span, val: false } }
| Expr '.' 'ID'
{ Expr::Field { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
| Expr '.' 'INT'
{ Expr::TupleField { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
| Expr '@' 'ID'
{ Expr::Field { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
| '(' Exprs ')'
{ Expr::Tuple { span: $span, exps: $2 } }
| '[' Exprs ']'
{ Expr::Tuple { span: $span, exps: $2 } }
| '{' Schedule '}'
{ Expr::BlockExpr { span: $span, body: Box::new($2) } }
| '<' Fields '>'
{ Expr::Record { span: $span, fields: rev($2) } }
| Expr '\\' Expr
{ Expr::SetOp { span: $span, op: SetOp::Difference, lhs: Box::new($1), rhs: Box::new($3) } }
| Expr '|' Expr
{ Expr::SetOp { span: $span, op: SetOp::Union, lhs: Box::new($1), rhs: Box::new($3) } }
| Expr '&' Expr
{ Expr::SetOp { span: $span, op: SetOp::Intersection, lhs: Box::new($1), rhs: Box::new($3) } }
: RExprs { rev($1) }
;
RExprs -> Vec<Expr>
: { vec![] }
| Expr { vec![$1] }
| Expr ',' RExprs { snoc($1, $3) }
Fields -> Vec<(Span, Expr)>
: { vec![] }
| 'ID' '=' Expr { vec![(span_of_tok($1), $3)] }
| 'ID' '=' Expr ',' Fields { snoc((span_of_tok($1), $3), $5) }
Selector -> Selector
: '(' '*' ')'
{ Selector::SelectAll { span: $span } }
| '(' Exprs ')'
{ Selector::SelectExprs { span: $span, exprs: $2 } }
MacroDecl -> MacroDecl
: 'macro_keyword' 'MACRO' Params '(' 'ID' ')' MacroDef
{ MacroDecl {
name: span_of_tok($2),
params: rev($3),
selection_name: span_of_tok($5),
def: Box::new($7),
}
}
Params -> Vec<Span>
: { vec![] }
| '[' Ids ']' { $2 }
Ids -> Vec<Span>
: { vec![] }
| 'ID' { vec![span_of_tok($1)] }
| 'ID' ',' Ids { snoc(span_of_tok($1), $3) }
Unmatched -> () : 'UNMATCHED' {};
%%
use cfgrammar::Span;
use lrlex::DefaultLexeme;
fn snoc<T>(x: T, mut xs: Vec<T>) -> Vec<T> {
xs.push(x);
xs
}
fn rev<T>(mut xs: Vec<T>) -> Vec<T> {
xs.reverse();
xs
}
fn span_of_tok(t : Result<DefaultLexeme, DefaultLexeme>) -> Span {
t.map_err(|_| ()).map(|l| l.span()).unwrap()
}
pub enum OperationList {
NilStmt(),
FinalExpr(Expr),
ConsStmt(Stmt, Box<OperationList>),
pub enum Stmt {
LetStmt { span: Span, var: Span, expr: Expr },
AssignStmt { span: Span, var: Span, rhs: Expr },
ExprStmt { span: Span, exp: Expr },
Fixpoint { span: Span, limit: FixpointLimit, body: Box<OperationList> },
MacroDecl { span: Span, def: MacroDecl },
pub enum FixpointLimit {
NoLimit { span: Span },
StopAfter { span: Span, limit: Span },
PanicAfter { span: Span, limit: Span },
PrintIter { span: Span },
#[derive(Copy, Clone, Debug)]
pub enum SetOp {
Difference,
Union,
Intersection,
}
pub enum Expr {
Function { span: Span, name: Span, args: Vec<Expr>, selection: Selector },
Macro { span: Span, name: Span, args: Vec<Expr>, selection: Selector },
Variable { span: Span },
Integer { span: Span },
Boolean { span: Span, val: bool },
Field { span: Span, lhs: Box<Expr>, field: Span },
BlockExpr { span: Span, body: Box<OperationList> },
Record { span: Span, fields: Vec<(Span, Expr)> },
SetOp { span: Span, op: SetOp, lhs: Box<Expr>, rhs: Box<Expr> },
Tuple { span: Span, exps: Vec<Expr> },
TupleField { span: Span, lhs: Box<Expr>, field: Span },
pub enum Selector {
SelectAll { span: Span },
SelectExprs { span: Span, exprs: Vec<Expr> },
}
pub struct MacroDecl {
pub name: Span,
pub params: Vec<Span>,
pub selection_name: Span,
pub def: Box<OperationList>,