ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

コンパイラ・コンパイラコミュのはじめまして、質問があります。

  • mixiチェック
  • このエントリーをはてなブックマークに追加
 卒業論文のために、初めてyaccを使おうと思っているのですが。分らないことだらけで困っています。以下のようなソースファイルを実行したいのですが、どうしても以下のような警告(引数の型が合わない?)が出てしまいます。皆さんのご意見をお聞きしたいです。よろしくお願いします。

////////////////////////////////////////////////////////
//ヘッダーファイル:head.h
#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>

#define PTL 100
#define PTR 101
#define R 102
#define D 103
#define A 104

struct node{
int NUM;
struct node* one;
struct node* two;
struct node* three;
struct node* four;
};

struct node* make_node(struct node* a , struct node* b, struct node* c, struct node* d);
struct node* make_op(int NUM);
//////////////////////////////////////////////////////

///////////////////////////////////////////////////////
//yacc部
#include"head.h"


FILE *fp;
%}

%token PT_R PT_L ALP RMD DOT
%start sxpr
%%

sxpr : pxpr sxpr{$$ = make_node($1, $2, NULL, NULL);}
|
;
pxpr : PT_L expr PT_R{$$ = make_node(make_op($1), $2, make_op($3), NULL);}
;
expr : RMD VAL DOT FUNC{$$ = make_node(make_op($1), $2, make_op($3), $4);}
;

VAL : ALP MR_V{$$ = make_node(make_op($1), $2, make_op($3), $4);}
;
MR_V : SR_V MR_V{$$ = make_node($1, $2, NULL, NULL);}
|
;
SR_V : ALP{$$ = make_node(make_op($1), NULL, NULL, NULL);}
;


FUNC : ALP NF{$$ = make_node(make_op($1), $2, NULL, NULL);}
| pxpr NF{$$ = make_node($1, make_op($2), NULL, NULL);}
;
NF : SNF NF{$$ = make_node($1, $2, NULL, NULL);}
|
;
SNF : ALP{$$ = make_op($1)}
| pxpr{$$ = make_node($1, NULL, NULL, NULL);}
;
%%
///////////////////////////////////////////////////////

///////////////////////////////////////////////////////
//c言語による関数の定義部
#include"head.h"

void make_head()
{
head = (struct node*)malloc(sizeof(struct node));

}
struct node* make_node(struct node* a , struct node* b, struct node* c, struct node* d)
{
struct node* p;
p = (struct node*)malloc(sizeof(struct node));

p->one = a;
p->two = b;
p->three = c;
p->four = d;

return p;

}

struct node* make_op(int num)
{
struct node* a;
a = (struct node*)malloc(sizeof(struct node));
a->one = NULL;
a->two = NULL;
a->four = NULL;
a->three = NULL;
a->NUM = num;

return a;
}

////////////////////////////////////////////////////////

///////////////////////////////////////////////////////
//エラーメッセージ
$ make
cc -c y.tab.c -o parse.o
test.y: In function `yyparse':
test.y:12: warning: passing arg 1 of `make_node' makes pointer from integer with
out a cast
test.y:12: warning: passing arg 2 of `make_node' makes pointer from integer with
out a cast
test.y:12: warning: assignment makes integer from pointer without a cast

上のようなメッセージが大量に出てしまいます。
////////////////////////////////////////////////////////

コメント(2)

 えーと、yaccやbisonから離れてもう何年にもなるので最新のbison等がどんなことができるようになっているのか知らないため、もっといい方法があるかもしれませんが…。

 yaccやbisonはディフォルトのデータ型(各意味値の型)はintです。なので、

exp : exp '+' exp { $$ = $1 + $3; }

のような感じで作るよくある計算機プログラムがうまくいくのは実はintしか使わないからです。これを実数計算機にするには、

#define YYSTYPE double

とする必要があります。逆にこの場合計算機はdoubleしか使えなくなります。上記の文法ファイルを見る限り全ての値はstruct node*のようなので、

#define YYSTYPE struct node*

を最初の%%の前に書いてあげればコンパイルは上記のメッセージ出力なしに通るかと思います(すいません、めんどくさくて試してないですが…)。
 まぁ、出ているのはエラーではなくて警告(整数からポインタへの暗黙キャスト)ですから無視しても「動いちゃう」ような気もします^^;

 ちなみに、各非終端記号の値が整数だったりポインタだったりする場合、この方法は都合が悪いです。この場合、やはり最初の%%の前に#define YYSTYPE ... の代わりに、

%union {
 int i;
 struct node* ptr;
}

といったような共用体の宣言を行い、このあとに、

%type <ptr> exp sexp
%type <i> number
 :
 :

と全ての非終端記号についてunionのどのメンバを使用するかをチクチク指定してあげれば大丈夫になります。
ありがとうございます。大変参考になりました。すぐに試してみます。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

コンパイラ・コンパイラ 更新情報

コンパイラ・コンパイラのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング