假设<条码>(a)(a)条码>也有效,在此可以解决这个问题:
grammar T;
options {
output=AST;
}
tokens {
EXPR_LIST;
CALL;
INDEX;
LOOKUP;
}
parse
: expr EOF -> expr
;
expr
: add_expr
;
add_expr
: mul_exp (( + | - )^ mul_exp)*
;
mul_exp
: atom (( * | / )^ atom)*
;
atom
: fncall
| NUM
;
fncall
: (fncall_start -> fncall_start) ( ( expr_list ) -> ^(CALL $fncall expr_list)
| [ expr ] -> ^(INDEX $fncall expr)
| . ID -> ^(LOOKUP $fncall ID)
)*
;
fncall_start
: ID
| ( expr ) -> expr
;
expr_list
: (expr ( , expr)*)? -> ^(EXPR_LIST expr*)
;
NUM : 0 .. 9 +;
ID : ( a .. z | A .. Z | _ ) ( a .. z | A .. Z | 0 .. 9 | _ )*;
上文图表中产生的教区将抑制投入:
(foo.bar().array[i*2])(42)(1,2,3)
and construct the following AST:
Without the tree rewrite rules, the grammar would look like this:
grammar T;
parse
: expr EOF
;
expr
: add_expr
;
add_expr
: mul_exp (( + | - ) mul_exp)*
;
mul_exp
: atom (( * | / ) atom)*
;
atom
: fncall
| NUM
;
fncall
: fncall_start ( ( expr_list ) | [ expr ] | . ID )*
;
fncall_start
: ID
| ( expr )
;
expr_list
: (expr ( , expr)*)?
;
NUM : 0 .. 9 +;
ID : ( a .. z | A .. Z | _ ) ( a .. z | A .. Z | 0 .. 9 | _ )*;