Я определил грамматику ANTLR4, где лексер и парсер находятся в двух разных файлах. Это XML похожая на грамматику. В моем парсере я тоже хочу определить выражение, которое может повторно использовать себя для целей расчета (например, '(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 ;
Последнее, что я добавил, было expression PLUS expression
, и с тех пор я получаю следующую ошибку в C# сгенерированном TestExpressionParser
классе:
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 не могу понять, почему это происходит. Я использую расширение ANTLR Language Support в сочетании с пакетом Antlr4 NuGet от Sam Haswell. Я тоже пытался использовать инструмент генерации по умолчанию (который является последней версией ANTLR, но не имеет расширения VS), но он выдал ту же ошибку.
Кто-то знает, что я делаю неправильно?