【问题标题】:Ignoring "noise" in ANTLR4忽略 ANTLR4 中的“噪音”
【发布时间】:2016-11-30 01:04:35
【问题描述】:

我想在 ANTLR4 中构建一个自然语言日期解析器,但一直在忽略“噪音”输入。下面的简化语法解析包含格式为 DATE MONTH 的有效日期的任何字符串:

dates
    : simple_date dates
    | EOF
    ;

simple_date
    : DATE MONTH
    ;

DATE  : [0-9][0-9]?;
MONTH : January | February | March // etc.;

将接受诸如“1 January 22 February”之类的文本。我希望语法也接受其他文本,所以我在末尾添加了ANY : . -> skip;

dates
    : simple_date dates
    | EOF
    ;

simple_date
    : DATE MONTH
    ;

DATE  : [0-9][0-9]?;
MONTH : January | February | March // etc.;
ANY   : . -> skip;

然而,这并不完全符合我的要求。虽然接受了诸如“1 月 1 日和 2 月 22 日”之类的字符串并且 simple_date 规则匹配了两次,但字符串“1 月 1XX 日”也将匹配该规则。

问题:我如何构建一个语法,其中规则仅与 exact 标记序列匹配,而忽略所有其他输入,包括未在任何规则中定义的顺序的标记?考虑以下情况:

"From 1 January to 2 February" -> simple_date matches "1 January" and "2 February"
"From 1XX January to 2 February" -> simple_date matches "2 February", rest is ignored
"From January to February" -> no match, everything ignored

【问题讨论】:

  • 你需要发布一个有效的语法。你的语法如何匹配“1 January 22 February”?有些规则应该使用 + 或 * 运算符,但未显示。
  • 抱歉,语法中有错字 - 我已将顶级规则中的 date 更改为 dates 以使其按所述工作。

标签: parsing grammar antlr4


【解决方案1】:

不要在词法分析器中丢弃额外的“噪音”,例如您的 ANY 规则。 Lexer 不知道当前令牌是在什么上下文中。而你想要的是“当它不是 DATE MONTH 的形式时丢弃一些噪音标记”。将您的 ANY 规则移至与噪声匹配的解析器规则。

此外,建议在 LEXER 中删除空格。但在这种情况下,您的 ANY 规则应排除那些与 WS 规则匹配的规则。另请注意,您的 DATE 规则拦截了 [0-9][0-9] 形式的噪声标记?

dates
    : (noise* (simple_date) noise*)+

    ;

simple_date
    : DATE MONTH
    ;
noise: (DATE|ANY);

DATE  : [0-9][0-9]?;
MONTH : 'January' | 'February' | 'March' ;
ANY   : ~(' '|'\t' | '\f')+ ;
WS    : [ \t\f]+ -> skip;

接受:

1 January and 22 February  noise 33
1 January and 22 February 3

拒绝:

1xx January

这没有经过全面测试。此外,您的 MONTH 词法分析器规则还截获了一个独立的月份文字(例如一月),这被认为是一种噪音,但在我的语法中没有处理,例如

22 February January 

【讨论】:

  • 谢谢,这看起来很有希望,确实帮助我理解了这个问题。我测试了你的语法,但仍然缺少一件事 - simple_date 规则似乎只匹配具有多个正确日期的字符串中最后一次出现的 DATE MONTH,例如1 January and 22 February noise 33 匹配“2 月 22 日”,但忽略“1 月 1 日”。
  • 我也不明白为什么在1 January, 2 February 等字符串中,“January”部分被认为是noise
  • @David,我的语法本来是草稿,而不是完整的解决方案。它绝对不能涵盖您的所有情况。但是在1 January and 22 February noise 33 中,simple_date 应该同时匹配1 January22 February,而其余的则匹配noise
  • 1 January, 2 February 这样的输入会导致问题,因为January,January 长,因此词法分析器将ANY 视为ANY,因此成为noise 解析器规则。因此最好有单独的词法分析器规则匹配标识符[a-zA-Z0-9]+ 和符号 (','|'.'|....)+。有激进的词法分析器规则匹配非特定模式的东西通常会导致这样的麻烦。始终在词法分析器规则中说明您想要的内容
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 2012-10-31
  • 2019-09-14
  • 2022-01-06
  • 2022-11-09
  • 1970-01-01
相关资源
最近更新 更多