下面的语法解析( left part = right part # comment )
,# comment
是可选的。
两个问题:
id2
)id2
)可以包含字符'('和')'。 语法:
grammar NestedBrackets1a1;
//==========================================================
// Lexer Rules
//==========================================================
Int
: Digit+
;
fragment Digit
: '0'..'9'
;
Special
: ( TCUnderscore | TCQuote )
;
TCListStart : '(' ;
TCListEnd : ')' ;
fragment TCUnderscore : '_' ;
fragment TCQuote : '"' ;
// A word must start with a letter
Word
: ( 'a'..'z' | 'A'..'Z' | Special ) ('a'..'z' | 'A'..'Z' | Special | Digit )*
;
Space
: ( ' ' | '\t' | '\r' | '\n' ) { $channel = HIDDEN; }
;
//==========================================================
// Parser Rules
//==========================================================
assignment
: TCListStart id1 '=' id1 ( comment )? TCListEnd
;
id1
: Word+
;
comment
: '#' ( id2 )*
;
id2
: ( Word | Int )+
;
答案 0 :(得分:0)
ANTLRStarter写道:
有时警告(ANTLRWorks 1.4.2):决策可以使用多个替代方案匹配输入,例如“{Int,Word}”:1,2(引用id2) 但有时候只是!
不,您发布的语法总是产生此警告。也许你并不总是注意到它(你的IDE插件或ANTLRWorks可能会在你没有打开的标签中显示它),但警告就在那里。通过从命令行创建词法分析器/解析器来说服自己:
java -cp antlr-3.4-complete.jar org.antlr.Tool NestedBrackets1a1.g
将产生:
warning(200): NestedBrackets1a1.g:49:19:
Decision can match input such as "{Int, Word}" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
这是因为*
规则中( id2 )
之后comment
id2
,而( Word | Int )+
也是令牌的重复:"# foo bar"
。假设您的输入为#
(Word
后跟两个"foo"
令牌。 ANTLR现在可以通过多种方式解析输入:"bar"
可以匹配2个令牌( id2 )*
和id2
,其中Word
匹配单个"foo"
一次只有令牌,但"bar"
和id2
也可以是comment
: '#' ( ( Word | Int )+ )*
;
规则的一次匹配。
查看合并后的规则:
( ( ... )+ )*
了解你是如何重复重复的:*
?这通常是一个问题,就像你的情况一样。
通过将?
替换为comment
: '#' ( id2 )?
;
id2
: ( Word | Int )+
;
:
+
或删除comment
: '#' ( id2 )*
;
id2
: ( Word | Int )
;
:
TCListEnd
ANTLRStarter写道:
下一个扩展名应该是注释(id2)可以包含字符'('和')'。
这是一个问题,因为评论后跟)
,即)
。我不建议让评论与Comment
: '#' ~('\r' | '\n')* {skip();}
;
匹配。
请注意,在对输入源进行标记时,通常会从源文件中删除注释。这样您就不需要在解析器规则中考虑它们了。你可以通过词法分析器规则中“跳过”这些标记来实现这一点:
{{1}}