【问题标题】:Prevent "Antlr4.Runtime.NoViableAltException" with Antlr使用 Antlr 防止“Antlr4.Runtime.NoViableAltException”
【发布时间】:2015-07-04 18:18:07
【问题描述】:

我正在使用 Antlr 4(C# 实现),每当要解析的字符串很复杂时,我都会收到以下异常。

A first chance exception of type 'Antlr4.Runtime.NoViableAltException' occurred in DataImportClassLibrary.dll

这个有效:

[Pitch Angle] > 5

这个会产生错误:

[Pitch Angle] > 5 AND [Pressure Altitude] < 10000

语法:

grammar EventDetection;

AND : 'AND' ;
OR  : 'OR' ;

GT : '>' ;
GE : '>=' ;
LT : '<' ;
LE : '<=' ;
EQ : '=' ;

LPAREN : '(' ;
RPAREN : ')' ;

DECIMAL : '-'?[0-9]+('.'[0-9]+)? ;
IDENTIFIER : '[' [a-zA-Z_][a-zA-Z_0-9 ]* ']';
SEMI : ';' ;
COMMENT : '//' .+? ('\n'|EOF);// -> skip ;
WS : [ \r\t\u000C\n]+;// -> skip ;

rule_set : single_rule* ;

single_rule : logical_expr ;

logical_expr : logical_expr AND logical_expr  # LogicalExpressionAnd
             | logical_expr OR logical_expr   # LogicalExpressionOr
             | comparison_expr                # ComparisonExpression
             | LPAREN logical_expr RPAREN     # LogicalExpressionInParen
             ;

comparison_expr : IDENTIFIER comp_operator DECIMAL  # ComparisonExpressionWithOperator
            ;

comp_operator : GT
              | GE
              | LT
              | LE
              | EQ
              ;
  1. 有没有办法强制词法分析器优先考虑规则?例如。如果它只是先选择 OR,我认为我不会遇到这个问题。
  2. 我需要在代码中处理这个吗?

【问题讨论】:

  • 不是优先级导致这个异常,所以应该多花点时间调试语法,比如在Visual Studio上调试生成的代码。

标签: antlr antlr4


【解决方案1】:

我使用了您的语法文件,并且能够解析您提供的两个输入字符串。

为了让它工作,我取消了“->skip;”的注释。你有你的规则。可以试试吗?

COMMENT : '//' .+? ('\n'|EOF) -> skip ;
WS : [ \r\t\u000C\n]+ -> skip ;

【讨论】:

    【解决方案2】:

    原来问题出在空格上。如果我将输入字符串更改为:

    [Pitch Angle]>5AND[Pressure Altitude]<10000
    

    它有效,即使我有一个处理空格的规则。

    解决方案是将其更改为以下内容:

    WS : [ \r\t\u000C\n]+ -> channel(HIDDEN);
    

    感谢调查此问题的人。

    【讨论】:

      【解决方案3】:

      由于您将AND 定义为logical_expr 中的第一个替代项,因此生成的解析器将首先解析5 AND [Pressure Altitude],而不是[Pitch Angle] &gt; 5

      您可能希望在ANDOR 之前定义comparison_expr

      logical_expr : comparison_expr                # ComparisonExpression
                   | logical_expr AND logical_expr  # LogicalExpressionAnd
                   | logical_expr OR logical_expr   # LogicalExpressionOr
                   | LPAREN logical_expr RPAREN     # LogicalExpressionInParen
                   ;
      

      【讨论】:

      • 谢谢巴特。不幸的是,这并没有什么不同。
      • 好的,您能否编辑您的问题并发布SSCCE 以便其他人可以重现该错误?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 2011-01-03
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多