sly icon indicating copy to clipboard operation
sly copied to clipboard

Cannot use '[]' with EBNF?

Open zhang-stephen opened this issue 5 years ago • 6 comments

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

zhang-stephen avatar Jul 27 '20 07:07 zhang-stephen

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.

dabeaz avatar Jul 27 '20 10:07 dabeaz

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
    

zhang-stephen avatar Jul 28 '20 08:07 zhang-stephen

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.

vladimirdabic avatar Jul 30 '20 08:07 vladimirdabic

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.

dabeaz avatar Jul 30 '20 10:07 dabeaz

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. 😀

MystPi avatar Jun 30 '21 20:06 MystPi

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!

zhang-stephen avatar Jul 30 '21 07:07 zhang-stephen