我有一部分ANTLR4规则,我想向后解析。我怀疑这不是真正的解决方案,所以我可能会缺少一些东西。
我的问题的症结在于,我想要提取的表达中间有一部分。但是,如果可能的话,这部分有一些(定义的)后缀我真的想单独提取。这些后缀可以用逗号分隔或不用;语法可以正常使用逗号,但是如果逗号丢失,则整个部分都为unknown
,即使后缀存在也是如此。
我把我的语法简化成一个小例子,可以在这篇帖子的底部看到。
给定字符串why hello, x y z foo bar baz blah blah blah, goodbye!
,我的语法将x y z foo bar baz
解析为phrase
。我希望将x y z
与unknown
和foo bar baz
匹配作为后缀。如果有逗号(x y z, foo bar baz
),则有效:
但是,如果没有逗号,则整个x y z foo bar baz
(以及之后的一些文字)为unknown
:
我尝试将unknown
更改为不同意(+?
),但这也是不受欢迎的,只消耗phrase
的一个令牌:
有没有办法强制phrase
规则首先尝试匹配右边的后缀,然后再回到unknown
?
另一种说法:当结束带有一个或多个后缀时,有没有办法unknown
匹配除之外的任何内容? (后缀可以出现在文本中,只要它们不在最后)
示例语法:
grammar Example;
// parse tree root
exampleExpression : ignored HELLO separator phrase separator? unknown separator? GOODBYE ignored;
// what I want to match
phrase : unknown (COMMA? suffix+)*;
// convenience rule for swaths of tokens to be ignored (e.g. at the beginning and end)
ignored : (unknown | separator)*;
// roll up unknown tokens under one rule
unknown : (~(PERIOD | COMMA | PIPE | BULLET | SP_SEP_DASH))+;
separator : PERIOD | COMMA | PIPE | BULLET | SP_SEP_DASH;
// the pre-defined suffixes
suffix : FOO | BAR | BAZ;
/* TOKENS */
HELLO : 'hello';
GOODBYE : 'goodbye';
FOO : 'foo';
BAR : 'bar';
BAZ : 'baz';
/* FRAGMENTS */
fragment DIGIT : [0-9];
fragment DASH : '-';
/* REMAINING TOKENS */
LPAREN : '(' ;
RPAREN : ')' ;
COMMA : ',';
PERIOD : '.';
PIPE : '|';
BULLET : '\u00B7' | '\u2219' | '\u22c5';
SP_SEP_DASH : SP DASH SP;
SP : [ \u000B\t\r\n] -> channel(HIDDEN);
NUMBER : ([0] | [1-9] DIGIT*) ('.' DIGIT+)?;
WORD : [A-Za-z] [A-Za-z-]*;
// catch-all
OTHER : .;
答案 0 :(得分:1)
问题是:
另一种说法:除了以一个或多个后缀结尾之外,有没有办法让未知匹配? (后缀可以在文字中出现,只要它们不在最后)
但之前,有unknown
内部后缀的解析被拒绝了:
但是,如果没有逗号,则将整个x y z foo bar baz(以及之后的一些文本)视为未知
这似乎不一致。
从示例中,您似乎正在尝试进行自然语言解析;无论它的优点如何,ANTLR可能都不是一个好的工具。但这可能只是基于你的简化的幻想。
无论如何,原始问题的答案 - "是否可以将非终端定义为任何序列的令牌,这些令牌不会以后缀类中的一个或多个令牌结束&# 34;是的,是的,这可以写成无上下文语法"。在没有涉及ANTLR细节的情况下,这是一个简单的CFG:
wordlist: /* empty */ | wordlist non_suffix | wordlist suffix_list non_suffix ;
suffix_list: suffix | suffix_list suffix ;