我有一个hello.g4
语法文件,其中包含语法定义:
definition : wordsWithPunctuation ;
words : (WORD)+ ;
wordsWithPunctuation : word ( word | punctuation word | word punctuation | '(' wordsWithPunctuation ')' | '"' wordsWithPunctuation '"' )* ;
NUMBER : [0-9]+ ;
word : WORD ;
WORD : [A-Za-z-]+ ;
punctuation : PUNCTUATION ;
PUNCTUATION : (','|'!'|'?'|'\''|':'|'.') ;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
现在,如果我试图从以下输入构建解析树:
a b c d of at of abc bcd of
a b c d at abc, bcd
a b c d of at of abc, bcd of
它返回错误:
Hello::definition:1:31: extraneous input 'of' expecting {<EOF>, '(', '"', WORD, PUNCTUATION}
a b c d at: abc bcd!
ANTLR Tool v4.2.2 (/var/folders/.../antlr-4.2.2-complete.jar)
Hello.g4 -o /Users/.../eclipse_workspace/antlr_test_project/target/generated-sources/antlr4 -listener -no-visitor -encoding UTF-8
grammar Hello;
text : (entry)+ ;
entry : blub 'abrr' '-' ('1')? '.' ('(' NUMBER ')')? sims '-' '(' definitionAndExamples ')' 'Hello' 'all' 'the' 'people' 'of' 'the' 'world';
blub : WORD ;
sims : sim (',' sim)* ;
sim : words ;
definitionAndExamples : definitions (';' examples)? ;
definitions : definition (';' definition )* ;
definition : wordsWithPunctuation ;
examples : example (';' example )* ;
example : '"' wordsWithPunctuation '"' ;
words : (WORD)+ ;
wordsWithPunctuation : word ( word | punctuation word | word punctuation | '(' wordsWithPunctuation ')' | '"' wordsWithPunctuation '"' )* ;
NUMBER : [0-9]+ ;
word : WORD ;
WORD : [A-Za-z-]+ ;
punctuation : PUNCTUATION ;
PUNCTUATION : (','|'!'|'?'|'\''|':'|'.') ;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
现在看来,条目
规则中的单词以某种方式破坏了条目
规则中的其他规则。但为什么?它在语法上是一种反模式吗?
通过在解析器规则中包含''的,ANTLR创建了一个隐式匿名令牌来表示该输入。
的单词将始终具有该特殊标记类型,因此它永远不会具有
word
类型。它在解析树中出现的唯一位置是在解析器规则中出现'of'
的位置。
您可以通过将语法分离为单独的hellolexer.g4中的
lexer语法hellolexer
和helloparser.g4中的parser语法helloparser
来防止ANTLR创建这些匿名令牌类型。我强烈建议您始终使用此表单,原因如下:
- lexer模式仅在执行此操作时才起作用。
- 隐式定义的标记是语法中最常见的bug来源之一,将语法分离可以防止错误发生。
word
: WORD
| 'of'
| ... other keywords which are also "words"
;
我有一个非常简单的语法,如下所示: (我需要使用语义谓词,因为我需要解析关键字可以用作标识符的语言)。 参考:https://github.com/antlr/antlr4/blob/master/doc/predicates.md
如果我保存语法
我有一个字符串。我需要找到外部标点符号并将它们从附加的单词中拆分出来,并将它们视为另一个单词。输出将是: 将是一个单词(内部标点符号) 小狗 将是两个单词, 我的代码根据外部标点符号拆分单词,但我希望它们作为单独的单词。 我该怎么做?
我看到这个问题,就想知道。 忽略了几乎所有语言都必须向后兼容的事实,有什么理由我们不能使用运算符作为关键字和函数,这取决于它是否紧跟括号?这会让语法更难吗? 我想的主要是python,但也像C语言。
可能重复: 是否可能将可空类型作为泛型参数? 我遇到了一个关于泛型类型约束的非常奇怪的事情。我有一门课是这样的: 但是,我发现我不能像预期的那样使用null类型: 我得到一个错误,必须是引用类型。Nullable真的只是一个语法糖的结构,使其看起来像引用类型吗?
我正在编写一个解析器来解析字符串,比如 antlr4语法文件如下所示: 如果我把def加回来,就会出现错误: 属性:1:0:不匹配 输入“aaa.bb”应为ATTR_ID 注意:如果输入字符串为:则可以工作