gpt4 book ai didi

c - 如何创建一个解释器来在 Flex/Bison 中打印字符串

转载 作者:行者123 更新时间:2023-11-30 15:09:38 24 4
gpt4 key购买 nike

我使用 flex/bison 创建了一个小型解释器。

这只能打印一个数字,但我想知道如何添加一个字符串打印?

<小时/>

词法分析器:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
%}
%%

<INITIAL>[s|S][h|H][o|O][w|W] {return show;}
<INITIAL>[0-9a-zA-z]+ {yylval.num=atoi(yytext);return string;}
<INITIAL>[\-\+\=\;\*\/] {return yytext[0];}
%%
int yywrap (void) {return 1;}
<小时/>

yacc:

%{
void yyerror(char *s);
#include <stdio.h>
#include <stdlib.h>
%}
%union {int num;}
%start line
%token show
%token <num> number
%type <num> line exp term

%%
line : show exp ';' {printf("showing : %d\n",$2);}
| line show exp ';' {printf("showing : %d\n",$3);}
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
| exp '*' term {$$ = $1 * $3;}
| exp '/' term {$$ = $1 / $3;}
;
term : number {$$ = $1;}
%%
int main (void)
{
return yyparse();
}
void yyerror (char *s)
{
printf("-%s at %s !\n",s );
}
<小时/>

测试数据:

show 5;
show 5+5;
show 5*2-5+1;
<小时/>

我想将字符串代码添加到词法分析器:

<INITIAL>\"                                 {BEGIN(STRING);}
<STRING>\" {BEGIN(INITIAL);}

现在如何使用content of in <STRING>

你能帮我完成我的翻译吗?

我需要将此示例添加到我的解释器中:

show "hello erfan";//hello erfan
show "hello ".5;//hello 5

请帮助我。

最佳答案

目前您的解释器也无法处理数字! (它是一个解释器,因为它直接生成结果,并且不会像编译器那样生成代码)。

要使其适用于数字(再次),您必须从词法分析器返回数字标记而不是字符串。这行是错误的:

<INITIAL>[0-9a-zA-z]+                       {yylval.num=atoi(yytext);return string;}

它应该返回一个数字标记:

<INITIAL>[0-9]+                       {yylval.num=atoi(yytext);return number;}

现在让我们添加一个字符串。我看到你开始了:

<INITIAL>\"                                 {BEGIN(STRING);}
<STRING>\" {BEGIN(INITIAL);}

我们需要将字符串的状态添加到词法分析器:

%x STRING

我们还应该匹配字符串的内容。我在这里稍微作弊一下:

<STRING>[^"]*\"                                  {BEGIN(INITIAL); return(string);}

我们还需要返回 lval 中的字符串值。再次作弊,我可以在整数中存储一个字符指针

<STRING>[^"]*\"             {BEGIN(INITIAL); yylval.num=strdup(yytext); return(string); }

现在我们必须将字符串添加到 yacc 语法中。我再次作弊,不允许混合整数和字符串。如果您愿意,您可以稍后扩展:

line    : show exp ';'          {printf("showing : %d\n",$2);}
| line show exp ';' {printf("showing : %d\n",$3);}
| show string ';' {printf("showing : %s\n",$2);}
| line show string ';' {printf("showing : %s\n",$3);}
;

我们需要记住声明字符串标记:

%token <num> number string

现在我们可以把它们放在一起:

词法分析器文件:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
%}
%x STRING
%%

<INITIAL>[s|S][h|H][o|O][w|W] {return show;}
<INITIAL>[0-9]+ {yylval.num=atoi(yytext);return number;}
<INITIAL>[\-\+\=\;\*\/] {return yytext[0];}
<INITIAL>\" {BEGIN(STRING);}
<STRING>[^"]*\" {BEGIN(INITIAL);yylval.num=strdup(yytext);return(string);}
%%
int yywrap (void) {return 1;}

解析器文件:

%{
void yyerror(char *s);
#include <stdio.h>
#include <stdlib.h>
%}
%union {int num;}
%start line
%token show
%token <num> number string
%type <num> line exp term

%%
line : show exp ';' {printf("showing : %d\n",$2);}
| line show exp ';' {printf("showing : %d\n",$3);}
| show string ';' {printf("showing : %s\n",$2);}
| line show string ';' {printf("showing : %s\n",$3);}
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
| exp '*' term {$$ = $1 * $3;}
| exp '/' term {$$ = $1 / $3;}
;
term : number {$$ = $1;}
%%
int main (void)
{
return yyparse();
}
void yyerror (char *s)
{
printf("-%s at %s !\n",s );
}
#include "lex.yy.c"

它很基本并且有效(我测试过)。我还有很多东西需要打磨。您可以从字符串文本中删除引号字符;您可以使字符串标记为字符串值而不是整数,以避免可怕的类型不匹配,并且您可以使 show 语句更复杂一些,但至少我已经让您开始了。

关于c - 如何创建一个解释器来在 Flex/Bison 中打印字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36547267/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com