这一篇看看thrift是如何生成语法树的(词法语法解析用到flex和bison),以找到include文件为例。
Triftl.ll 文件(这是个flex文件)
135行
"include" { return tok_include; }
定义了include词法符号。
literal_begin (['\"]) // 这是个正则表达式匹配
{literal_begin} {
char mark = yytext[0];
std::string result;
for(;;)
{
int ch = yyinput();
switch (ch) {
case EOF:
yyerror("End of file while read string at %d\n", yylineno);
exit(1);
case '\n':
yyerror("End of line while read string at %d\n", yylineno - 1);
exit(1);
case '\\':
ch = yyinput();
switch (ch) {
case 'r':
result.push_back('\r');
continue;
case 'n':
result.push_back('\n');
continue;
case 't':
result.push_back('\t');
continue;
case '"':
result.push_back('"');
continue;
case '\'':
result.push_back('\'');
continue;
case '\\':
result.push_back('\\');
continue;
default:
yyerror("Bad escape character\n");
return -1;
}
break;
default:
if (ch == mark) {
yylval.id = strdup(result.c_str());
return tok_literal; // return 一个字符串标记
} else {
result.push_back(ch);
}
}
}
}
通过这两个词法标记,可以组成一个include头文件的语法
见Thrifty.yy (bison文件)
Include:
tok_include tok_literal
{
pdebug("Include -> tok_include tok_literal");
if (g_parse_mode == INCLUDES) {
std::string path = include_file(std::string($2));
if (!path.empty()) {
g_program->add_include(path, std::string($2));
}
}
}
当碰到这个include头文件语法时会调用 g_program->add_include方法,把一个头文件添加到语法树中。
语法树的其它部分原理是一样,慢慢的就充实了struct service 等结构,就完成了语法树。