【问题标题】:C++ scanner (string-fu!)C++ 扫描器 (string-fu!)
【发布时间】:2010-10-04 06:34:32
【问题描述】:

我正在编写一个扫描仪作为编译器的一部分。

我在写这一部分时头疼:

我需要能够解析标记流并将它们一个一个地推入向量中,忽略空格并标记特殊符号(简单的情况,让我们只考虑括号和大括号)

示例: int main(){ }

应该解析成6个不同的token:

  1. int
  2. 主要
  3. (
  4. )
  5. {
  6. }

你会如何解决这个问题?我是用 C++ 编写的,但也欢迎使用 java/C# 解决方案。

几点:

  1. 不,我不能使用 Boost,我不能保证这些库会 可供我使用。 (别问……)

  2. 我不想使用 lex 或任何其他特殊工具。我从来没有做过 这个之前,只是想尝试一次,说我已经做到了。

【问题讨论】:

    标签: c# java c++ string


    【解决方案1】:

    购买一本Compilers: Principles, Techniques, and Tools(龙之书)。您尝试编写的是词法分析器,而不是“扫描仪”。

    【讨论】:

    • 这是一本非常深入的书,仅用于学习如何对字符串进行词法分析。
    • 公平地说,这是一本很棒的书。尽管比此任务所需的更深入...
    • 他说他正在编写它作为编译器的一部分。我想他可能想知道编译器的其余部分通常是如何工作的。
    【解决方案2】:

    Stroustrup 的书,C++ 编程语言,其中有一个很好的例子,关于为一个简单的计算器程序构建一个词法分析器/解析器。它应该作为一个很好的起点来学习如何做你想做的事。

    【讨论】:

      【解决方案3】:

      为什么要自己编写 - 看看 Lex。

      如果您必须拥有自己的,您只需逐个字符读取输入并保持一些最小状态以累积标识符。

      问题本身并不难。如果解决不了,肯定是筋疲力尽了,只需要休息一下。早上再看一遍。

      【讨论】:

      • "问题本身并不难。" ::shrugs:: 人们第一次看到这个问题时会做愚蠢的事情并不少见。 '当然,我发现做错几次很有启发性,而且这是一个足够小的问题,很快就会发生......
      • dmckee,如果我可以投票给你,我会的。我有点厌倦这些“哦,那是一个小问题”类型的反应......
      • @eviljack:不要对 Arkadiy 太苛刻,词法分析真的很难。有一些可以相当容易地发现的有效解决方案。但与我交谈过的大多数人都不得不先尝试几种错误的方法。
      • 天啊!猜猜我真的是睡眠不足。
      • 如果@eviljack 正在编写一个编译器,那么词法分析对他来说真的不难。我猜他只是脑子有问题。
      【解决方案4】:

      umm .. 我只是做一个 while 循环,迭代器测试每个字符的类型,只有 alpha 到非 alpha 的变化,如果字符串非空,则转储字符串。如果它是非 alpha 非空白字符,我只需将其推送到令牌堆栈上,这确实是一个微不足道的解析任务。射击,我一直想学习 lexx/yacc,但是您想要的解析级别真的很容易。我曾经写过一个 html 标记器,它比这更复杂。我的意思是你只是在寻找名称、空格和单个非字母数字字符。就这样做吧。

      【讨论】:

        【解决方案5】:

        如果你真的想从这个练习中学到一些东西,那就开始编码吧。它不需要大量代码,因此您可以反复失败而不会超过一个下午。

        此时,您将对问题有一个很好的认识。

        然后查看任何随机编译器书籍,看看“通常”的方法是什么,然后你就会立即了解。

        【讨论】:

          【解决方案6】:

          如果您想从头开始编写此代码,您可以考虑编写一个有限状态机(枚举中的状态,用于状态切换的大型 switch/case 块)。您必须将状态推送到堆栈,因为所有内容都可以嵌套。

          我知道这不是理想的方法;我只是想直接解决这个问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-10
            相关资源
            最近更新 更多