我使用的是ANTLR和以下语法:
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:‘行应该是一个标签,但它试图解析为一个语句,并给我一个错误,说不匹配的输入':’预期的'=‘。
发布于 2012-05-29 15:53:10
您的label规则错误:
label
: (ALPHANUMERIC)+
;因为ALPHANUMERIC是片段词法分析器规则,所以它只能由其他词法分析器规则使用,而不能在解析器规则中使用。您的词法分析器将只生成以下标记:IDENTIFIER、INTEGER、REAL和STRING (加上解析器规则中的文字标记,如'.'等):使这些规则成为解析器规则中唯一可以使用的词法分析器规则。
此外,您应该只创建具有唯一根的AST。您正在尝试为labelStatement和labeledStatement创建一个根,这不会使它与其他解析器规则区分开来:使树遍历器(无论是ANTLR的树遍历器,还是您自己的树遍历器)在遇到此类AST的根时出现问题。更好的方法是创建(虚构的) LABEL和LABELED_STAT标记,并使它们成为你的AST的根:
...
tokens
{
LABEL;
LABELED_STAT;
}
parse
: block EOF
;
...
labelStatement
: label ':' -> ^(LABEL label)
;
labeledStatement
: label statement -> ^(LABELED_STAT label statement)
;
...
label
: IDENTIFIER
| INTEGER
;这将创建以下AST:

发布于 2012-05-29 13:02:17
尝试使用小写skip()而不是Skip(),并使用类似下面的内容来允许多个空格
SPACE
: (' ' | '\t' | '\u000C' | '\n' | '\r' )+ {skip();}
;https://stackoverflow.com/questions/10792880
复制相似问题