【问题标题】:Syntax analysis question语法分析题
【发布时间】:2009-11-11 15:36:05
【问题描述】:

在学校,我们被指派设计一种语言,然后实施它,(我在实施它时获得了很多乐趣 =))。我的老师告诉我们使用 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,然后拥有像 VariableAssignmentIfSentence 等子类,并拥有一个类 Program,它只是一堆句子对吗?然后在所有Sentences 上调用一个抽象方法eval,所以我最初编译该语言的方法只包括两个阶段:

  1. 识别每行的语法
  2. 为每一行创建对应的类

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

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

【问题讨论】:

  • 大错特错。您应该学习解析,而不是使用正则表达式。您应该改用 Java 解析系统,例如 Jack,或者更好的是,使用 BYACC/J byaccj.sourceforge.net,这样您就可以与课程更加同步。

标签: java code-analysis compiler-theory


【解决方案1】:

我不会问你为什么不听从导师的建议并使用 yacc/lex 的明显问题,因为我知道答案。你想出去做一些你认为很酷并且可以帮助你学习的事情。不幸的是,您的教授推荐了这种方法,因为正如另一篇帖子所说,在您探索多种方法并花费大量时间试图找到一个好的解决方案之前,有很多非常聪明的人。

您可以使两阶段编译器工作,但您需要接受它永远不会像完成整个过程那样好,因为它更难检测错误。事实上要难得多。在某些情况下,您甚至无法判断存在错误,直到为时已晚。即:已经编译并正在尝试运行。

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

也就是说,您将比班上其他任何人了解更多有关它的信息。如果你有时间,我会按照你现在的方式来做。这些知识将来可能会派上用场。我也会和你的教授谈谈,告诉他你会用另一种方式来反对他的建议,因为你想有一个更彻底的理解。也许他不会因为你的雄心勃勃而从你的项目中扣分,即使结果是错误的。

毕竟,在大学里做项目的目的是为了学习。

【讨论】:

    【解决方案2】:

    很多聪明人都考虑过这一点,从我收到的你的帖子中,他们得出的结论是所有阶段都是必要的。

    因此,如果您希望编译器正常工作,请按照理论规定的方式进行操作。

    如果您想了解它为何决定阶段,请尝试捷径。这可能需要更长的时间。


    免责声明:我对编译器理论一无所知


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

    【讨论】:

    • @Jens Schauder,“现在你有两个问题”引用 +1。
    【解决方案3】:

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

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

    Java Regex API 可以帮助您使用词法分析器,但您必须从那里编写解析器。您可以采取以下几种方法之一:

    • 如果您使用 Java,您可以查看 Antlr(无需使用 Java 的正则表达式库编写词法分析器),或者
    • 您可以手动编写递归下降解析器

    其中

    (另外,“Statement”是“Sentence”的同义词,在编译器文本中更常见)

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-29
          • 2011-12-16
          • 1970-01-01
          • 1970-01-01
          • 2022-01-02
          • 2013-08-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多