使用antlr 4

时间:2016-11-02 08:11:28

标签: antlr antlr4

我想解析以下类型的日期:

  • 15 / APR / 2016
  • apr 15th

所以这是我的语法:

date: formal_date|explicit_date|EOF;

formal_date:
     INT SEPARATOR month SEPARATOR INT
    | INT SEPARATOR month SEPARATOR INT4
    | INT SEPARATOR INT SEPARATOR INT4;

explicit_date:
         INT TH OF month
     ;

month : JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC ;

number : FLOAT | INT | INT4 ;

// lexer rules

FLOAT : DIGIT+ '.' DIGIT+ ;

INT4 : DIGIT DIGIT DIGIT DIGIT;
INT : DIGIT+;

JAN : [Jj][Aa][Nn] ;
FEB : [Ff][Ee][Bb] ;
MAR : [Mm][Aa][Rr] ;
APR : [Aa][Pp][Rr] ;
MAY : [Mm][Aa][Yy] ;
JUN : [Jj][Uu][Nn] ;
JUL : [Jj][Uu][Ll] ;
AUG : [Aa][Uu][Gg] ;
SEP : [Ss][Ee][Pp] ;
OCT : [Oo][Cc][Tt] ;
NOV : [Nn][Oo][Vv] ;
DEC : [Dd][Ee][Cc] ;

SEPARATOR : [/\\\-] ;

ON : [Oo][Nn] ;
TH : [Tt][Hh] ;
OF : [Oo][Ff] ;

fragment DIGIT : [0-9];

这些是antlr的输出:

Parsing: 15/apr/2016
Tree: (date (formal_date 15 / (month apr) / 2016))

Parsing: 15th of apr
Tree: (date (explicit_date 15 th of (month apr)))

但是如果我将像birthday on 15th of apr这样的句子传递给antlr,它将解析一个错误的树:

Parsing : birthday on 15th of apr
Tree: (date th on 15 th of apr)

那么有没有解决这个问题?例如,跳过th中的birthday

1 个答案:

答案 0 :(得分:1)

这里的语法按你想要的方式工作(抱歉没有时间在我写评论的时候写答案)

grammar testDate;

date: formal_date|explicit_date|EOF;

formal_date:
     INT SEPARATOR month SEPARATOR INT
    | INT SEPARATOR month SEPARATOR INT4
    | INT SEPARATOR INT SEPARATOR INT4;

explicit_date:
         INT TH OF month
     ;

month : JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC ;

number : FLOAT | INT | INT4 ;

// lexer rules

FLOAT : DIGIT+ '.' DIGIT+ ;

INT4 : DIGIT DIGIT DIGIT DIGIT;
INT : DIGIT+;

JAN : [Jj][Aa][Nn] ;
FEB : [Ff][Ee][Bb] ;
MAR : [Mm][Aa][Rr] ;
APR : [Aa][Pp][Rr] ;
MAY : [Mm][Aa][Yy] ;
JUN : [Jj][Uu][Nn] ;
JUL : [Jj][Uu][Ll] ;
AUG : [Aa][Uu][Gg] ;
SEP : [Ss][Ee][Pp] ;
OCT : [Oo][Cc][Tt] ;
NOV : [Nn][Oo][Vv] ;
DEC : [Dd][Ee][Cc] ;

SEPARATOR : [/\\\-] ;

//ON : [Oo][Nn];
TH : [Tt][Hh]' ' ;
ND : [Nn][Dd]' ' ;
RD : [Rr][Dd]' ' ;
OF : [Oo][Ff]' ';

fragment REST : [A-Za-z \n\t\r];
REST_L : REST+? -> skip;

fragment DIGIT : [0-9];

当然,根据您想要扩展和扩展的方式,可能会缺少一些东西。几点解释

  • 词法分析器REST_L最后匹配+?,这就是 非贪婪的运营商
  • 令牌ON已删除(已注释掉),因为您没有使用它 任何解析器规则
  • 为代币th,nd,rd,of添加了一个空格 - 这只是我有时用来获取所需内容的技巧。 (实现这一目标的正确方法是使用词法分析器模式,当我们知道它是日期的一部分时我们有模式,而当它不是时,我们就会有模式)

因此,对于输入birthday on 15th of apr,您将获得以下解析树:

enter image description here