Error with tatsu : does not recognize the right grammar pattern

92 views Asked by At

I am getting started with tatsu and I am trying to implement a grammar for the miniML language. Once my grammar successfully parsed, I tried to parse some little expressions to check that it was working ; however I discovered Tatsu was unable to recognize some of the expected patterns.

Here is the code :

`

grammar="""
@@grammar::CALC


start
    =
    expression $
    ;


expression
    =
    |integer
    |addition
    |soustraction
    |multiplication
    |division
    |Fst
    |Snd
    |pair
    |varname
    |assign
    |function
    |application
    |parentheses
    ;

    
integer
    =
    /\d+/
    ;
    
addition
    =
    left:'+' right:pair
    ;
    
soustraction
    =
    '-' pair
    ;
    
multiplication
    =
    '*' pair
    ;
    
division
    =
    '/' pair
    ;
    
Fst
    =
    'Fst' pair
    ;

Snd
    =
    'Snd' pair
    ;
    
pair
    =
    '(' expression ','  expression ')'
    ;
    
varname
    =
    /[a-z]+/
    ;
    
assign
    =
    varname '=' expression ';' expression
    ;
    
function
    =
    'Lambda' varname ':' expression
    ;

application
    =
    ' '<{expression}+
    ;

parentheses
    =
    '(' expression ')'
    ;
    

"""

`

then parsed :

parser = tatsu.compile(grammar)

All of those expression are successfully recognized, except the "assign" and the "application" ones. If i try something like this :

parser.parse("x=3;x+1") I get that error message :

FailedExpectingEndOfText: (1:2) Expecting end of text :
x=3;x+1
 ^
start

and same goes for an expression of the type "expression expression". What could be the syntax error I made here ? I have no clue and I can't find any in the documentation.

Thanks in advance !

1

There are 1 answers

0
Swifty On BEST ANSWER
  • It seems the failure of assign comes from a conflict with the varname rule; to solve it, simply place |assign BEFORE |variable in your expression rule.

A now obsolete workaround, that I'll leave anyway:

# I added a negative lookahead for '=' so it will not conflict with the assign rule
varname = /[a-z]+/!'=' ;
    
assign =  /[a-z]+/ '=' expression ';' expression ;

Example:

parser.parse("x=1;+(x,1)")
# ['x', '=', '1', ';', AST({'left': '+', 'right': ['(', 'x', ',', '1', ')']})]
  • About 'application' : replacing ' ' with / / at the start of the rule, and placing |application at the start of the expression rule solves the problem:
parser.parse("1 2 (x=1;3) *(4,5)")
Out[207]: 
(' ',
 '1',
 (' ',
  '2',
  (' ',
   ['(', ['x', '=', '1', ';', '3'], ')'],
   ['*', ['(', '4', ',', '5', ')']])))