微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Antlr模式匹配和词法分析器模式

如何解决Antlr模式匹配和词法分析器模式

我正在尝试为html grammar编译模式。以下代码显示了如何解析包含htmlAttributeRule的字符串:

String code = "href=\"val\"";
CharStream chars = CharStreams.fromString(code);
Lexer lexer = new HTMLLexer(chars);
lexer.pushMode(HTMLLexer.TAG);
TokenStream tokens = new CommonTokenStream(lexer);
HTMLParser parser = new HTMLParser(tokens);
parser.htmlAttribute();

但是当我尝试:

ParseTreePatternMatcher matcher = new ParseTreePatternMatcher(lexer,parser);
matcher.compile(code,HTMLParser.RULE_htmlAttribute);

它失败并出现错误

line 1:0 no viable alternative at input 'href="val"'

org.antlr.v4.runtime.NoViableAltException
at org.antlr.v4.runtime.atn.ParserATNSimulator.noViableAlt(ParserATNSimulator.java:2026)
at org.antlr.v4.runtime.atn.ParserATNSimulator.execATN(ParserATNSimulator.java:467)
at org.antlr.v4.runtime.atn.ParserATNSimulator.adaptivePredict(ParserATNSimulator.java:393)
at org.antlr.v4.runtime.ParserInterpreter.visitDecisionState(ParserInterpreter.java:316)
at org.antlr.v4.runtime.ParserInterpreter.visitState(ParserInterpreter.java:223)
at org.antlr.v4.runtime.ParserInterpreter.parse(ParserInterpreter.java:194)
at org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher.compile(ParseTreePatternMatcher.java:205)

当我尝试:

List<? extends Token> tokenList = matcher.tokenize(code);

结果包含单个标记,与将词法分析器与DEFAULT_MODE一起使用时相同。有什么办法可以解决这个问题?

解决方法

问题是来自ParseTreePatternMatcher::tokenize的以下代码:

TextChunk textChunk = (TextChunk)chunk;
ANTLRInputStream in = new ANTLRInputStream(textChunk.getText());
lexer.setInputStream(in);
Token t = lexer.nextToken();

Lexer::setInputStream清除_modeStack并将_mode设置为0。一种可能的解决方案是扩展ParseTreePatternMatcher,覆盖方法tokenize并将lexer.pushMode(lexerMode)插入lexer.setInputStream(in)之后:

TextChunk textChunk = (TextChunk)chunk;
ANTLRInputStream in = new ANTLRInputStream(textChunk.getText());
lexer.setInputStream(in);
lexer.pushMode(lexerMode);
Token t = lexer.nextToken();

但是方法tokenize使用ChunkTextChunk,它们不能从特大包中访问,因此我们必须在与ParseTreePatternMatcher相同的包中定义扩展类。

我正在考虑的另一种解决方案是使用ASM修改该方法的字节码。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。