首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Bison/Flex教程,包括C++、AST和可重入的词法和解析器

Bison/Flex教程,包括C++、AST和可重入的词法和解析器
EN

Stack Overflow用户
提问于 2012-05-24 07:22:26
回答 2查看 6.1K关注 0票数 4

我在学解析,野牛和莱克斯。我正在寻找一个清晰完整的教程/示例,它演示了以下所有内容:

来自字符串的抽象语法Tree.

  • Re-entrant lexer.

  • Re-entrant parser.

  • Reading (与来自文件的抽象语法)
  1. C++ (非C)也很好。

我已经找到了多个示例和教程,但每个示例和教程通常只满足上述几个需求。到目前为止,我最好的教程是John在Oreilly书中的第3-2章-它有AST;不过,所有的C都只满足上面的Re_1。我欢迎推荐一些很好的例子/教程、现实生活中的开源项目。例如,我看到了MySql .yy文件--写得很好,但对于像我这样的初学者来说太大/太复杂了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-14 00:30:27

最后,我结合了几个例子来得到我想要的东西。前两个例子来自约翰莱文的书野牛和挠曲(第二版),ISBN-10: 0596155972。另一个是来自php编译器的网站,不幸的是,在2017-02-28年间,该网站已经不复存在。我把链接放在这里,以防网站被归档: www.phpcompiler.org/articles/reentrantparser.html

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

http://web.archive.org/web/20120520150851/http://www.phpcompiler.org/articles/reentrantparser.html

票数 4
EN

Stack Overflow用户

发布于 2012-06-14 00:03:05

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

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

然而,建立AST是可能的。看看一个小的示例程序。

代码语言:javascript
运行
复制
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;
      }
};

这是这个程序的AST:

这棵树被严重放大了。叶子上的黄色圆圈(很小)是终端符号,中间的绿色圆圈是非终端。中间的粉红色圆圈是TranslationUnit。这棵树有2009年节点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10732932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档