Antlr4 解析fortran style.op。操作员
我正试图为一个受fortran启发的DSL编写一个ANTLR4语法。我在“ole classic”方面遇到困难。op.“运算符:Antlr4 解析fortran style.op。操作员,antlr4,Antlr4,我正试图为一个受fortran启发的DSL编写一个ANTLR4语法。我在“ole classic”方面遇到困难。op.“运算符: if (1.and.1) then 其中,两个“1”都应解释为整数。我查看了OpenFortranParser以获得洞察力,但我无法理解它 最初,我在lexer中对INTEGER和REAL有合适的定义。因此,不管我怎么做,上面的第一个“1”总是解析为实数。我尝试将东西移动到解析器中,并使它能够可靠地识别“.”和“.”以及它周围的数字作为适当的整数或实数 if (1.
if (1.and.1) then
其中,两个“1”都应解释为整数。我查看了OpenFortranParser以获得洞察力,但我无法理解它
最初,我在lexer中对INTEGER和REAL有合适的定义。因此,不管我怎么做,上面的第一个“1”总是解析为实数。我尝试将东西移动到解析器中,并使它能够可靠地识别“.”和“.”以及它周围的数字作为适当的整数或实数
if (1.and.1) # INT/INT
if (1..and..1) # REAL/REAL
……等等
我当然想在这样的语句中识别变量名:
if (a.and.b)
在下面的小语法中,引号中的任何文字(例如,'和','如果',所有单字符数字后缀)都不被接受为ID,我得到一个错误;接受任何其他符合ID的字符串:
if (a.and.b) # errs, as 'b' is valid INTEGER suffix
if (a.and.c) # OK
对这种行为的任何见解,或关于如何解析.op的更好建议。fortran中的运算符将不胜感激--谢谢
grammar Foo;
start : ('if' expr | ID)+ ;
DOT : '.' ;
DIGITS: [0-9]+;
ID : [a-zA-Z0-9][a-zA-Z0-9_]* ;
andOp : DOT 'and' DOT ;
SIGN : [+-];
expr
: ID
| expr andOp expr
| numeric
| '(' expr ')'
;
integer : DIGITS ('q'|'Q'|'l'|'L'|'h'|'H'|'b'|'B'|'i'|'I')? ;
real
: DIGITS DOT DIGITS? (('e'|'E') SIGN? DIGITS)? ('d' | 'D')?
| DOT DIGITS (('e'|'E') SIGN? DIGITS)? ('d' | 'D')?
;
numeric : integer | real;
EOLN : '\r'? '\n' -> skip;
WS : [ \t]+ -> skip;
为了消除点的歧义,在点规则之前添加一个带谓词的词法规则
DIT : DOT { isDIT() }? ;
DOT : '.' ;
更改“andOp”
andOp : DIT 'and' DIT ;
然后添加一个谓词方法
@lexer::members {
public boolean isDIT() {
int offset = _tokenStartCharIndex;
String r = _input.getText(Interval.of(offset-4, offset));
String s = _input.getText(Interval.of(offset, offset+4));
if (".and.".equals(s) || ".and.".equals(r)) {
return true;
}
return false;
}
}
但是,这并不是你当前问题的根源。整数解析器规则在lexer之外有效地定义lexer常量,这就是为什么“b”与ID不匹配的原因
换成
integer : INT ;
INT: DIGITS ('q'|'Q'|'l'|'L'|'h'|'H'|'b'|'B'|'i'|'I')? ;
lexer将计算出其余的部分。使用ANTLR4,('q'|'q'|'l'|'l'|'h'|'h'|'b'|'i'|'i')
可以写成[qllhbbii]
。