ANTLR C#4语法-优先级

ANTLR C#4语法-优先级,antlr,grammar,Antlr,Grammar,我有下面的语法(为了演示而简化),在一个与逻辑运算符相关的特殊情况下,我遇到了一个问题 除了逻辑运算符在我引用的标识符内的情况外,我测试的所有内容都有效。例如,这项工作: @M=“ABC12345” 但这并不是: @M=“ABC12OR345” 发生的情况是字符串中的OR导致以下错误 “外部输入”或“预期{'”,LOWCHAR

我有下面的语法(为了演示而简化),在一个与逻辑运算符相关的特殊情况下,我遇到了一个问题

除了逻辑运算符在我引用的标识符内的情况外,我测试的所有内容都有效。例如,这项工作:

@M=“ABC12345”

但这并不是:

@M=“ABC12OR345”

发生的情况是字符串中的OR导致以下错误

“外部输入”或“预期{'”,LOWCHAR 我不知道如何使优先级正确

谢谢

            grammar PRDL;

            options
            {
                    language=CSharp;
            }

            statement
                : expression ( logicalOperator expression )*
                ;

            logicalOperator
                : logicalOR | logicalAND
                ;

            logicalOR
                : OR
                ;

            logicalAND
                : AND
                ;

            expression
                : mVar
                | nVar
                | parenStatement
                | notExpression
                ;

            parenStatement
                : LPAREN statement RPAREN
                ;

            notExpression
                : NOT expression
                ;

            mVar
                : M equalityOperator quotedIdentifier
                ;

            nVar
                : N equalityOperator quotedIdentifier
                ;

            equalityOperator
                    : EQUAL
                    ;

            quotedIdentifier
                : '"' identifier '"'
                ;

            identifier
                : (HIGHCHAR | LOWCHAR | DIGIT)+
                ;


            // ============  Lexer Defintions  ========================

            // OPERATORS

            NOT_ALLOWED : '*' | '/' | '+' | '-' | '#' | '$' | '%' | '^';

            EQUAL       : '=';

            COMMA       : ',';

            LPAREN      : '(';

            RPAREN      : ')';

            LPARENSQ    : '[';

            RPARENSQ    : ']';

            OR          : ('OR' | 'or' | '||');

            AND         : ('AND' | 'and' | '&&');

            NOT         : ('NOT' | 'not' | '!') ;

            M               : '@M';

            N               : '@N';

            LOWCHAR     : 'a'..'z';

            HIGHCHAR    : 'A'..'Z';

            DIGIT       : '0'..'9';


            // Whitespace -- ignored
            WS          : [ \n\t\r\f]+ -> skip;

你把lexer和parser之间的条放错地方了

quotedIdentifier
    : '"' identifier '"'
    ;

identifier
    : (HIGHCHAR | LOWCHAR | DIGIT)+
    ;
现在,每一封信都成为一种象征。这不会很好地工作,正如你所看到的,因为你会犯错误

这两个解析器规则实际上应该是lexer规则:

QUOTED_IDENTIFIER
    : '"' (HIGHCHAR | LOWCHAR | DIGIT)+ '"'
    ;

IDENTIFIER
    : (HIGHCHAR | LOWCHAR | DIGIT)+
    ;
HIGHCHAR
LOWCHAR
DIGIT
应该是片段,以防止在单个字符上获得不同的令牌类型:

fragment LOWCHAR     : 'a'..'z';
fragment HIGHCHAR    : 'A'..'Z';
fragment DIGIT       : '0'..'9';
使用这样的lexer,每个标识符将获得一个令牌,这对于解析来说更好

而且,像这样的规则几乎毫无用处:

equalityOperator
        : EQUAL
        ;

因为这只是将lexer规则与解析器规则混淆。

嗨,卢卡斯,谢谢你的回复。根据您的信息,我尝试了几种变体,但仍然存在问题。抱歉,按enter键后无法及时返回。我没有提到的一点是,我使用的是一个侦听器,因此在解析器中有更多的规则(例如,public override void ExitQuotedIdentifier…)。在解析时,我正在构建一个内部列表,稍后我可以将实值应用于变量并计算真/假条件。看起来我需要做更多的阅读来更好地理解使用这个版本的antlr-与我8年或10年前使用的版本有些不同。好的,我明白了。通过更改:标识符:(高字符|低字符|数字)+;对此:标识符:标识符+;然后像这样把标识符放在lexer中:IDENTIFIER:(HIGHCHAR | LOWCHAR | DIGIT)+;我能让事情顺利进行。谢谢