ANTLR NoViableAltException

时间:2014-06-05 10:50:11

标签: antlr antlr4

我一次又一次地遇到这种情况。要解析{1}SB0$1:U,请输入S:G$mabit$0$0({1}SB0$1:U),H,0,0这里有这些规则:

/*
 *  Type Chain Record
 */

type_chain_record
    :
    '{' number[10] '}' type_dcl_id (',' type_dcl_id)? ':' type_sign
    ;

type_dcl_id
    :
      'DA' EXPRESSION 'd'                 // Array of n elements
    | 'DF'                                      // Function
    | 'DG'                                      // Generic pointer
    | 'DC'                                      // Code pointer
    | 'DX'                                      // External ram pointer
    | 'DD'                                      // Internal ram pointer
    | 'DP'                                      // Page pointer
    | 'DI'                                      // Upper 128 byte pointer
    | 'SL'                                      // long
    | 'SI'                                      // int
    | 'SC'                                      // char
    | 'SS'                                      // short
    | 'SV'                                      // void
    | 'SF'                                      // float
    | 'ST' EXPRESSION                   // Structure of name <name>
    | 'SX'                                      // sbit
    | 'SB' EXPRESSION '$' EXPRESSION    // Bit field of n bits
    ;

type_sign
    :
      'U' // Unsigned
    | 'S' // Signed
    ;


number[int numbase] returns[long val]
    :
    n = EXPRESSION
    {
        $val = Convert.ToInt64($n.text, $numbase);
    }
    ;


// ////////////////////////////////////////////////////////////////////////////
// LEXER RULES

fragment LETTER 
    :
      'a'..'z' 
    | 'A'..'Z'
    ;

fragment DIGIT
    :
    '0'..'9'
    ;

fragment NONZERO_DIGIT
    :
    '1'..'9'
    ;


FILE_SCOPE
  :
  'L' (LETTER)+ '.' (LETTER)+
  ;

EXPRESSION
  :
  (LETTER | DIGIT | '_' )+
  ;

WS 
  :
  '\r' | '\n'
  ;

我不明白为什么,但我得到NoViableAltExceptionline x:y no viable alternative at input 'SB0'

有人能解释我为什么会这样吗?解析器规则type_dcl_id在每个选项前面都有唯一的文字。我不明白为什么解析器此时会遇到麻烦。

我添加了所有词法规则。

旁注:

我想要那个粒度而不是简单解析该输入的原因是我希望type_dcl_id稍后返回一个对象,该对象应该传播到type_chain_record,然后用于构造另一个对象ChainRecord将保留一个对象DCLType

2 个答案:

答案 0 :(得分:1)

| 'SB' EXPRESSION '$' EXPRESSION // Bit field of n bits

与SBO不匹配。

答案 1 :(得分:1)

SB0被标记为EXPRESSION,因为词法分析器将匹配尽可能长的序列,显然SB0长于SB

一个简单的解决方法是使LETTERDIGIT真正的词法规则而不是片段,并通过以下新的解析器规则交换EXPRESSION词法分析器规则:

expression : (LETTER | DIGIT | '_' )+ ;

有关详细信息,您可能会发现此帖子很有用:https://github.com/antlr/antlr4/issues/485#issuecomment-37284837