ANTLR4:lexer规则:任何字符串,只要它不';是否不包含这两个并排的字符?
有没有办法用ANTLR4来表达这一点: 任何字符串,只要它不立即包含星号 然后是正斜杠 这不起作用:ANTLR4:lexer规则:任何字符串,只要它不';是否不包含这两个并排的字符?,antlr,grammar,antlr4,lexer,lexical-analysis,Antlr,Grammar,Antlr4,Lexer,Lexical Analysis,有没有办法用ANTLR4来表达这一点: 任何字符串,只要它不立即包含星号 然后是正斜杠 这不起作用:(~'*/')*由于Antll引发此错误:在lexer集合中不允许使用多字符文字:'*/' 这是可行的,但并不正确:(~[*/])*因为它禁止包含单个字符的字符串*或/我能做的最接近的事情是将测试放在解析器中,而不是放在词法分析器中。这不完全是你想要的,但确实有效 诀窍是在必须测试任何有害字符的字符串之前使用语义谓词。实际测试是用Java完成的 grammar myTest; @header {
(~'*/')*
由于Antll引发此错误:在lexer集合中不允许使用多字符文字:'*/'
这是可行的,但并不正确:
(~[*/])*
因为它禁止包含单个字符的字符串*
或/
我能做的最接近的事情是将测试放在解析器中,而不是放在词法分析器中。这不完全是你想要的,但确实有效
诀窍是在必须测试任何有害字符的字符串之前使用语义谓词。实际测试是用Java完成的
grammar myTest;
@header
{
import java.util.*;
}
@parser::members
{
boolean hasEvilCharacters(String input)
{
if (input.contains("*/"))
{
return false;
}
else
{
return true;
}
}
}
// Mimics a very simple sentence, such as:
// I am clean.
// I have evil char*/acters.
myTest
: { hasEvilCharacters(_input.LT(1).getText()) }? String
(Space { hasEvilCharacters(_input.LT(1).getText()) }? String)*
Period EOF
;
String
: ('A'..'Z' | 'a'..'z')+
;
Space
: ' '
;
Period
: '.'
;
通过NetBeans 8.0.1中AntlWorks 2中的TestRig使用ANTLR 4.4进行测试。如果不允许的序列很少,则存在一个没有解析器/词法分析器操作的解决方案:
grammar NotParser;
program
: (starslash | notstarslash)+
;
notstarslash
: NOT_STAR_SLASH
;
starslash
: STAR_SLASH
;
STAR_SLASH
: '*'+ '/'
;
NOT_STAR_SLASH
: (F_NOT_STAR_SLASH | F_STAR_NOT_SLASH) +
;
fragment F_NOT_STAR_SLASH
: ~('*'|'/')
;
fragment F_STAR_NOT_SLASH
: '*'+ ~('*'|'/')
| '*'+ EOF
| '/'
;
这个想法是为了组成
- 既不是“*”也不是“/”的所有令牌
- 以“*”开头但后跟“/”或单个“/”的所有标记
有一些规则处理特殊情况(多个“”后跟“/”,或尾随“”)我有类似的问题,我的解决方案:
(~'*'.|)('*'+~[/*])*'*'*.
你能提供一些关于你试图实现什么的详细信息吗?必须将不带-*/的字符串绝对识别为单个lexer标记吗?嗨,Marc。是的,一个lexer标记:lexer规则应该返回一个字符串,只要它不包含*/在ANTLR中应该有一个简单的方法来实现这一点。谢谢James!哇,要解决这么简单的问题需要做大量的工作。有人能解释一下这是怎么回事吗?我看不出它在哪里捕获了包含“*”的令牌。(我在解析方法hasEvilCharacters()
中查找,该方法由myTest
解析器规则中的语义谓词调用。有关更多信息,请阅读最终ANTLR 4参考中的第10章……如果文件中的最后一个字符是“*”,ANTLR会发生什么情况?对于特殊情况,“/”测试做什么或接受什么?现在应该做什么(尾随“”、单个“/”、多个“”)。可能解析树与预期不符……但在不了解应用程序的情况下,很难对其进行调整。您和我的答案的复杂性和不可伸缩性表明了ANTLR 4中的一个弱点——或者说这是一个机会?。如果您为带有/*....*/注释的语言编写了多个lexer,您应该已经知道这个技巧。