我试图使用jparsec来定义和使用我相当简单的语法,但是我对如何去做它完全感到困惑。在这一点上,我不知道这是否是我对问题空间的理解不足,或者是jparsec的稀疏和无用的文档。或两者。jparsec中的混淆
我有一个语法是这样的:
foo='abc' AND bar<>'def' OR (biz IN ['a', 'b', 'c'] AND NOT baz = 'foo')
所以你可以看到它支持运营商如AND
,OR
,NOT
,IN
,=
,<>
。它还支持任意嵌套的括号来决定优先级。
我想我用标记化得到了相当多的东西。下面是我有:
public final class NewParser {
// lexing
private static final Terminals OPERATORS = Terminals.operators("=", "OR", "AND", "NOT", "(", ")", "IN", "[", "]", ",", "<>");
private static final Parser<?> WHITESPACE = Scanners.WHITESPACES;
private static final Parser<?> FIELD_NAME_TOKENIZER = Terminals.Identifier.TOKENIZER;
private static final Parser<?> QUOTED_STRING_TOKENIZER = Terminals.StringLiteral.SINGLE_QUOTE_TOKENIZER.or(Terminals.StringLiteral.DOUBLE_QUOTE_TOKENIZER);
private static final Parser<?> IGNORED = Parsers.or(Scanners.WHITESPACES).skipMany();
private static final Parser<?> TOKENIZER = Parsers.or(OPERATORS.tokenizer(), WHITESPACE, FIELD_NAME_TOKENIZER, QUOTED_STRING_TOKENIZER).many();
@Test
public void test_tokenizer() {
Object result = TOKENIZER.parse("foo='abc' AND bar<>'def' OR (biz IN ['a', 'b', 'c'] AND NOT baz = 'foo')");
Assert.assertEquals("[foo, =, abc, null, AND, null, bar, <>, def, null, OR, null, (, biz, null, IN, null, [, a, ,, null, b, ,, null, c, ], null, AND, null, NOT, null, baz, null, =, null, foo,)]", result.toString());
}
}
test_tokenizer
通行证,所以我认为它的工作确定。
现在,我已经有了一个表示语法的类型层次结构。例如,我有类叫做Node
,BinaryNode
, FieldNode
, LogicalAndNode
,ConstantNode
等等。我试图做的是创建一个Parser
,它需要我的令牌并且吐出一个Node
。这是我一直陷入困境的地方。
我想我会用很简单的东西像这样开始:
private static Parser<FieldNode> fieldNodeParser =
Parsers.sequence(FIELD_NAME_TOKENIZER)
.map(new Map<Object, FieldNode>() {
@Override
public FieldNode map(Object from) {
Fragment fragment = (Fragment)from;
return new FieldNode(fragment.text());
}
});
我想我能做到这一点:
public static Parser<Node> parser = fieldNodeParser.from(TOKENIZER);
但是,这给了我一个编译错误:
The method from(Parser<? extends Collection<Token>>) in the type Parser<FieldNode> is not applicable for the arguments (Parser<capture#6-of ?>)
所以它看起来像我的仿制药在某处,但我不知道在哪里或如何解决这个问题。我甚至不确定我是否以正确的方式去解决这个问题。任何人都可以启发我吗?