Add support for "|" inside productions
plafer opened this issue · 5 comments
Cleans up the use case where one has many small productions. For example,
@pg.production("prod: TOKEN_1")
# ... <24 lines>
@pg.production("prod: TOKEN_26")
def func(p):
pass
Would be simplified to
@pg.production("prod: TOKEN_1 | ... | TOKEN_26")
def func(p):
pass
More specifically, I need this right now, as I need to accept (and throwaway) all tokens until I see a newline.
I'd be happy to submit a PR if you guys think it's a valuable feature to have.
We have a production rule bin_expr : expr | expr
where | stands for BitOr, which was fine with 0.7.7 but broken on 0.7.8. It seems to be caused by this change. I wonder if there's a way to get around? Some kind of escaping or else?
Perhaps \ escapes it? If not then add a lexer rule to match | to VERTICLE_PIPE or similar and use that? @nobodxbodon
@leocornelius thanks for the suggestion. Just tried this test case and it does seem to work:
def test_arithmetic(self):
lg = LexerGenerator()
lg.add("NUMBER", r"\d+")
lg.add("BITOR", r"\|")
pg = ParserGenerator(["NUMBER", "BITOR"], precedence=[
("left", ["BITOR"]),
])
@pg.production("main : expr")
def main(p):
return p[0]
@pg.production("expr : expr BITOR expr")
def expr_binop(p):
return BoxInt(operator.or_(p[0].getint(), p[2].getint()))
@pg.production("expr : NUMBER")
def expr_num(p):
return BoxInt(int(p[0].getstr()))
lexer = lg.build()
parser = pg.build()
assert parser.parse(lexer.lex("1|8")) == BoxInt(9)
See #101, it should now be fixed :)