Lexer统治一句话

时间:2015-02-09 11:47:33

标签: antlr lexer

我知道词法规则是匹配单词而不是句子。但是有可能做到这一点。因为我的输入有以下格式

ADD FILE first-doc VERSION 1 TYPE sequential FIXED 23 BLOCK 23 MODE 
ebdic LABEL standard KEY REC_NR#09545 RULE DOMANI _ scorebestand MKC

和其他输入可能有类似的

ADD FILE secound-doc VERSION 3 TYPE normal FIXED 39 BLOCK 39 MODE 
gdieds LABEL constant KEY CTR-NR#62872 
RULE CBTPSN49 : dagextract (loadfile) met key PIB_KLN_NR 

在上面两个输入我的解析器规则看起来像

add_file   :
'ADD FILE' file=String 'VERSION' ver=Integer 'TYPE' String 
'FIXED' Integer 'BLOCK' Integer 'MODE' codePage=String
'LABEL' String KEY  key=String ;

我能够写到KEY,因为所有内容都是单个单词但无法继续使用RULE因为它随句子而变化

即使我尝试过贪婪的比赛

All   : .*;

但它给我带来了错误。

以上声明的Lexer规则

WhiteSpace: ('\r' | '\t' | '\u000C' | '\n' | ' ') { $channel=HIDDEN; };

COMMENT:('**'.*'\n'|'REMARKS'.*'\n')*{skip();};

String: ('a'..'z'|'A'..'Z'|'-'|'#') ('a'..'z'|'A'..'Z'|'0'..'9'|'-'|'#')*;

Integer: '-'? ('0' | '1'..'9' ('0'..'9')*);

我的问题是“是否可以将多个单词与一个词法分析器规则匹配? 如果是这样的话怎么办?“

我只能在ANTLR 4中实现这一目标吗?我对这个ANTLR只有两个星期了 请帮忙。

提前致谢

2 个答案:

答案 0 :(得分:1)

下面的 ANTLR4 解析器规则会读取所有内容,直到该行结束。

add_file   :
'ADD FILE' file=String 'VERSION' ver=Integer 'TYPE' String 
'FIXED' Integer 'BLOCK' Integer 'MODE' codePage=String
'LABEL' String 'KEY'  key=String 'RULE' expr=everything_until_CR '\r'? '\n'?;

everything_until_CR : ~('\n'|'\r')* ;

ANTLR3 中,遗憾的是这似乎不起作用。解决方法 lexer 规则如下所示。你必须剥离领先的" RULE"用目标语言。

RULE : 'RULE ' ~('\n'|'\r')* ;

add_file   :
  'ADD FILE' file=String 'VERSION' ver=Integer 'TYPE' String 
  'FIXED' Integer 'BLOCK' Integer 'MODE' codePage=String
  'LABEL' String 'KEY'  key=String
  expr=RULE '\r'? '\n'? {System.out.println($expr.text.substring(5));}
;

如果您确实需要上下文相关的 lexer 规则,请查看island grammars(链接到ANTLR3 doc)。 '希望这有帮助!

答案 1 :(得分:0)

我想出了另一种解析句子的方法,只需在最后添加String*。请看下面我的语法,它接缝效果很好

add_file : 'ADD FILE' file=String 'VERSION' ver=Integer 'TYPE' String 'FIXED' Integer 'BLOCK' Integer 'MODE' codePage=String 'LABEL' String 'KEY' key=String 'RULE' String*;

//字符串的Lexer规则

String: ('a'..'z'|'A'..'Z'|'-'|'#'|':') ('a'..'z'|'A'..'Z'|'0'..'9'|'-'|'#'|':')*;