首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ANTLR语言的QuickBasic语法

使用ANTLR语言的QuickBasic语法
EN

Stack Overflow用户
提问于 2012-05-29 11:57:31
回答 2查看 731关注 0票数 1

我使用的是ANTLR和以下语法:

代码语言:javascript
复制
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')
    ;

有了这个,我尝试解析下面的文件:

代码语言:javascript
复制
PI = 3.141592
CALC:
100 A = 1

接下来发生的事情是,'CALC:‘行应该是一个标签,但它试图解析为一个语句,并给我一个错误,说不匹配的输入':’预期的'=‘。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-29 15:53:10

您的label规则错误:

代码语言:javascript
复制
label
    :    (ALPHANUMERIC)+
    ;

因为ALPHANUMERIC是片段词法分析器规则,所以它只能由其他词法分析器规则使用,而不能在解析器规则中使用。您的词法分析器将只生成以下标记:IDENTIFIERINTEGERREALSTRING (加上解析器规则中的文字标记,如'.'等):使这些规则成为解析器规则中唯一可以使用的词法分析器规则。

此外,您应该只创建具有唯一根的AST。您正在尝试为labelStatementlabeledStatement创建一个根,这不会使它与其他解析器规则区分开来:使树遍历器(无论是ANTLR的树遍历器,还是您自己的树遍历器)在遇到此类AST的根时出现问题。更好的方法是创建(虚构的) LABELLABELED_STAT标记,并使它们成为你的AST的根:

代码语言:javascript
复制
...

tokens 
{
    LABEL;
    LABELED_STAT;
}

parse
    :    block EOF
    ;

...

labelStatement
    :    label ':' -> ^(LABEL label)
    ;

labeledStatement
    :    label statement -> ^(LABELED_STAT label statement)
    ;

...

label
    :    IDENTIFIER
    |    INTEGER
    ;

这将创建以下AST:

票数 2
EN

Stack Overflow用户

发布于 2012-05-29 13:02:17

尝试使用小写skip()而不是Skip(),并使用类似下面的内容来允许多个空格

代码语言:javascript
复制
SPACE
    :    (' ' | '\t' | '\u000C' | '\n' | '\r' )+ {skip();} 
    ;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10792880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档