在学校,我们被分配设计一种语言,然后实施它,(我实现它很有趣=))。我的老师告诉我们使用yacc / lex,但我决定使用java + regex 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
然后有类似VariableAssignment
,IfSentence
等子类,并且有一个类{{1这只是一堆句子对吗?然后在所有Program
上调用抽象方法eval
,因此我对语言进行编译的初始方法仅包括两个阶段:
当然,如果任何阶段出现问题,Ii可能会引发错误。
我的问题是,我做错了吗?我应该像理论一样(词汇,句法,语义)来讨论所有阶段吗?我应该继续使用我的天真的两阶段编译器吗?
答案 0 :(得分:5)
许多聪明人都在想这个问题,从我的帖子中,他们得出的结论是,所有阶段都是必需的。
因此,如果您希望编译器工作,请按理论规定的方式进行。
如果你想了解,为什么它决定了阶段,试试捷径。这可能需要更长的时间。
免责声明:我不了解编译器理论
另一个注意事项:你有问题;你决定用regexp来解决它;现在你有两个问题
答案 1 :(得分:5)
我不会问一个明显的问题,即为什么你不遵循导师的建议并使用yacc / lex,因为我知道答案。你想去做一些你认为很酷的事情并且会帮助你学习。不幸的是,这种方法是由你的教授推荐的,因为正如另一篇文章所述,在你探索多种方法并花费大量时间试图找到一个好的解决方案之前,很多非常聪明的人。
您可以使两阶段编译器工作,但您需要接受它将永远不会像完成整个过程一样好,因为它更难以检测错误。实际上要困难得多。在某些情况下,你甚至不能告诉它有错误,直到为时已晚。即:已经编译并试图运行。
如果你想要了解更多关于它的知识,那么请选择两阶段方法,你会遇到与之前遇到的人相同的问题。请务必明白,要获得最终解决方案需要花费更长的时间,您可能会在项目中停靠点,而且可能无法正常工作。
那就是说,你会比班上的其他人更多地了解它。如果你有空的时间,我会按你现在的方式做。这些知识可能会派上用场。我也会和你的教授谈谈,并告诉他你将采取另一种方式反对他的建议,因为你想要有更透彻的理解。也许他不会因为雄心勃勃而从你的项目中剔除分数,即使事实证明是错误的。
毕竟,在大学里做项目的目的是学习。
答案 2 :(得分:1)
如果您使用正则表达式解析每行,您的语言语法将非常有限。
如果语法变得更复杂,您将无法仅使用正则表达式API解析每一行。如果您开始添加 AND 和 OR 运算符,即使if { equals("guy1" to yourName) }
也无法使用正则表进行解析,如果您开始支持{{}等转义字符,会发生什么情况1}}在你的字符串文字中?
Java Regex API将能够帮助您使用词法分析器,但您必须从那里编写解析器。您可以采取以下几种方法之一:
等等
(另外,“Statement”是编译器文本中更常见的“Sentence”的同义词)
答案 3 :(得分:1)
如果您只想使用正则表达式来解析您的语言,那么您的语言只能是常规语言。这是一个很大的限制,例如,任意深度嵌套是不可能的,因为你必须分别教你的解析器每个嵌套组合。我不确定是否可以构建图灵完整的常规语言。
答案 4 :(得分:0)
如果你真的想弄脏你的手代码一个递归下降解析器。如果您想了解编译器理论,请使用antlr并专注于离开解析器生成器实现的原则。 顺便说一句,为什么要用正则表达式让你的生活变得复杂?!