thrift的编译器2

原创 2012年03月24日 11:07:06

    main函数中调用了两个非常重要的函数,parse()和generate(),parse()解析thrift文件,生产语法树,即全局变量g_program。generate()通过这棵语法树,生产具体的语言代码。具体看看这两个函数。thrift的词法解析和语法解析用了flex和bison。

void parse(t_program* program, t_program* parent_program) {
  // Get scope file path 获取thrift文件的路径
  string path = program->get_path();

  // Set current dir global, which is used in the include_file function
  g_curdir = directory_name(path);
  g_curpath = path;

  // Open the file
  yyin = fopen(path.c_str(), "r");
  if (yyin == 0) {
    failure("Could not open input file: \"%s\"", path.c_str());
  }

  // Create new scope and scan for includes
  // 进行第一次yyparse,找出所有的include文件。
  pverbose("Scanning %s for includes\n", path.c_str());
  g_parse_mode = INCLUDES;
  g_program = program;
  g_scope = program->scope();
  try {
    yylineno = 1;
    if (yyparse() != 0) {
      failure("Parser error during include pass.");
    }
  } catch (string x) {
    failure(x.c_str());
  }
  fclose(yyin);

  // Recursively parse all the include programs
  vector<t_program*>& includes = program->get_includes();
  vector<t_program*>::iterator iter;
  for (iter = includes.begin(); iter != includes.end(); ++iter) {
    parse(*iter, program);
  }

  // Parse the program file
  // 第二次yyparse,生成语法树
  g_parse_mode = PROGRAM;
  g_program = program;
  g_scope = program->scope();
  g_parent_scope = (parent_program != NULL) ? parent_program->scope() : NULL;
  g_parent_prefix = program->get_name() + ".";
  g_curpath = path;
  yyin = fopen(path.c_str(), "r");
  if (yyin == 0) {
    failure("Could not open input file: \"%s\"", path.c_str());
  }
  pverbose("Parsing %s for types\n", path.c_str());
  yylineno = 1;
  try {
    if (yyparse() != 0) {
      failure("Parser error during types pass.");
    }
  } catch (string x) {
    failure(x.c_str());
  }
  fclose(yyin);
}



void generate(t_program* program, const vector<string>& generator_strings) {
  // Oooohh, recursive code generation, hot!!
  // 是否递归的生成include文件的代码
  if (gen_recurse) {
    const vector<t_program*>& includes = program->get_includes();
    for (size_t i = 0; i < includes.size(); ++i) {
      // Propogate output path from parent to child programs
      includes[i]->set_out_path(program->get_out_path(), program->is_out_path_absolute());

      generate(includes[i], generator_strings);
    }
  }

  // Generate code!
  try {
    pverbose("Program: %s\n", program->get_path().c_str());

    // Compute fingerprints.
    generate_all_fingerprints(program);

    if (dump_docs) {
      dump_docstrings(program);
    }

    //  循环生成不同语言的代码
    vector<string>::const_iterator iter;
    for (iter = generator_strings.begin(); iter != generator_strings.end(); ++iter) {
      t_generator* generator = t_generator_registry::get_generator(program, *iter);

      if (generator == NULL) {
        pwarning(1, "Unable to get a generator for \"%s\".\n", iter->c_str());
      } else {
        pverbose("Generating \"%s\"\n", iter->c_str());
        generator->generate_program();  // 不同语言实现不同的函数。
        delete generator;
      }
    }

  } catch (string s) {
    printf("Error: %s\n", s.c_str());
  } catch (const char* exc) {
    printf("Error: %s\n", exc);
  }

}




                    

Thrift之代码生成器Compiler原理及源码详细解析1

我的新浪微博:http://weibo.com/freshairbrucewoo。 欢迎大家相互交流,共同提高技术。 又很久没有写博客了,最近忙着研究GlusterFS,本来周末打算写几篇...
  • wanweiaiaqiang
  • wanweiaiaqiang
  • 2012年04月23日 23:45
  • 9979

Python编译器实现内幕:添加一个新语句

Python编译器实现内幕:添加一个新语句本文尝试理解Python前端的编译实现内幕,如果仅仅是读取文档,或者查看Python的实现代码,会让人感觉迷迷糊糊的,所以我的想法是动手来做一些事情:添加一个...
  • caimouse
  • caimouse
  • 2015年08月06日 08:28
  • 2473

自制脚本语言(5) 自制的编译器——LR(1) parser

摘要:针对自定义的脚本语言,设计LR(1) parser。LR(1) parser利用之前的parser generator生成的action table和grammar表格,生成抽象语法树(AST)...
  • nklofy
  • nklofy
  • 2015年12月22日 10:41
  • 1151

vs2010编译thrift之compiler出错的处理方法

问题描述 在使用visual studio 2010 SP1编译thrift-0.9.1的compiler时,出现: The command "flex -o "src\\thriftl.cc" sr...
  • cool_way
  • cool_way
  • 2014年12月04日 20:11
  • 2542

Thrift0.8.0安装常见问题

项目要求thrift的版本为0.8.0,这是一个老版本,所以我们不能使用包管理器(例如brew)来进行安装了。 我们必须采用源码安装。 源码安装需要配置、编译、链接的过程,会有一些依赖条件,所以在...
  • yums467
  • yums467
  • 2016年06月30日 22:48
  • 931

[心得]Mac下编译thrift踩坑总结

thrift 0.8.0安装8的时候会遇到如下问题,并按如下解决:Osx 10.10 是比较新的系统, 从这个版本开始, 系统默认编译器从GCC 改为 Clang(gcc -v 一下, 给的是clan...
  • cmrsautomation
  • cmrsautomation
  • 2016年11月17日 19:48
  • 313

kafka源码分析之一server启动分析

0. 关键概念 关键概念 Concepts Function Topic 用于划分Message的逻辑概念,一个Topic可以分布在多个Broker上...
  • xgjianstart
  • xgjianstart
  • 2017年04月13日 20:53
  • 395

C++ thrift详细教程 及和Protobuf对比

最近同时用了thrift和protobuf,进行通信传输。之前已写过关于protobuf的一篇博文,具体请点击:http://blog.csdn.net/zsk4232000/article/deta...
  • zsk4232000
  • zsk4232000
  • 2015年12月18日 18:58
  • 2636

【Apache Thrift】Thrift的使用和编译(二)

一、Thrift的使用   1.1基本类型  thrift不支持无符号类型,因为很多编程语言不存在无符号类型,比如javabyte: 有符号字节i16: 16位有符号整数i32: 32位有符号整数i6...
  • liulongling
  • liulongling
  • 2016年07月12日 20:07
  • 5235

git 常用命令总结和git服务器代码仓库创建

进来一段时间一直在忙碌,很少回头总结学过,用过的知识,由于缺少总结导致下次在遇到的时候总是记忆很模糊,有种似曾相识但却无能为力的感觉。特在此加以总结形成博客 创建git 仓库: git confi...
  • liuhaomatou
  • liuhaomatou
  • 2015年07月16日 21:02
  • 4700
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:thrift的编译器2
举报原因:
原因补充:

(最多只允许输入30个字)