2009-11-11 60 views
1

在学校里,我们被分配去设计一门语言,然后实施它(我有很多乐趣实现它=))。我的老师告诉我们使用YACC /法,但我决定去与Java +正则表达式API,这里是语言我如何设计外观:语法分析问题

Program "my program" 
var yourName = read() 
if { equals("guy1" to yourName) } 
    print("hello my friend") 
else 
print("hello extranger") 
end 
Program End 

好吧,你可以看到,它的一个非常基本的语言=)。

我以为我能实现它在一个非常OOP的时尚,就像让一个抽象类Sentence,然后让子类像VariableAssignmentIfSentence等,并有一个类Program这仅仅是一串句子正确的?然后调用一个抽象方法eval所有Sentence S,所以我最初的做法complie语言仅包括两个阶段:

  1. 确定SEACH行的语法
  2. 每行
创建correspondig类

当然,如果在任何阶段出现问题,Ii都可能引发错误。

我的问题是,我做错了吗?我是否应该像理论说的那样遍历所有阶段(词汇,语法,语义)?我应该继续使用我的天真的两阶段编译器吗?

+7

大错误。你应该学习解析,而不是用正则表达式来解决问题。您应该切换到使用Java解析系统(如Jack),或者更好的方法是使用BYACC/J http://byaccj.sourceforge.net/,以便您更好地与类同步。 – 2009-11-11 15:56:38

回答

5

我不会问一个显而易见的问题,你为什么不遵循教师的建议和使用yacc/lex,因为我知道答案。你想离开,做一些你认为很酷的事情,并会帮助你学习。不幸的是,这种方法是由你的教授推荐的,因为正如另一篇文章所述,很多非常聪明的人在探索多种方法之前花费大量时间试图找到一个好的解决方案。

您可以使两阶段编译器工作,但您需要接受它不会像完整过程那样好,因为它很难检测到错误。其实很难。在某些情况下,您甚至不能在出现错误之前就知道有错误。即:已编译并尝试运行。

如果您想了解更多关于它的信息,请使用两阶段方法,您会碰到与之前遇到的人相同的问题。请务必明白,要达到最终解决方案需要更长的时间,您可能会将项目停靠点,并且可能无法正常工作。

也就是说,你会比班上其他人更多地了解它。如果你有时间空余,我会按照你现在的样子去做。知识可能会派上用场。我还会和你的教授谈谈,并告诉他你会以另一种方式违背他的建议,因为你希望有一个更透彻的理解。也许他不会因为雄心勃勃而从你的项目中脱颖而出,即使结果不对。

毕竟,在大学里做项目的重点是学习。

5

很多聪明的人都想到了这个问题,并且从我发表的文章中,他们得出了所有阶段都需要的结论。

所以,如果你想要你的编译器工作,按照理论的方式。

如果你想了解,为什么它决定阶段,试试捷径。它可能会花更长的时间。


免责声明:我不知道编译原理想法


另注:你有问题;你决定使用正则表达式来解决它;现在你有两个问题

+0

@Jens Schauder,+1为“现在你有两个问题”引用。 – 2009-11-11 16:16:03

1

如果您使用正则表达式解析每行,您的语言将具有非常有限的语法。

如果语法变得更复杂,那么您将无法仅使用正则表达式API解析每一行。如果您开始添加运算符,那么即使if { equals("guy1" to yourName) }也无法用正则表达式解析,如果您在字符串文字中开始支持转义字符如\n会发生什么情况?

Java Regex API将能够帮助您使用词法分析器,但您必须从那里编写解析器。如果您使用的是Java

  • ,你可以看看Antlr(这否定了需要写一个lexicall分析仪与Java的正则表达式库),或
  • 你可以写一个:你可以采取几种方法之一手工递归下降解析器

(也,“声明”是“句”这是比较常见的编译器文本的同义词)

0

如果你真的想肮脏你的手代码一个递归下降解析器。如果您想了解编译器理论,请使用antlr,并专注于为解析器生成器留下实现的原则。顺便说一句,为什么会用正则表达式使你的生活复杂化?!

1

如果您只想使用正则表达式来分析您的语言,那么您的语言只能是常规语言。这是一个很大的限制,例如,任意深度的嵌套将是不可能的,因为您将不得不分别教您的解析器每个嵌套组合。我不确定是否可以构建一个完整的图灵语言。