使用 Flex &野牛

发布于 2024-11-17 11:17:50 字数 1036 浏览 3 评论 0原文

我正在尝试学习 Flex &野牛。我已经通读了材料,并且在理论层面上了解了它是如何运作的。然而,我似乎无法在不遇到心理障碍的情况下实现最基本的事情。 (注意:我没有参加任何编译器课程或类似的课程......这是我第一次接触这些东西)。我想一旦我看到这个超级基本的东西被实现,我将能够继续前进并更容易理解。

基本上,我想做的就是编写一个程序,在看到 type my_type /// some text 时将调用 my_type 的名为“set_text”的函数,并将文本设置为该注释之后的内容。相反,我的 Bison 语法将调用函数 my_type.set_text(some text); 我意识到我可以在不使用 Flex 和 Bison 的情况下轻松完成此操作,但重点是学习。

我已经正确设置了文件...我需要实现的只是令牌传递(来自 Flex)和采取的操作(来自 Bison)。

到目前为止我的 Flex 令牌传递情况:

"\/"{3}               { return COMMENT; }

到目前为止我的 Bison 令牌抓取情况

%token COMMENT

,这就是我能想到的全部内容。我知道我还需要什么......我只是不知道该怎么做。我知道我需要:
a) 将 type 和 my_type 作为某种东西传递
b) 在 Bison 中提出一个“规则”来处理这些东西并调用函数正确的函数

有帮助吗?我已经走远了吗?

更新(关于如何执行此操作的进一步想法): 也许我的 Bison 文件应该包含这样的规则:

commented_variable:                           {($2).set_text($4);}
    IDENTIFIER NAME COMMENT COMMENT_TEXT                      

因此我的 Flex 文件需要向它传递这些令牌?我走在正确的轨道上吗?

I'm trying to learn Flex & Bison. I've read through material, and I understand how it works at a theoretical level. However, I can't seem to even implement the most basic thing without hitting a mental block. (Note: I haven't taken any compiler courses or anything like that...this is my first exposure to any of this stuff). I think once I see this super basic thing implemented, I'll be able to move on and understand much more easily.

Basically, all I'm trying to do is write a program that upon seeing type my_type /// some text will call my_type's function called "set_text", and set the text to what's after that comment. Rather, my Bison grammar will call the function my_type.set_text(some text); I realize I could do this easily without using Flex and Bison, but the point is to learn.

I already have the files set up correctly...all I need to implement is the token passing (from Flex) and the action taken (from Bison).

My Flex token passing so far:

"\/"{3}               { return COMMENT; }

My Bison token grabbing so far

%token COMMENT

and that's seriously all I can come up with. I know what else I need...I just can't figure out how to do it. I know that I need:
a) to pass type and my_type as something
b) To come up with a "rule" in Bison to handle this stuff and call the function correct function

Any help? Am I way off already?

UPDATE (further thoughts on how to do this):
Maybe my Bison file should include a rule like

commented_variable:                           {($2).set_text($4);}
    IDENTIFIER NAME COMMENT COMMENT_TEXT                      

Thus my Flex file would need to pass it those tokens? Am I on the right track?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹂绝世的画 2024-11-24 11:17:50

让我推荐一些东西。
虽然处理 COMMENTCOMMENT_TEXT 并非不可能
单独使用 flex 的启动条件,我认为更容易
一次处理它们。
bison 源代码如下(虚构代码):

%union {
  name_type *name;
  char const *comment;
}
%token <name> NAME
%token <comment> COMMENT
%%
commented_variable: IDENTIFIER NAME COMMENT {$2->set_text($3);}

从词法角度来看,您的 IDENTIFIERNAME 似乎无法区分。
所以我在用户代码中对它们进行了排序(不是词汇上的)。
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返回的指针。
如果您对 flex/bison 没有太多经验,我建议首先使用
充分确认词法分析器。
例如,我建议确认预期的令牌被识别
使用像
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"); }

Let me suggest some stuffs.
Though it isn't impossible to process COMMENT and COMMENT_TEXT
individually using start condition of flex, I suppose it's easier to
handle them at a time.
bison source will be like the following(fictitious code):

%union {
  name_type *name;
  char const *comment;
}
%token <name> NAME
%token <comment> COMMENT
%%
commented_variable: IDENTIFIER NAME COMMENT {$2->set_text($3);}

From lexical viewpoint, your IDENTIFIER and NAME seem indistinguishable.
So I sorted them out in user code(not lexically).
flex source will be like the following:

"///".*                 {
                        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;
                        }

However, the above code still needs appropriate name_type and
lookup_name, and freeing the pointer returned from strdup.
If you don't have much experience in flex/bison, I'd recommend first
confirming lexer sufficiently.
For example, I suggest confirming that expected tokens are recognized
with simple code like
int main() { while ( yylex() ) {} } and

"///".*                 printf("comment %s\n", yytext);
[A-Za-z_][A-Za-z_0-9]*  printf("symbol %s\n", yytext);

Similarly, as for bison code, I recommend first resolving grammatical
issue like shift/reduce-conflict, and confirming that the grammar is
recognized properly with simple code like:

commented_variable: IDENTIFIER NAME COMMENT { puts("OK"); }
快乐很简单 2024-11-24 11:17:50

鉴于您实际上使用分隔符后面的文本,我不会对上面的任何内容使用“注释”一词。也就是说,您在更新中添加的内容几乎是正确的想法。

Given that you're actually using the text following the delimiter, I would not use the word "comment" for anything you have above. That said, what you've put into your update is pretty much the right idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文