我在努力学习Flex & Bison。我已经阅读过材料,并且我从理论上理解了它是如何工作的。然而,我似乎无法实现最基本的事情而不触及心理障碍。(注意:我没有上过任何编译器课程,也没有学过类似that...this的课程,这是我第一次接触到这些东西)。我想,一旦我看到这个超级基本的东西实现了,我将能够更容易地继续前进和理解。
基本上,我所要做的就是编写一个程序,当看到type my_type /// some text时,它将调用my_type的函数"set_text",并将文本设置为该注释之后的内容。相反,我的Bison语法将调用函数my_type.set_text(some text); --我意识到不用使用Flex和Bison就可以很容易地做到这一点,但关键是要学习。
我已经设置了文件,我需要实现的correctly...all是令牌传递(来自Flex)和所采取的操作(来自Bison)。
到目前为止,我的Flex令牌通过了:
"\/"{3} { return COMMENT; }到目前为止我的野牛令牌被抢了
%token COMMENT这是我唯一能想到的。我知道我还需要什么.我只是不知道该怎么做。我知道我需要:
( a)将类型和my_type传递为
( b)在Bison中想出一条“规则”来处理这些东西,并调用函数更正函数
有什么帮助吗?我已经走远了吗?
更新(关于如何做到这一点的进一步思考):也许我的Bison文件应该包含如下规则
commented_variable: {($2).set_text($4);}
IDENTIFIER NAME COMMENT COMMENT_TEXT 因此,我的Flex文件需要传递这些令牌吗?我在正确的轨道上吗?
发布于 2011-06-26 13:24:16
让我提出一些建议。虽然使用COMMENT的启动条件单独处理flex和COMMENT_TEXT并不是不可能的,但我认为一次处理它们更容易。
bison源代码将类似于以下(虚拟代码):
%union {
name_type *name;
char const *comment;
}
%token <name> NAME
%token <comment> COMMENT
%%
commented_variable: IDENTIFIER NAME COMMENT {$2->set_text($3);}从词汇角度看,您的IDENTIFIER和NAME似乎难以区分。所以我用用户代码(而不是词汇)对它们进行分类。flex源如下所示:
"///".* {
yylval.comment = strdup( yytext + 3 );
return COMMENT;
}
[A-Za-z_][A-Za-z_0-9]* {
name_type *n = lookup_name( yytext );
if ( n ) {
yylval.name = n;
return NAME;
}
return IDENTIFIER;
}但是,上面的代码仍然需要适当的name_type和lookup_name,以及从strdup返回的指针的free。
如果您在flex/bison方面没有太多经验,我建议您首先充分确认lexer。例如,我建议使用简单的代码来确认预期的令牌,如
int main() { while ( yylex() ) {} }和
"///".* printf("comment %s\n", yytext);
[A-Za-z_][A-Za-z_0-9]* printf("symbol %s\n", yytext);同样,对于bison代码,我建议首先解决转换/减少冲突这样的语法问题,并确认使用以下简单代码正确识别语法:
commented_variable: IDENTIFIER NAME COMMENT { puts("OK"); }发布于 2011-06-24 07:45:08
考虑到您实际上是在使用分隔符后面的文本,我不会对上面的任何内容使用“注释”一词。也就是说,您在更新中所做的几乎是正确的想法。
https://stackoverflow.com/questions/6464224
复制相似问题