grako

Ignoring empty elements matched by {} in recursive rule


I would like to describe a nestable condition. Here is what I'm working with :

expr = ( /[_a-zA-Z][a-zA-Z0-9_-]*/ ) ;

condop = ( "AND" | "OR" ) ;
condition = expr { condop condition } ;

start = condition ;

I can generate an AST with lines like :

foo AND bar

Here the AST :

[
  "foo", 
  [
    [
      "AND", 
      [
        "bar", 
        []
      ]
    ]
  ]
]

But there is an empty list after "bar", because I guess the last time the condition rule is matched, "condop condition" worth an empty string. According to the docs https://pypi.python.org/pypi/grako/3.16.0, {} generates an empty list.

Is there a way to prevent this from happening ?


Solution

  • What you're seeing is not Grako-specific. You're using both recursion and closures on the same rule.

    There are (more than) two ways to describe those expressions:

    condition = expr { condop expr } ;
    

    or

    condition = expr [ condop condition ] ;
    

    or

    condition = expr condop condition | expr;
    

    which is equivalent to the previous one.

    Left recursion doesn't work in all cases with Grako, so use it at your own risk. The equivalent would be:

    condition = condition condop condition | expr;