当前位置: 首页 > 知识库问答 >
问题:

为什么ANTLR4不匹配作为单词的“of”和作为标点符号的“,”?

养学
2023-03-14

我有一个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

现在看来,条目规则中的单词以某种方式破坏了条目规则中的其他规则。但为什么?它在语法上是一种反模式吗?

共有1个答案

孙化
2023-03-14

通过在解析器规则中包含''的,ANTLR创建了一个隐式匿名令牌来表示该输入。的单词将始终具有该特殊标记类型,因此它永远不会具有word类型。它在解析树中出现的唯一位置是在解析器规则中出现'of'的位置。

您可以通过将语法分离为单独的hellolexer.g4中的lexer语法hellolexer和helloparser.g4中的parser语法helloparser来防止ANTLR创建这些匿名令牌类型。我强烈建议您始终使用此表单,原因如下:

  1. lexer模式仅在执行此操作时才起作用。
  2. 隐式定义的标记是语法中最常见的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 注意:如果输入字符串为:则可以工作