grammar Hello;
file : ( fixedSentence )* EOF ;
sentence : KEYWORD1 ID+ KEYWORD2 ID+ PERIOD
| KEYWORD3 ID+ KEYWORD4 ID+ PERIOD;
KEYWORD1 : 'hello' | 'howdy' | 'hi' ;
KEYWORD2 : 'bye' | 'goodbye' | 'adios' ;
KEYWORD3 : 'dear' | 'dearest' ;
KEYWORD4 : 'love' | 'yours' ;
PERIOD : '.' ;
ID : [a-z]+ ;
WS : [ \t\r\n]+ -> skip ;
hello snickers bar goodbye mars bar.
dear peter this is fun yours james.
效果很好。但是我也想匹配包含关键字的句子,这些关键字不会被期望终止ID+块。例如
hello hello kitty goodbye my dearest raggedy ann and andy.
hello
fist显示为keyword1
,然后作为第一个ID+的一部分。按照上面链接的问题的例子,我可以这样修复它:
// ugly solution:
fixedSentence : KEYWORD1 a=(ID|KEYWORD1|KEYWORD3|KEYWORD4)+ KEYWORD2 b=(ID|KEYWORD1|KEYWORD2|KEYWORD3|KEYWORD4)+ PERIOD
| KEYWORD3 a=(ID|KEYWORD1|KEYWORD2|KEYWORD3)+ KEYWORD4 b=(ID|KEYWORD1|KEYWORD2|KEYWORD3|KEYWORD4)+ PERIOD;
它起作用了,而且做的正是我想要的。在我的真实语言中,我有数百个关键字列表,用于不同类型的句子,所以如果我尝试这种方法,我肯定会犯错误,当我在我的语言中创建新的结构时,我必须返回并编辑所有其他结构。
最好是从列表中进行非贪婪匹配,遵循ANTLR4书中的示例进行注释。所以我试了这个
// non-greedy matching concept:
KEYWORD : KEYWORD1 | KEYWORD2 | KEYWORD3 | KEYWORD4 ;
niceID : ( ID | KEYWORD ) ;
niceSentence : KEYWORD1 niceID+? KEYWORD2 niceID+? PERIOD
| KEYWORD2 niceID+? KEYWORD3 niceID+? PERIOD;
我认为它遵循了评论的模式(例如在书的第81页中给出的):
COMMENT : '/*' .*? '*/' -> skip ;
通过使用?
来表示不贪婪。(尽管示例是lexer规则,但这是否改变了这里的含义?)FixedStrence
有效,但NiceSentence
失败。从这里我要去哪里?
line 1:6 extraneous input 'hello' expecting ID
line 1:29 extraneous input 'dearest' expecting {'.', ID}
line 1:6 extraneous input 'hello' expecting {ID, KEYWORD}
line 1:29 extraneous input 'dearest' expecting {KEYWORD2, ID, KEYWORD}
line 1:57 extraneous input '.' expecting {KEYWORD2, ID, KEYWORD}
如果查看解析树有帮助,这里是它们。
认识到解析器最适合处理语法,即结构,而不是语义区别。关键字在一个上下文中是否是ID
终止符,而在另一个上下文中是否是ID
终止符,这两者在语法上是等价的,这是本质上的语义问题。
处理语义歧义的典型ANTLR方法是创建一个解析树,识别尽可能多的结构差异,然后遍历树,分析每个节点与周围节点的关系(在本例中),以解决歧义。
如果解析器为
sentences : ( ID+ PERIOD )* EOF ;
那么你的句子基本上是自由形式的。更合适的工具可能是NLP库--斯坦福有一个很好的工具。
附加
如果将lexer规则定义为
KEYWORD1 : 'hello' | 'howdy' | 'hi' ;
KEYWORD2 : 'bye' | 'goodbye' | 'adios' ;
KEYWORD3 : 'dear' | 'dearest' ;
KEYWORD4 : 'love' | 'yours' ;
. . . .
KEYWORD : KEYWORD1 | KEYWORD2 | KEYWORD3 | KEYWORD4 ;
hello hello kitty goodbye my dearest ...
KEYWORD1 KEYWORD1 ID KEYWORD2 ID KEYWORD3 ...
niceID : ( ID | keyword ) ;
keyword : KEYWORD1 | KEYWORD2 | KEYWORD3 | KEYWORD4 ;
基本上,我试图为lexer指定尝试匹配(LOWCHARHIGHCHAR)的非贪婪方式,因此它停止在关键字lookahead。到目前为止,我所读到的关于ANTLR lexer的内容是,应该有某种lexer规则的优先级。如果我在lexer语法中首先指定关键字lexer规则,那么后面的任何lexer规则都不能匹配所使用的字符。 经过一番搜索,我明白了这里的问题是它不能以正确的方式标记输入,因为例如对于输
据我所知,非贪婪匹配不是基本正则表达式(BRE)和扩展正则表达式(ERE)的一部分。然而,不同版本的(BSD和GNU)上的行为似乎表明了另一种明智的做法。 举个例子,我们来看下面这个例子。我有一串话要说: 以下是从字符串中提取< code>hello的一些尝试。 BRE尝试(失败): 输出产生整个字符串,这表明非贪婪量词在 BRE 上不起作用。请注意,我只是转义,因为不会失去它的意义,也不需要转义
本文向大家介绍python re模块匹配贪婪和非贪婪模式详解,包括了python re模块匹配贪婪和非贪婪模式详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了python re模块匹配贪婪和非贪婪模式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python贪婪和非贪婪 正则表达式通常用于在文本中查找匹配的字符串。Pytho
本文向大家介绍php正则表达式中贪婪与非贪婪介绍,包括了php正则表达式中贪婪与非贪婪介绍的使用技巧和注意事项,需要的朋友参考一下 一、贪婪与非贪婪 什么叫贪婪,比如说要从字符串中<td>面包一</td><td>面包二</td>吃面包,本来你只可以吃面包一,可是你贪心,于是就把第一个<td>到最后一个</td>里面的两个面包取出来了,你想多吃点,非贪婪也就是你不贪吃了,就只吃面包一。 我们来看看正
问题内容: 我有下一个代码: 并具有下一个输出: 但我认为它必须是: 有人请解释为什么。 问题答案: 由于您的模式是非贪婪的,因此它们在仍由匹配项组成的情况下,匹配的文本越少越好。 去除 ?在第二组中,您会得到 单词 word word big small
我是一个Antlr4新手,有一个相对简单的语法问题。语法在末尾的底部给出。(这是一个语法片段,用于分析生物序列变体的描述)。 在下面的单元测试中,我试图解析字符串。 这里出了什么问题?我在哪里可以学习如何解决这个问题?