2017-03-10 16 views
0

私は単純なプログラミング言語(宿題)用にASTを構築しようとしています。 しかし、私はそれを動作させることはできません:中間値($ 1、$ 2、...)は無効で、私が "サブ式"で返すものに対応していないようです。BisonでASTをビルドするときに無効なポインタ

私のプロジェクトのBisonコードはここにあります(問題はここにあり、私のAST関数ではないと思います)。私は無効な値に遭遇したときにコメントを付けました。 Bisonを使ったのは私の最初のプロジェクトなので、正しくやっているかわからない。

私もFlexを使用していますが、フレックスコードが正しく動作しているようです。

ありがとうございました。あなたのレクサー(あなたが表示されませんフレックスコードは、)直接yytextを返すため

%{ 
#include <stdio.h> 

#include "node.h" 
#include "print_node.h" 

int yylex(); 
int yyerror(char * s); 

CommandNode * root = NULL; 
%} 

%union 
{ 
    struct ExpressionNode * expression; 
    struct CommandNode * command; 
    int number; 
    char * var; 
} 

%type <expression> E T F 
%type <command>  C 

%token <number>  NUMBER 
%token <var>   VAR 

%token     AF SKIP SEQ IF THEN ELSE WHILE DO ADD SUB MUL EOL 

%% 

root:   C EOL  { root = $1; return 0; /************ $1 seems to be garbage ************/ } 
       ; 

E:    E ADD T { $$ = newAddNode($1,$3); } 
     |  E SUB T { $$ = newSubNode($1,$3); } 
     |  T   { $$ = $1;    } 
     ; 

T:    T MUL F { $$ = newMulNode($1,$3); } 
     |  F   { $$ = $1;    } 
     ; 

F:    '(' E ')' { $$ = $2;    } 
     |  NUMBER  { $$ = newNumberNode($1); } 
     |  VAR  { $$ = newVarNode($1); } 
     ; 

C:    SKIP     { $$ = newSkipNode();  } 
     |  VAR AF E    { $$ = newAfNode($1,$3); } 
     |  '(' C ')'   { $$ = $2;     } 
     |  IF E THEN C ELSE C { $$ = newIfNode($2,$4,$6); } 
     |  WHILE E DO C   { $$ = newWhileNode($2,$4); } 
     |  C SEQ C    { $$ = newSeqNode($1,$3); /************ $1 and $3 seems to be garbage ************/ } 
     ; 

%% 

int main() 
{ 
    yyparse(); 
} 

int yyerror(char * s) 
{ 
    fprintf(stderr, "yyerror: %s\n", s); 
} 
+0

"(私の問題はここにあり、私のASTの機能ではないと思います)"私はそれについてはあまりよく分かりません。あなたもそれらを投稿することはできますか? – sepp2k

+1

貼ったものは私にはうまく見えます。あなたのノード作成はmallocメモリを機能させるのか、それともローカル変数のアドレスを返すだけですか? 2番目の場合、それは問題になります。最初の場合は、結局、割り当てられたメモリを解放するコードを挿入する必要があります。いつものように、あなたは[mcve]を提供することによって良い答えを手に入れることができます。 – rici

+1

フレックス・タグは、あなたの問題に関連していると言っているので、削除しました。あなたがそれを戻すか、または将来別の質問をするのが正当な理由があるなら、フレックス語彙スキャナジェネレータの正しいタグは[tag:flex-lexer]です。 [tag:flex]はApacheプロジェクトの一部である埋め込み言語です。 – rici

答えて

0

は最も一般的に、あなたが記述の症状が起こります。 yytextはスキャナの内部バッファを指しているので、そのインスタンスは正常に見えますが、次のトークンが読み取られた後、その値は不思議に変わります。それを修正するために

[a-zA-A][a-zA-Z0-9]* { yylval.var = yytext; return VAR; } 

、あなたのパーサーにそれを返す前にyytextのコピーを作成する必要があります。これはあなたのようなフレックスルールを持っている場合に発生します。何かのように

[a-zA-A][a-zA-Z0-9]* { yylval.var = strdup(yytext); return VAR; } 

あなたはメモリリークにさらされますが、トリックを行います。

+0

ありがとう!私はast関数で文字列のコピーを行っていましたが、明らかに遅すぎました。私のバグは今解決されています(ただし、私はいくつかの間違いを修正したので、それが唯一の問題ではないと確信しています)。 –

関連する問題