ANTLR NoViableAltException

ANTLR NoViableAltException,antlr,antlr4,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'

我一次又一次地碰到这个问题。要解析
{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'
  ;
/*
*类型链记录
*/
类型链记录
:
“{”编号[10]“}”类型的dcl\U id(“,”类型的dcl\U id)?”:“类型标志
;
类型\u dcl\u id
:
'DA'表达式'd'//n个元素的数组
|'DF'//函数
|'DG'//泛型指针
|'DC'//代码指针
|'DX'//外部ram指针
|'DD'//内部ram指针
|'DP'//页指针
|'DI'//上128字节指针
|'SL'//长
|'SI'//int
|'SC'//char
|'SS'//短
|'SV'//无效
|'SF'//浮点
|“ST”表达式//名称的结构
|'SX'//sbit
|“SB”表达式“$”表达式//n位的位字段
;
类型标志
:
'U'//未签名
|'S'//已签名
;
数字[int numbase]返回[long val]
:
n=表达式
{
$val=Convert.ToInt64($n.text,$numbase);
}
;
// ////////////////////////////////////////////////////////////////////////////
//LEXER规则
碎片字母
:
“a”…“z”
|“A”…“Z”
;
碎片数字
:
'0'..'9'
;
片段非零位
:
'1'..'9'
;
文件范围
:
“L”(字母)+.”(字母)+
;
表情
:
(字母|数字|'|')+
;
WS
:
“\r”|“\n”
;
我不明白为什么,但我得到了一个
noviableexception
第x行:y在输入“SB0”时没有可行的替代方案

谁能解释一下为什么会发生这种情况?解析器规则
type\u dcl\u id
在每个选项前面都有唯一的文本。我不明白为什么解析器在这一点上会有问题

我添加了所有lexer规则

旁注:

我之所以需要这种粒度,而不是对输入进行简单的解析,是因为我希望
type\u dcl\u id
稍后返回一个对象,该对象将传播到
type\u chain\u record
,然后用于构造另一个对象
ChainRecord
,该对象将保存一个对象
DCLType


|“SB”表达式“$”表达式//n位的位字段


与SBO不匹配。

SB0
被标记为
表达式
,因为lexer将匹配最长的可能序列,并且显然
SB0
SB

一个简单的解决方法是使用
字母
数字
真正的词法规则而不是片段,并通过以下新的解析器规则交换
表达式
词法规则:

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

有关更多信息,您可能会发现这篇文章很有帮助:

表达式可以是
数字
字母
SB0$1
后面必须有另一个表达式,正如我上面回答的那样。你的语法不允许单独使用SB0。@TheantlGuy,我不明白
0
可以是一个
表达式
,那么为什么它不将
0
识别为后跟
$EXPRESSION
的表达式?SB匹配“SB”,0匹配第一个表达式。然后它需要字符串“SB0”中不存在的“$”,对吗?