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

Cannot use '[]' with EBNF? #57

Open
zhang-stephen opened this issue Jul 27, 2020 · 6 comments
Open

Cannot use '[]' with EBNF? #57

zhang-stephen opened this issue Jul 27, 2020 · 6 comments

Comments

@zhang-stephen
Copy link

zhang-stephen commented Jul 27, 2020

I tried to write this formula for a variable or a reference of element in one array:

@_("'$' IDENTIFIER [ '[' consts ']' ]")
def vars(self, p):
    print(len(p))

As well known, strings in '[]' is optional for this rule, but I try to get length of it, the length always is 3: if I Input $i as a variable not ref, the p[2] will be (None, None, None) as a tuple.

How to solve it? I think the length would be 5 if my input looks like $x[0] and length would be 2 if my input looks like $i

@dabeaz
Copy link
Owner

dabeaz commented Jul 27, 2020

Optional EBNF rules don't work in the way that you suggest. Typical code would look like this:

@_("'$' IDENTIFIER [ '[' consts ']' ]")
def vars(self, p):
     name = p.IDENTIFIER
     index = p.consts
     if index is None:
            # Not provided
            ...

If you refer to p[2] you'll get a tuple of the matching pieces or a tuple of Nones to indicate they weren't present.

@zhang-stephen
Copy link
Author

zhang-stephen commented Jul 28, 2020

OK, Got it. I noticed the tuple and used it to get what I needed after opening this issue.
There are some new questions. For convenience I would not open new issue, they are following:

  1. May I ask you to update the docs with the details of using EBNF? I think current docs might be outdated a little. And I think the examples are too simple to make user understand this library. Could you give more examples to users?
  2. The literals doesn't work with following code:
    @_("terms { ( '+'|'-' ) terms }")
      def expr(self, p):
          lval = p[0]
          for op, rval in p[1]:
              if op == '+':
                  lval += rval
              if op == '-':
                  lval -= rval
          return lval
    The | cannot be processed correctly by sly. Does it means that I cannot use literal characters in the EBNF, or my using method is wrong?
    P.S. the rule I wanted is following:
    expr : terms '+' terms
            | terms '-' terms
    

@vladimirdabic
Copy link

The thing that confuses me is that the pipe character is used in one of the scripts in the "tests" folder in the repository.
I need to do a very similar rule as stark-zhang.

@dabeaz
Copy link
Owner

dabeaz commented Jul 30, 2020

If you want to write a rule for

expr : terms `+` terms
     | terms  `-` terms

Then write it as

@_("term '+' term",
   "term '-' term")
def expr(self, p):
     ...

As for docs, your request is noted, but nothing more. This is a side project. Sometimes I work on it. Sometimes not. There are many other parsing libraries available.

@MystPi
Copy link

MystPi commented Jun 30, 2021

Could you list some good libraries please? I've used your PLY library and its been enough for me so far, but I'd like to know if there are any other nice ones to use. 😀

@zhang-stephen
Copy link
Author

Could you list some good libraries please? I've used your PLY library and its been enough for me so far, but I'd like to know if there are any other nice ones to use. 😀

this project, sly, is newer and better than PLY, try it!

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