Java JParsec在简单测试中失败
我正在尝试使用尽可能最简单的解析器来处理JPARSEC2.0.1,但运气不好。我有以下AST课程:Java JParsec在简单测试中失败,java,parsing,jparsec,Java,Parsing,Jparsec,我正在尝试使用尽可能最简单的解析器来处理JPARSEC2.0.1,但运气不好。我有以下AST课程: public abstract class Node { } public final class ConstantNode extends Node { private final String value; public ConstantNode(String value) { this.value = value; } @Override
public abstract class Node {
}
public final class ConstantNode extends Node {
private final String value;
public ConstantNode(String value) {
this.value = value;
}
@Override
public String toString() {
return this.value;
}
}
以及以下测试代码:
import junit.framework.Assert;
import org.codehaus.jparsec.Parser;
import org.codehaus.jparsec.Parsers;
import org.codehaus.jparsec.Scanners;
import org.codehaus.jparsec.Terminals;
import org.codehaus.jparsec.Token;
import org.codehaus.jparsec.functors.Map;
import org.junit.Test;
import ast.ConstantNode;
import ast.Node;
public class ParserTest {
private static final Parser<Token> CONSTANT_LEXER = Parsers
.or(Terminals.StringLiteral.SINGLE_QUOTE_TOKENIZER,
Terminals.StringLiteral.DOUBLE_QUOTE_TOKENIZER)
.token();
private static final Parser<Node> CONSTANT_PARSER = CONSTANT_LEXER.map(new Map<Token, Node>() {
@Override
public Node map(Token from) {
return new ConstantNode(from.toString());
}
});
private static final Parser<Void> IGNORED = Scanners.WHITESPACES;
@Test
public void testParser() {
Object result = null;
// this passes
result = CONSTANT_LEXER.parse("'test'");
Assert.assertEquals("test org.codehaus.jparsec.Token", result + " " + result.getClass().getName());
// this fails with exception: org.codehaus.jparsec.error.ParserException: Cannot scan characters on tokens.
result = CONSTANT_PARSER.from(CONSTANT_LEXER, IGNORED).parse("'test'");
Assert.assertEquals("test ast.ConstantNode", result + " " + result.getClass().getName());
}
}
然而,这对我来说还没有完全成功。我怀疑有更好的方法可以做到这一点,所以我对任何想法都非常感兴趣。您正在混合两种不同的“解析器”:字符串解析器。JParsec中的扫描仪和令牌解析器:
CONSTANT\u PARSER.from(CONSTANT\u LEXER,忽略)。parse('test')代码>
本质上说,常量语法分析器应该以令牌流的形式从常量语法分析器获取其输入,并将忽略作为分隔符。问题是常量语法分析器是由“映射”常量语法分析器定义的,这意味着它使用语法分析器解析输入,而不是映射结果。这会引发以下错误:
org.codehaus.jparsec.error.ParserException:无法扫描令牌上的字符。
通过将常量解析器定义为Parsers.tokenType(Token.class,“CONSTANT”)
可以有效地说解析器使用一个令牌流,将它们命名为CONSTANT
。然而,我认为这并不像您期望的那样有效,因为这将匹配任何类型的令牌,而不仅仅是常量
这当然是JParsec中文档较少的部分之一,而且也没有很好的文档记录
private static final Parser<Node> CONSTANT_PARSER = Parsers.tokenType(Token.class, "constant").map(new Map<Token, Node>() {
@Override
public Node map(Token from) {
return new ConstantNode(from.toString());
}
});