'не найден подходящий метод для переопределения' в сгенерированных классах ANTLR4 - PullRequest
1 голос
/ 23 марта 2020

Я определил грамматику 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), но он выдал ту же ошибку.

Кто-то знает, что я делаю неправильно?

1 Ответ

2 голосов
/ 23 марта 2020

Потратив несколько часов на поиск решения, я отправил этот вопрос, продолжая искать ... и только что нашел проблему. Ошибка произошла из-за именования правила «правило».

Не используйте «правило» в качестве имени правила, поскольку оно становится RuleContext, который является предопределенным контекстным объектом.

...