Skip to content

Add support for "|" inside productions #100

Description

@plafer

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.

Activity

  1. alex commented on Aug 4, 2020

    @alex
    Owner
  2. nobodxbodon commented on May 10, 2021

    @nobodxbodon
    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?

  3. leahcornelius commented on Aug 16, 2021

    @leahcornelius

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

  4. nobodxbodon commented on Aug 17, 2021

    @nobodxbodon
    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)
  5. leahcornelius commented on Jan 5, 2022

    @leahcornelius

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions