【问题标题】:programming a "compiler" - any way of knowing if a { (opener) was } (closed)? [closed]编写“编译器” - 任何方式知道 {(开启者)是否 }(关闭)? [关闭]
【发布时间】:2013-05-26 15:46:55
【问题描述】:

好的,所以,我有一个练习来构建一种 java 编译器。细节我就不多说了。 基本上,我想知道是否可以使用可以识别右括号的正则表达式。 例如,这将是一个合法的输入

void foo(){
   asd
}

这不会是

void foo(){
   asd
   if (){
      asd
   }

如您所见,对于 2 个开启者 ({),只有 1 个关闭器 (}),因此输入无效。有什么方法可以使用正则表达式并确定出现次数是否匹配?

【问题讨论】:

  • 了解分词器。正则表达式不用作编译器的主要实现工具是有原因的。正则表达式可能被用作标记化/编译的一部分,但有些语言情况无法由正则表达式处理。
  • 传统上这是通过堆栈完成的。
  • 标准正则表达式不能用于此目的(假设您要处理任意级别的嵌套)。
  • 是否允许使用 ANTLR、JavaCC 或 VisualLangLab 等专用工具?
  • 以上所有都不是,只是标准的 java 1.7 类。它不应该是一个真正的编译器......我知道如何使用堆栈或级别计数器来计算数字,我只是想知道是否可以使用正则表达式来识别它。感谢您的帮助。

标签: java regex compiler-theory language-theory


【解决方案1】:

无法使用正则表达式检查括号是否正确,因为要检查是否需要跟踪已打开的括号数量等,但正则表达式无法做到这一点。

我建议你,特别是如果你想构建一个编译器,熟悉形式语言理论。例如,这篇维基百科文章对形式语言理论上下文中的正则表达式提供了一些见解:http://en.wikipedia.org/wiki/Regular_expression#Formal_language_theory

【讨论】:

    【解决方案2】:

    最简单(简化?)答案:

    如果您解析语法,通常会维护某种堆栈(直接或间接)。 对于每个左括号,您将一个元素压入堆栈。看到右括号后,您可以通过检查堆栈知道它是否与最后一个左括号匹配。

    另请注意,打开括号的方法有很多种,“{”只是其中一种。 因此堆栈不仅会告诉您有多少个左括号,还会告诉您在给定的解析状态下哪种类型的右括号是合法的。

    【讨论】:

      【解决方案3】:

      标准正则表达式只能表达regular languages 的语法,这正是deterministic finite automata 接受的语言类别。 DFA只有有限个状态,而括号可以无限嵌套;可能具有无限嵌套级别的语言不是正则语言,不能仅通过正则表达式进行解析。

      虽然大多数语言中的正则表达式库不仅仅是“标准”正则表达式并且能够解析一些非正则语言,但它们通常需要过于复杂的表达式才能做到这一点。

      通常,要检查括号语言的格式良好的嵌套,您将需要一个context-free grammar (CFG) 解析器。 CFG 比正则表达式严格更强(即如果一个语法可以用 RE 表达,那么它就可以用 CFG 表达,反之则不一定)。

      【讨论】:

        【解决方案4】:

        如果你使用 C,好的工具是用于 Tokens 的 Flex 和用于语法的 Bison

        JFlex 和 Cup,如果你想用 Java 来做,也可以使用 Visitor paddern 以获得更好的程序结构

        【讨论】:

          猜你喜欢
          • 2010-09-05
          • 2011-05-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-27
          • 2016-07-30
          • 1970-01-01
          相关资源
          最近更新 更多