我正在用一种语法试验w / ANTL4,这种语法最好被标记为短语而不是单词(即大多数标记可能包含空格)。但是,在某些情况下,我想将特定的子字符串短语捕获为单独的标记。请考虑以下示例:
Occurrence A of Encounter Performed
短语“出现A”是特别的 - 每当我看到它时,我想把它拉出来。声明的其余部分(“遭遇遭遇”)相当武断,就本例而言,可能是任何事情。
对于这个例子,我已经掀起了这个快速的语法:
grammar test;
stat: OCCURRENCE PHRASE;
OCCURRENCE: 'Occurrence' LABEL 'of' ;
fragment LABEL: [A-Z] ;
PHRASE: (WORD ' ')* WORD ;
fragment WORD: [a-zA-Z\-]+ ;
WS: [ \t\n\r]+ -> skip ;
如果我针对上述陈述对其进行测试,则失败(“1:0行在'遇到的遭遇的发生A'时失去了发生'”)。我相信这是因为词法分析器将匹配可以消耗最多连续字符的令牌(在这种情况下为PHRASE)。
所以...我理解这个问题 - 我不清楚最好的解决方案。可能吗?或者我需要只使用与单词边界匹配的词法分析器和将它们组合成短语的解析器?我更喜欢在词法分析器中这样做,因为短语(如“遭遇遭遇”)实际上是一个单元。
我是ANTLR(以及一般的词法分析器/解析器)的新手,所以如果解决方案很简单,请原谅我!然而,到目前为止,我还没有找到答案。谢谢你的帮助!
答案 0 :(得分:1)
虽然有一种方法可以在词法分析器**中做你想做的事情,但是在这样一个简单的语法上,它不太值得付出努力。此外,通过将所有内容打包到一个令牌中,您可以将自己设置为最终在令牌字符串中手动挖掘,以便选择LABEL的值。
您仍然可以定义语义上合适的规则 - 反映您认为是“令牌”的规则 - 就像简单的“较低级别”解析器规则一样:
stat: occurrence phrase ;
occurrence: OCCURRENCE label=WORD OF ;
phrase: WORD+ ;
OCCURRENCE: 'Occurrence' ;
OF: 'of' ;
WORD: [a-zA-Z\-]+ ;
WS: [ \t\n\r]+ -> skip ;
**如果您真的想要,可以实现词法分析器模式,并使用'more'运算符将OCCURRENCE ...字符串消耗为单个标记。这是未经测试的 - 我认为“更多”将如图所示工作,但如果不是,您将需要自己打包令牌文本。无论如何,它说明了你所说的你希望做的事情的潜在复杂性。
OCCURRENCE: 'Occurrence' -> pushMode(stuff), more ;
mode stuff ;
OF: 'of' -> popMode, more ;
OTHER: . -> more ;