2016-11-30 72 views
0

我想在ANTLR4中构建一个自然语言日期解析器,并被卡在忽略“噪声”输入上。下面的简化语法分析包含格式日期月份有效日期的任何字符串:忽略ANTLR4中的“噪声”

dates 
    : simple_date dates 
    | EOF 
    ; 

simple_date 
    : DATE MONTH 
    ; 

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

文字,如“1年1月22日”将被接受。我想语法接受其他文字一样,所以我在结尾加上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规则匹配两次,但字符串“On 1XX January”也将匹配规则。

问题:如何建立在这种规则只与确切令牌序列相匹配的语法,而忽略其他所有输入,包括在任何规则没有定义的命令令牌?考虑以下情况:

"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 
+0

你需要发布一个工作语法。你的语法如何匹配“2月22日2月”?有些规则应该使用未显示的+或*运算符。 – JavaMan

+0

对不起,在语法中出现了一个错字 - 我已经在顶级规则中将'date'更改为'dates',以使其按照描述工作。 – David

回答

0

不要在诸如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词法分析器规则还拦截了一个独立的月份文字(例如1月),该文字被认为是一种噪音,但未在我的语法中处理,例如

22 February January 
+0

谢谢,这看起来很有前途,真的帮助我理解了这个问题。我测试了语法,但仍然缺少一件事 - simple_date规则似乎只匹配具有多个正确日期的字符串中最后一次出现的“DATE MONTH”。 '1月1日和2月22日噪音33'匹配“2月22日”,但忽略“1月1日”。 – David

+0

我也不明白为什么在诸如'1月1日,2月2日'这样的字符串中,“1月”部分被认为是“噪声”。 – David

+0

@大卫,我的语法本来是一个粗略的草案,而不是一个完整的解决方案。它绝对不包括你所有的情况。但在'1月1日和2月22日的噪音33'中,'simple_date'应该匹配'1月1日和2月22日',而其余的则与噪音相匹配。 – JavaMan