Tôi đang cố gắng sử dụng jparsec để xác định và sử dụng ngữ pháp khá đơn giản của tôi, nhưng tôi hoàn toàn bối rối về cách thực hiện nó. Tôi không biết tại thời điểm này cho dù đó là sự hiểu biết không đầy đủ của tôi về không gian vấn đề, hoặc tài liệu thưa thớt và không rõ ràng của jparsec. Hoặc cả hai.Lẫn lộn trong jparsec
Tôi có một cái gì đó ngữ pháp như thế này:
foo='abc' AND bar<>'def' OR (biz IN ['a', 'b', 'c'] AND NOT baz = 'foo')
Vì vậy, bạn có thể thấy nó hỗ trợ các nhà khai thác như AND
, OR
, NOT
, IN
, =
, <>
. Nó cũng hỗ trợ các dấu ngoặc đơn tùy ý để ra lệnh ưu tiên.
Tôi nghĩ rằng tôi đã khá xa vời với cách viết hoa. Dưới đây là những gì tôi có:
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
đèo, vì vậy tôi nghĩ rằng nó hoạt động OK.
Bây giờ, tôi đã có một hệ thống phân cấp kiểu đại diện cho cú pháp. Ví dụ: tôi có các lớp được gọi là Node
, BinaryNode
, FieldNode
, LogicalAndNode
, ConstantNode
và vân vân. Và những gì tôi đang cố gắng làm là tạo ra một Parser
lấy mã của tôi và nhổ ra một số Node
. Và đây là nơi tôi tiếp tục gặp khó khăn.
tôi nghĩ rằng tôi muốn bắt đầu với một cái gì đó thực sự đơn giản như thế này:
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());
}
});
tôi nghĩ rằng tôi muốn có thể làm điều này:
public static Parser<Node> parser = fieldNodeParser.from(TOKENIZER);
Nhưng điều đó mang lại cho tôi một lỗi biên dịch:
The method from(Parser<? extends Collection<Token>>) in the type Parser<FieldNode> is not applicable for the arguments (Parser<capture#6-of ?>)
Vì vậy, có vẻ như generics của tôi bị siết chặt ở đâu đó, nhưng tôi không biết làm cách nào hoặc cách khắc phục điều này. Tôi thậm chí không chắc chắn tôi đang đi về điều này một cách đúng đắn. Ai có thể khai sáng cho tôi không?