Get rid of left-recursion cached rule
This commit is contained in:
parent
10ea99e95c
commit
13353f8801
@ -6,6 +6,12 @@ fn rc_string(s: &str) -> Rc<String> {
|
||||
Rc::new(s.to_string())
|
||||
}
|
||||
|
||||
enum ExtendedPart<'a> {
|
||||
Index(Vec<Expression>),
|
||||
Accessor(&'a str),
|
||||
Call(Vec<InvocationArgument>),
|
||||
}
|
||||
|
||||
peg::parser! {
|
||||
pub grammar schala_parser() for str {
|
||||
|
||||
@ -207,52 +213,33 @@ peg::parser! {
|
||||
quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} /
|
||||
expected!("operator")
|
||||
|
||||
|
||||
rule extended_expr(struct_ok: bool) -> ExpressionKind =
|
||||
item:extended_expr_ok_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
|
||||
item:extended_expr_no_struct() {? if !struct_ok { Ok(item) } else { Err("!no-struct-allowed") } }
|
||||
|
||||
#[cache_left_rec]
|
||||
rule extended_expr_ok_struct() -> ExpressionKind =
|
||||
indexee:extended_expr_ok_struct() indexers:index_part() {
|
||||
ExpressionKind::Index {
|
||||
indexee: Box::new(Expression::new(Default::default(), indexee)),
|
||||
indexers,
|
||||
primary:primary(struct_ok) parts:(extended_expr_part()*) {
|
||||
let mut expression = Expression::new(Default::default(), primary);
|
||||
for part in parts.into_iter() {
|
||||
let kind = match part {
|
||||
ExtendedPart::Index(indexers) => {
|
||||
ExpressionKind::Index { indexee: Box::new(expression), indexers }
|
||||
},
|
||||
ExtendedPart::Accessor(name) => {
|
||||
let name = rc_string(name);
|
||||
ExpressionKind::Access { name, expr: Box::new(expression) }
|
||||
},
|
||||
ExtendedPart::Call(arguments) => {
|
||||
ExpressionKind::Call { f: Box::new(expression), arguments }
|
||||
}
|
||||
} /
|
||||
f:extended_expr_ok_struct() arguments:call_part() {
|
||||
ExpressionKind::Call {
|
||||
f: Box::new(Expression::new(Default::default(), f)),
|
||||
arguments,
|
||||
};
|
||||
|
||||
expression = Expression::new(Default::default(), kind);
|
||||
}
|
||||
|
||||
} /
|
||||
expr:extended_expr_ok_struct() "." name:identifier() { ExpressionKind::Access {
|
||||
name: Rc::new(name.to_string()),
|
||||
expr: Box::new(Expression::new(Default::default(),expr)),
|
||||
} } /
|
||||
primary(true)
|
||||
|
||||
#[cache_left_rec]
|
||||
rule extended_expr_no_struct() -> ExpressionKind =
|
||||
indexee:extended_expr_no_struct() indexers:index_part() {
|
||||
ExpressionKind::Index {
|
||||
indexee: Box::new(Expression::new(Default::default(), indexee)),
|
||||
indexers,
|
||||
}
|
||||
} /
|
||||
f:extended_expr_no_struct() arguments:call_part() {
|
||||
ExpressionKind::Call {
|
||||
f: Box::new(Expression::new(Default::default(), f)),
|
||||
arguments,
|
||||
expression.kind
|
||||
}
|
||||
|
||||
} /
|
||||
expr:extended_expr_no_struct() "." name:identifier() { ExpressionKind::Access {
|
||||
name: Rc::new(name.to_string()),
|
||||
expr: Box::new(Expression::new(Default::default(),expr)),
|
||||
} } /
|
||||
primary(false)
|
||||
rule extended_expr_part() -> ExtendedPart<'input> =
|
||||
indexers:index_part() { ExtendedPart::Index(indexers) } /
|
||||
arguments:call_part() { ExtendedPart::Call(arguments) } /
|
||||
"." name:identifier() { ExtendedPart::Accessor(name) }
|
||||
|
||||
rule index_part() -> Vec<Expression> =
|
||||
"[" indexers:(expression() ++ ",") "]" { indexers }
|
||||
|
Loading…
Reference in New Issue
Block a user