使用C ++,AST进行Bison/Flex教程,并重新使用词法分析器和分析器

I am learning parsing, bison & lex. I am looking for a clear & complete tutorial/example that demonstrates all of:

  1. C ++(不是C)抽象语法树。
  2. 重新进入词法分析器。
  3. 重入解析器。
  4. 从字符串读取(从文件中读取)也很好。

我找到了多个示例和教程,但每个示例和教程通常只能满足上述几个要求。到目前为止,我最好的教程来自John Levine的Oreilly书中的第3-2章 - 它有AST;所有C虽然,只会遇到Re_1以上。我欢迎有关好的示例/教程,现实生活中的开源项目的建议。例如,我看到MySql .yy文件 - 看起来写得很好,但对于像我这样的初学者来说太大/复杂了。

0
额外 编辑
意见: 1
你的意思是用C ++编码?或者你想解析C ++?
额外 作者 Ira Baxter,
我希望与flex/bison交互的代码是C ++。特别是AST(抽象语法树)。提到的例子取决于c型宽大。另外,我想使用STL等等。至于我想解析的内容:一个类似于正则表达式的简单语法。
额外 作者 Radim Cernej,

2 答案

In the end I combined several examples to get what I wanted. The top two examples were from John Levine's book on bison&flex (2nd edition), ISBN-10: 0596155972. The other one was from a phpcompiler website which unfortunaltly as of 2017-02-28 no longer exists. I am leaving the link here, in case the site is archived somewhere: www.phpcompiler.org/articles/reentrantparser.html

谢谢阿德里安,这里是一个存档版本(作品截至2017-03-02):

http://web.archive。组织/网络/ 20120520150851/HTTP://www.phpcompiler.org/articles/reentrantparser.html

0
额外
事实上phpcompiler.org网站已经不存在了,谢谢你通知我。我已经编辑了我的2012年答案。
额外 作者 Radim Cernej,
对不起,杰克,我将无法上传代码或以其他方式帮助。我们正在谈论2012年(几乎5年前),IP由我的雇主Fluential Inc/LLC拥有(我不知道他们是否还在营业)。从那时起,我一直没有解析,我不记得很多:(。
额外 作者 Radim Cernej,
是的,据我所知,这似乎是同一篇文章。
额外 作者 Radim Cernej,
该链接似乎已经死亡。
额外 作者 Adrien,
该网址已上传至档案。 org 几次。网站最近的截图是2017/05/20,是你打算在你的答案中展示的正确版本吗?
额外 作者 Adrien,
嗨Radim,我碰巧需要编写一个(不是那么简单)的编译器。你可以上传你组装到Github之类的例子吗?人们可能会发现它很有用,因为现有的例子并不容易。只是想知道,谢谢。
额外 作者 jack,

首先我想说的是C ++语法对于Lex/Bison来说太复杂了。这里的问题主要是在语法冲突中。编写没有它们的C ++语法是不可能的。 C ++标准明确规定了这一点,并包含一些关于如何解决它们的指导原则。

解决语法冲突没有通用的解决方案。特别是C ++的语法冲突解决方案需要详细了解已定义的标识符。这意味着你需要拥有更大部分的C ++前端。只有语法是不够的。

尽管如此,建立AST是可能的。看一个小样本程序。

class HashEntry
{
private:

      int key;
      int value;

public:

      HashEntry(int key, int value)
      {
            this->key = key;
            this->value = value;
      }

      int getKey() { return key; }

      int getValue() { return value; }
};

const int TABLE_SIZE = 128;

class HashMap
{
private:

      HashEntry **table;

public:

      HashMap()
      {
            table = new HashEntry*[TABLE_SIZE];

            for (int i = 0; i < TABLE_SIZE; i++)
                  table[i] = NULL;
      }

      int get(int key)
      {
            int hash = (key % TABLE_SIZE);

            while (table[hash] != NULL && table[hash]->getKey() != key)
                  hash = (hash + 1) % TABLE_SIZE;

            if (table[hash] == NULL)
                  return -1;
            else
                  return table[hash]->getValue();
      }

      void put(int key, int value)
      {
            int hash = (key % TABLE_SIZE);

            while (table[hash] != NULL && table[hash]->getKey() != key)
                  hash = (hash + 1) % TABLE_SIZE;

            if (table[hash] != NULL)
                  delete table[hash];

            table[hash] = new HashEntry(key, value);
      }     

      ~HashMap()
      {
            for (int i = 0; i < TABLE_SIZE; i++)
                  if (table[i] != NULL)
                        delete table[i];

            delete[] table;
      }
};

And this is an AST for this program: enter image description here

这棵树严重缩小。叶子上的黄色圆圈(非常小)是终端符号,中间的绿色圆圈是非终端符号。中心的粉红色圆圈就是TranslationUnit。这棵树有2009个节点。

0
额外
您好基里尔,正如我在另一个评论中指出的,我不是想解析c ++,我只是想在c ++项目中使用bison/flex。我现在有一个解决方案,我会试着去解决这个问题。
额外 作者 Radim Cernej,