2013-02-04 131 views
0

我devloping我自己的编译器,我有错误恢复设计 在java语法的恐慌模式的问题。野牛C++多重错误恢复与丢失的分号

我想到了多种解决方案,但真正的问题:

我怎么能做到这一点与野牛C++?

我这样做:

包2

进口的java.lang。*;

误差必须消耗到第一半结肠和这与规则运行正确

package_rule:包错误“;”

但如果我写这个代码:

封装2

进口的java.lang *

等级Y {无效方法(){INT米}

}

我需要从解析器中像标准编译器那样报告错误:

标识符预计在包行。 失踪';'在导入指令行报告一个包。 mssing';'在整数m行。

我的意思是我需要包后错误消耗令牌,直到第一个分号或停止时,在最后一行befere声明他们找到类或接口声明!并报告线后发现的任何其他错误:

int m //缺少';'

请帮助我,在我脑海中有多种解决方案,但是如何用bison C++为java语法实现?

感谢名单了很多..

回答

0

你不会介意来解决这个问题在C++面向对象的方式,而不是在野牛的方式,你会吗?

考虑您有这些类型的定义

struct BaseExpression { 
    virtual std::string toIdentifier() = 0; 
    // other member. remember to declare a virtual destructor 
}; 

struct IntLiteral : BaseExpression { 
    std::string toIdentifier() { 
     error::toAnIdentifier(); 
     return ""; 
    } 
}; 

struct Identifier: BaseExpression { 
    std::string ident; 

    explicit Identifier(std::string id) : ident(id) {} 

    std::string toIdentifer() { 
     return ident; 
    } 
}; 

AST节点的定义是这样

%union { 
    BaseExpression* expr_type; 
} 

%type <expr_type> simple_expr 

package_expr: simple_expr 
{ 
    $1->toIdentifer(); // thus integers or float numbers would generate errors 
    // do sth with that identifer 
} 
; 

package_expr: package_rule '.' simple_expr 
{ 
    $3->toIdentifer(); // same trick 
    // do sth with that identifer 
} 
; 

的规则,其中simple_expr

simple_expr: int_literal { return new IntLiteral; } 
      | ... 
      | identifier { return new Identifier(yytext); } 
; 
1

好了,你的基本的问题是如何做您希望它尝试从语法错误中恢复。当你有一个像

package x import 

输入序列做你想让它假定有应该是一个分号那里,或者你希望它承担别的东西卡住了分号之前,它应该扔东西距离,直到它得到分号?

后者是你有什么 - 规则package: PACKAGE error ';'不正是 - 每当它看到关键字PACKAGE之后却什么来的package规则的其余部分不匹配,应该扔掉输入,直到它看到一个​​3210并尝试从那里继续。

如果你想前,你可以使用一个类似的规则package: PACKAGE name error - 如果看到PACKAGE的东西,看起来像一个有效的软件包名称,但没有分号,把它当作如果有一个分号那里,并尝试继续。

使它能够做到上述事情是非常困难的。最接近的将是具有语法看起来像:

package: PACKAGE name ';' /* normal package decl */ 
     | PACKAGE name  /* missing semicolon -- treat this as a semantic error */ 
     | PACKAGE error ';' /* no name -- skip up to the next semicolon to recover */ 

然而,这样的事情可能给你语法是很难解决冲突。

+0

thanx为你的答案,我解释我的问题犯了一点错误。 pakcage 2 //这里错误在id和缺少';' 什么我需要设计专业编译器的Java语言, 匹配标准的。 所以你的suggession克里斯多德是goOd,我写了它,但这要么 发现错误在ID或';'但不是他们两个! 我需要的东西或者消耗错误到下一个';'在导入时使用规则PACKAGEG 错误';',或者如果在声明类,接口或EOF之前没有发现停在最后一行。 我需要真正的高级解决方案,在java标准中得到相同的结果,我在等待你的建议。 – lady

+0

那么,你可以改为使用规则'package:PACKAGE error',甚至'declaration:error',从语法错误恢复到最高级别,而不会丢弃任何令牌。它可能会给你一个错误级联,但是(由于不完全恢复造成很多“错误”错误) –

+0

package:PACKAGE错误。在这种情况下,错误标记只包含PACKAGE标记后的第一个字,然后停止,这不是我的目标!我想要错误标记在类或接口之前消耗所有的标记,如果找到..然后发现类或接口内的错误,清除??在这个解决方案中,当写入规则时:> package:PACKAGE error |时出现其他问题包错误';' |那么第二条规则就不会被使用!真正的问题:( – lady