1
votes

I have defined a ANTLR4 grammar where the lexer and parser are in two different files. It's a XML look-a-like grammar. In my parser I want too define a expression which can re-use itself for calculation purposes (like '(1+1)*2').

parser grammar TestExpressionParser;

options { tokenVocab=TestExpressionLexer; }

compileUnit             : calculator ;

calculator              : '<' 'calculator' '>' tiers? rules?'</' 'calculator' '>' ;

// tiers
tiers                   : '<' 'tiers' '>' tier* '</' 'tiers' '>' ; 
tier                    : '<' 'tier' attrReference '>' '</' 'tier' '>' ;

// rules 
rules                   : '<' 'rules' '>' (rule) '</' 'rules' '>' ;
rule                    : '<' 'rule' '>' (calculation|reference|description)* '</' 'rule' '>' ;

calculation             : '<' 'calculation' '>' expression '</' 'calculation' '>' ;
description             : '<' 'description' '>' TEXT '</' 'description' '>' ;
reference               : '<' 'reference' '>' TEXT '</' 'reference' '>' ;

attrReference           : 'reference' '="' TEXT '"' ;


expression              : '(' expression ')'                #parentExpression
                        | expression PLUS expression        #plusExpression
                        | NUMBER                            #numberExpression
                        | REF_PARAMETER                     #parameterExpression
                        ;

lexer grammar TestExpressionLexer;

fragment LOWERCASE  : [a-z] ;
fragment UPPERCASE  : [A-Z] ;
fragment DIGIT          : [0-9] ;

PARENTHESIS_LEFT        : '(' ;
PARENTHESIS_RIGHT       : ')' ;

ATTR_OPEN                       : '="' ; 
ATTR_CLOSE                  : '"' ;

TAG_BEGIN_OPEN          : '<' ;
TAG_BEGIN_CLOSE         : '/>' ;
TAG_END_OPEN                : '</' ;
TAG_CLOSE                       : '>' ;  

// common
TAG_ATTR_REFERENCE  : 'reference' ;
TAG_CALCULATOR          : 'calculator' ;

// tiers
TAG_TIERS                       : 'tiers' ;
TAG_TIER                        : 'tier' ;

// rules
TAG_RULES                       : 'rules' ;
TAG_RULE                        : 'rule' ;
TAG_GROUP                       : 'group' ;
TAG_ATTR_RULE_CALCULATION : 'calculation' ;
TAG_ATTR_RULE_DESCRIPTION : 'description' ;

// calculation operations
ASTERISK            : '*' ;
SLASH               : '/' ;
PLUS                : '+' ;
MINUS               : '-' ;
TIER                : '=>' ;

REF_PARAMETER                   : '{' TEXT '}' ;
REF_TIER                            : '[' TEXT ']' ;

// others
TEXT                                : (UPPERCASE|LOWERCASE) (UPPERCASE|LOWERCASE|DIGIT|'_')* ;
NUMBER                          : FLOAT | DIGIT+ ;
FLOAT                               :   DIGIT+ (','|'.') DIGIT* | (','|'.') DIGIT+ ;

// whitespaces
WHITESPACE                  : (' '|'\n'|'\t'|'\r')+ -> skip ;

The last thing I added was the expression PLUS expression and since then I'm getting the follow error in the C# generated TestExpressionParser class:

line 866: 'TestExpressionParser.Sempred(TestExpressionParser.RuleContext, int, int)': no suitable method found to override
line 868: Cannot convert type '(..).Testing.TestExpressionParser.RuleContext' to '(..).Testing.TestExpressionParser.ExpressionContext'

I can't figure out why this is happening. I'm using the ANTLR Language Support extension in combination with the Antlr4 NuGet package by Sam Haswell. I've tried too use the default generating tool (which is the last version of ANTLR but don't have a VS extension) but it gave the same error.

Somebody knows what I'm doing wrong?

1

1 Answers

3
votes

After spending several hours searching for the solution, I posted this question while still searching.. and I have just found the problem. The error occured because of the naming of rule 'rule'.

Don't use 'rule' as a rule name because it becomes RuleContext which is the predefined context object.