【问题标题】:Writing Compilers, Lexical Analysis?编写编译器,词法分析?
【发布时间】:2010-12-09 17:17:02
【问题描述】:

我对编写编译器完全陌生。所以我目前正在启动项目(用Java编码),在编码之前,我想更多地了解词法分析部分。我在网上研究过,我发现他们中的大多数都使用标记器。

该项目要求我不使用它们(标记器),而是使用有限状态自动机。我很困惑,我需要使用链表来实现它吗?或者一个简单的嵌套开关案例就可以了。我对实现有限自动机不是很熟悉,有什么好处?

【问题讨论】:

  • 编译器资源大列表是Learning to write a compiler。其中的各种理论书籍/站点/等将解释如何使用 FSA 构建词法分析器(或者您可以自己找出解决方案来直接完成任务)。在 Java 中实现 FSA 可能存在多个问题。
  • 查看一些词法分析器生成的代码可能会有所帮助。例如。 COCO/R for Java 生成可读性很强的代码。
  • @max taldykin,感谢指向 COCO/R 的指针,它看起来很有趣。对于 OP,源代码中的scanner.java 解析器格式本身的FSA扫描仪,因此可能会提供一些灵感。

标签: compiler-construction linked-list theory analysis lexical


【解决方案1】:

Russ Cox 的Regular Expression Matching Can Be Simple And Fast 很好地介绍了使用有限状态机构建识别器。他展示了如何从正则表达式到非确定性有限自动机再到确定性有限自动机。他的参考实现使用directed graph(类似于链表,但每个节点可以有多个“out”引用,并且可以引用包括自身在内的任何其他节点)而不是链表。还有其他建模状态机的方法,包括:

您通过组合多个识别器来构建词法分析器/扫描器。例如,想象一种仅赋值语言,具有以下由正则表达式定义的标记:

  • 标识符:[a-zA-Z]+
  • 分配:=
  • 号码:[0-9]+
  • 关键字:和

当您从左到右扫描输入时,根据当前符号移动每个令牌机器中的转换。当一个符号没有有效的转换时,选择最后一台处于接受状态的机器。在该状态之前扫描的所有符号都是令牌的一部分。在最后一个接受的符号之后的符号处再次开始扫描。如果新令牌没有有效的转换,则输入无效,词法分析器应报告错误。如果有不止一台机器处于接受状态,则优先规则应决定使用哪个令牌。

注意:这些步骤描述了一个总是返回最长匹配的词法分析器。您还可以设计一个词法分析器,它在其中一台机器处于接受状态时立即返回一个标记。

样本输入的结果:

  • a=10 : (标识符 a)(赋值 =)(数字 10)
  • a = 10:无效 - 我们的令牌定义中不接受空格
  • 25=xyz : (number 25)(assignment)(identifier xyz)
  • 25and42 : (number 25)(keyword and)(number 42) - 假设关键字优先于标识符
  • b=1+2:无效 - 我们的令牌定义不接受“+”
  • andx=8 : (identifier andx)(assignment)(number 8) - 最长匹配为我们提供 (identifier andx) 与 (keyword and)(identifier x)

请注意,词法分析只返回标记。它不知道令牌是否正确使用。 '25=xyz' 可能没有任何意义,但我们必须等到解析阶段才能确定。

作为附加资源,Dick Grune 提供了Parsing Techniques - A Practical Guide 的第一版作为 Postscript 和 Pdf。

【讨论】:

    【解决方案2】:

    鉴于对标记器的人为禁令,我认为这是一项分配。

    lexical analysis using finite state automata”有很多谷歌匹配项。这些缺少什么?

    您是否在了解如何使用有限状态自动机进行词法分析时遇到问题?还是自己写一个自动机?知道它们也被称为有限状态机(FSM)可能会有所帮助

    分词器很可能在其内部使用 FSM,所以我不明白您为什么说必须使用 FSM 而不是分词器 - 这是否意味着您不能使用已编写且必须编写的分词器自己一个?

    正则表达式匹配器的实现通常也是一个有限状态机,所以这可能是一个需要考虑的领域。

    lex(和它最近的关系flex)是词法分析器,其源代码可用。你可以看看那些想法

    【讨论】:

    • 其实 lex 和 flex 不是词法分析器,而是词法分析器生成器。因此,查看它们的来源可能会令人困惑:)
    • 是的。我应该更具体。此类工具的输出可能也值得检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 2012-01-15
    • 1970-01-01
    • 2010-12-21
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多