我一次又一次地遇到这种情况。要解析{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'
;
我不明白为什么,但我得到NoViableAltException
说line x:y no viable alternative at input 'SB0'
。
有人能解释我为什么会这样吗?解析器规则type_dcl_id
在每个选项前面都有唯一的文字。我不明白为什么解析器此时会遇到麻烦。
我添加了所有词法规则。
旁注:
我想要那个粒度而不是简单解析该输入的原因是我希望type_dcl_id
稍后返回一个对象,该对象应该传播到type_chain_record
,然后用于构造另一个对象ChainRecord
将保留一个对象DCLType
。
答案 0 :(得分:1)
| 'SB' EXPRESSION '$' EXPRESSION // Bit field of n bits
与SBO不匹配。
答案 1 :(得分:1)
SB0
被标记为EXPRESSION
,因为词法分析器将匹配尽可能长的序列,显然SB0
长于SB
。
一个简单的解决方法是使LETTER
和DIGIT
真正的词法规则而不是片段,并通过以下新的解析器规则交换EXPRESSION
词法分析器规则:
expression : (LETTER | DIGIT | '_' )+ ;
有关详细信息,您可能会发现此帖子很有用:https://github.com/antlr/antlr4/issues/485#issuecomment-37284837