使用ANTLR的QuickBasic语法
我正在使用ANTLR和以下语法:使用ANTLR的QuickBasic语法,antlr,Antlr,我正在使用ANTLR和以下语法: grammar QuickBasic; options { language = 'CSharp2'; output = AST; } parse : block EOF ; block : (labelStatement | labeledStatement | statement)* ; labelStatement : label ':' -> ^(label)
grammar QuickBasic;
options
{
language = 'CSharp2';
output = AST;
}
parse
: block EOF
;
block
: (labelStatement | labeledStatement | statement)*
;
labelStatement
: label ':' -> ^(label)
;
labeledStatement
: label statement -> ^(label statement)
;
statement
: assignment
;
assignment
: IDENTIFIER '=' value -> ^('=' IDENTIFIER value)
;
value
: (IDENTIFIER | constant)
;
constant
: (STRING | INTEGER | REAL)
;
label
: (ALPHANUMERIC)+
;
IDENTIFIER
: LETTER (ALPHANUMERIC)*
;
REAL
: (INTEGER '.' NATURAL)
;
INTEGER
: ('-')? NATURAL
;
SPACE
: (' ' | '\t' | '\r' | '\n' | '\u000C') {Skip();}
;
STRING
: '"' ('""' | ~'"')* '"'
;
fragment NATURAL
: (DIGIT)+
;
fragment ALPHANUMERIC
: (DIGIT | LETTER)
;
fragment DIGIT
: '0'..'9'
;
fragment LETTER
: ('a'..'z' | 'A'..'Z')
;
有了这个,我将尝试解析以下文件:
PI = 3.141592
CALC:
100 A = 1
接下来发生的事情是,行“CALC:”应该是一个标签,但它试图作为一个语句进行分析,并给我一个错误,说输入不匹配“:“应为”=”。尝试使用小写的skip()而不是skip(),以及类似的东西来允许多个空格
SPACE
: (' ' | '\t' | '\u000C' | '\n' | '\r' )+ {skip();}
;
您的
标签
规则错误:
label
: (ALPHANUMERIC)+
;
因为字母数字
是一个片段词法规则,所以它只能由其他词法规则使用,而不能在解析器规则中使用。您的lexer将只生成以下标记:IDENTIFIER
、INTEGER
、REAL
和STRING
(加上解析器规则中的文字标记,如。
等):使这些成为您可以在解析器规则中使用的唯一lexer规则
此外,您应该只创建具有唯一根的AST。您正试图为labelStatement
和labeledStatement
创建一个根,这使得它无法与其他解析器规则区分开来:使树漫游者(ANTLR的树漫游者或您自己的树漫游者)在遇到此类AST的根时出现问题。最好创建(虚拟的)LABEL
和LABEL\u STAT
标记,并将它们作为AST的根:
...
tokens
{
LABEL;
LABELED_STAT;
}
parse
: block EOF
;
...
labelStatement
: label ':' -> ^(LABEL label)
;
labeledStatement
: label statement -> ^(LABELED_STAT label statement)
;
...
label
: IDENTIFIER
| INTEGER
;
这将创建以下AST:
我以为“skip()”只是java基类“Lexer”上的一个方法。。。当我使用c#时,方法是“Skip()”。这是正确的吗?不,Skip()
而不是Skip()
,并且在空间中添加+
规则不会有什么区别。(@JonathasCosta,是的,你是对的)。