Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for "|" inside productions #100

Open
plafer opened this issue Aug 4, 2020 · 5 comments
Open

Add support for "|" inside productions #100

plafer opened this issue Aug 4, 2020 · 5 comments

Comments

@plafer
Copy link
Contributor

plafer commented Aug 4, 2020

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.

@alex
Copy link
Owner

alex commented Aug 4, 2020 via email

@plafer plafer mentioned this issue Aug 4, 2020
@nobodxbodon
Copy link
Contributor

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?

@leahcornelius
Copy link

Perhaps \ escapes it? If not then add a lexer rule to match | to VERTICLE_PIPE or similar and use that? @nobodxbodon

@nobodxbodon
Copy link
Contributor

@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)

@leahcornelius
Copy link

See #101, it should now be fixed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants