2016-04-11 7 views
0

flex/bisonを使用して小さなインタプリタを作成しました。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 

私を助けてください。

答えて

1

現時点では、通訳者は数字でも動作しません! (その結果を直接生成し、コンパイラのようなコードを生成しないので、そのインタプリタです)。

数値を再現するには、文字列ではなくレクサーから数値トークンを返す必要があります。この行は間違っている:

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

今すぐ文字列を追加することができます:

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

それは数のトークンを返す必要があります。

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

我々はレクサーに文字列の状態を追加する必要があります:

%x STRING 

我々はまた、文字列の内容と一致している必要があり、私はあなたがスタートを切った参照してください。私はここでちょっと騙します:

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

また、lvalの文字列値を返す必要があります。私はcharポインタを整数に格納することができます

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

yacc文法に文字列を追加する必要があります。私は整数と文字列を混在させないことで、もう一度騙されている。

%token <num> number string 

は、今、私たちはそのすべて一緒に置くことができます:

レクサー・ファイル:

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);} 
     ; 

我々は文字列トークンを宣言することを忘れないでくださいする必要があります:あなたが望む後で場合に拡張することができます

%{ 
#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文をもっと複雑にすることができますが、少なくとも私はあなたを始めました。

+0

同じ(物理的な)行に複数の文字列がある入力でテストしましたか? – rici

+0

@rici - ああそう!貪欲な試合....よく目撃された。 –

+0

@rici固定... :-) –

関連する問題