Ll1 parser online dating
To support the unary operators, all we need to do is to add “nud” implementations to the relevant tokens: Note that the recursive call to expression uses a high binding power, to make sure that the unary operator binds to the token immediately to the right, instead of to the rest of the expression (“(-1)-2” and “-(1-2)” are two different things).
Adding exponentiation is a bit trickier; first, we need to tweak the tokenizer to identify the two-character operator: In this way, the parser will treat subsequent exponentiation operators (with binding power 30) as subexpressions to the current one, which is exactly what we want.
I'm currently studying LR parsing and in need of an online LR(1) parser to be able to verify my outcome.
We still need to write code for each token class, and while we’ve moved most of the dispatching from individual rules to the expression parser, most of that ended up in a big if/else statement in the tokenizer.
Before we look at ways to get rid of some of that code, let’s add two more features to the parser: unary plus and minus operators, and a Python-style exponentiation operator (**).
For example, here’s an excerpt from Python’s expression grammar.
The “test” rule is a basic expression element:test: or_test ['if' or_test 'else' test] | lambdef or_test: and_test ('or' and_test)* and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('') arith_expr)* arith_expr: term ((' '|'-') term)* term: factor (('*'|'/'|'%'|'//') factor)* factor: (' '|'-'|'~') factor | power power: atom trailer* ['**' factor] trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME With a naive recursive-descent implementation of this grammar, the parser would have to recurse all the way from “test” down to “trailer” in order to parse a simple function call (of the form “expression(arglist)”).