【问题标题】:ANTLRworks creating interpreter from grammarANTLRworks 从语法创建解释器
【发布时间】:2012-02-03 16:48:54
【问题描述】:

嘿,我有一个简单的问题。我正在使用 ANTLRworks 从一组语法中创建一个 Java 解释器。我打算用手把它写出来,但后来意识到我不需要因为 antlrworks。虽然我收到了这个错误

T.g:9:23:标签 ID 与同名令牌冲突

从语法创建解释器时,ANTLR 是否可行。你们都看到我的代码中有任何错误吗?

我正在尝试将 ID 设为从 a-z 开始的一个字母,并且不区分大小写。并在每个词位之间留有空白。谢谢你

grammar T;

programs : ID WS compound_statement;

statement:       
if_statement|assignment_statement|while_statement|print_statement|compound_statement;

compound_statement: 'begin' statement_list 'end';

statement_list: statement|statement WS statement_list;  

if_statement:    'if' '(' boolean_expression ')' 'then' statement 'else' statement;

while_statement:    'while' boolean_expression 'do' statement;

assignment_statement:   ID = arithmetic_expression;

print_statement:    'print' ID;

boolean_expression: operand relative_op operand;

operand :   ID |INT;

relative_op:    '<'|'<='|'>'|'>='|'=='|'/=';

arithmetic_expression:  operand|operand WS arithmetic_op WS operand;

arithmetic_op:  '+'|'-'|'*'|'/';


ID  :   ('a'..'z'|'A'..'Z'|'_').
;

INT :   '0'..'9'+
;
WS  :   ( ' '
    | '\t'
    | '\r'
    | '\n'
    ) {$channel=HIDDEN;}
;

这里是语法

<program> → program id <compound_statement>

<statement> → <if_statement> | <assignment_statement> | <while_statement> |     
<print_statement> | <compound_statement>

<compound_statement> → begin <statement_list> end

<statement_list> → <statement> | <statement> ; <statement_list>

<if_statement> → if <boolean_expression> then <statement> else <statement>

<while_statement> → while <boolean_expression> do <statement>

<assignment_statement> -> id := <arithmetic_expression>

<print_statement> → print id

<boolean_expression> → <operand> <relative_op> <operand>

<operand> → id | constant

<relative_op> → < | <= | > | >= | = | /=

<arithmetic_expression> → <operand> | <operand> <arithmetic_op> <operand>

<arithmetic_op> → + | - | * | / 

【问题讨论】:

    标签: java grammar interpreter antlrworks


    【解决方案1】:

    从语法创建解释器时,ANTLR 是否可行。

    没有。

    ANTLRWorks 只能用于编写您的语法并可能测试它是否正确输入(通过其调试器或解释器)。它不能用于为您为其编写语法的语言创建解释器。 ANTLRWorks 只是一个花哨的文本编辑器,仅此而已。

    你们都看到我的代码中有任何错误吗?

    正如 Treebranch 所指出的:您在 = 登录时没有引号:

    assignment_statement:   ID = arithmetic_expression;
    

    让 ANTLR “认为”你想将标签 ID 分配给解析器规则 arithmetic_expression,这是非法的:你不能有一个标签名称也是规则的名称 (ID ,在你的情况下)。

    【讨论】:

      【解决方案2】:

      您的代码中可能存在的一些问题:

      我想你希望你的 ID 标签有一个 + 正则表达式,这样它的长度就可以是 1 或更多,就像这样:

      ID  :   ('a'..'z'|'A'..'Z'|'_')+
      ;
      

      您的= 符号周围似乎也缺少引号:

      assignment_statement:   ID '=' arithmetic_expression;
      

      编辑

      关于左递归问题:ANTLR 非常强大,因为它具有正则表达式功能。虽然 EBNF(就像您介绍的那样)可能在表达事物的方式上受到限制,但 ANTLR 可用于以更简单的方式表达某些语法规则。例如,如果您想在您的复合语句中有一个 statement_list,只需使用带有闭包的 statement 规则 (*)。像这样:

      compound_statement: 'begin' statement* 'end';
      

      突然间,您可以删除不必要的规则,例如 statement_list。

      【讨论】:

      • 谢谢我修复了这些,现在弹出了哈哈。 TODO:运行并将输出发送到此控制台 [12:26:51] 错误(211):T.g:6:15: [fatal] rule statement_list 由于递归规则调用可从 alts 访问而具有非 LL() 决定1,2。通过左分解或使用句法谓词或使用 backtrack=true 选项来解决。 [12:26:51] 错误(211):X:\Users\Zahc\Documents\T.g:6:15: [fatal] rule statement_list 有非 LL() 决定,因为递归规则调用可从替代 1,2。通过左分解或使用语法谓词或使用 backtrack=true 选项来解决。
      • 除此之外,我的代码似乎还不错?抱歉,我只是新手。
      • 我没有深入研究你的代码,我只是想提出一些改进它的方法,并让你了解 ANTLR 的表现力。
      • 如果你有机会,你能做到吗?而且这段代码会在java中创建一个解释器对吗?
      • 我建议您做的是获取 ANTLR eclipse 插件并将您的代码带到那里,编写一堆测试用例供您的语法分析,然后运行它们以查看哪些部分的语法按预期工作,哪些没有。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多