質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。

受付中

C自作コンパイラ do-while構文規則(C, yacc, lex)

j0ker_9
j0ker_9

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。

1回答

0リアクション

0クリップ

452閲覧

投稿2022/07/03 01:51

Cの自作コンパイラにおいてdo-while文を実装したいのですが、syntax errorになってしまいます。以下のコードのdo-while文においてどのように修正すればよいか教えていただきたいです。以下に関連ファイルを載せておきます。

yacc

%token NUM; %token IDENT; %token READ; %token PRINT; %token WHILE; %token IF; %token DO; %left '+' '-'; %left '*' '/'; %% prog : IDENT '{' stlist'}' { dotree($3); return 0; } ; stlist : { $$ = 0; } | stlist stat { $$ = node(T_STLIST, $1, $2); } ; stat :var '=' expr ';' { $$ = node(T_ASSIGN, $1, $3); } | READ var ';' { $$ = node(T_READ, $2, 0); } | PRINT expr ';' { $$ = node(T_PRINT, $2, 0); } | WHILE '(' cond ')' stat { $$ = node(T_WHILE, $3, $5); } | IF '(' cond ')' stat { $$ = node(T_IF, $3, $5); } | DO '{' expr '}' stat { $$ = node(T_DO, $3, $5); }  // do-whileを表現する構文規則 | '{' stlist '}' { $$ = $2; } ; cond : expr '<' expr { $$ = node(T_LT, $1, $3); } | expr '>' expr { $$ = node(T_GT, $1, $3); } ; expr : term { $$ = $1; } | expr '+' term { $$ = node(T_ADD, $1, $3); } | expr '-' term { $$ = node(T_SUB, $1, $3); } ; term: prim{ $$ = $1; } | term '*' prim { $$ = node(T_MUL, $1, $3); } | term '/' prim { $$ = node(T_DIV, $1, $3); } | term '%' prim { $$ = node(T_REM, $1, $3); } ; prim : NUM { $$ = node(T_NUM, atoi(yytext), 0); } | var { $$ = node(T_VAR, $1, 0); } | '(' expr ')' { $$ = $2; } ; var : IDENT { $$ = lookup(yytext); } ;

test.uec

main { read x; i = 0; do{ // ここのdo-whileを実装したいです。 i = i + x; x = x - 1; }while(x > 0); print i;

lex

alpha [a-zA-Z] digit [0-9] white [\n\t ] %% while { return WHILE; } if { return IF; } do { return DO; } // ここも正しいか不明 read { return READ; } print { return PRINT; } {alpha}({alpha}|{digit})* { return IDENT; } {digit}+ { return NUM; } [-+()=;{}<>*/%] { return yytext[0]; } {white} { ; }

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/07/03 03:14

こちらの質問が複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました。

actorbug

2022/07/03 07:16

試せる環境がないので、間違っていたらすみません。 | DO stat WHILE '(' cond ')' ';' { $$ = node(T_DO, $5, $2); }  // do-whileを表現する構文規則
j0ker_9

2022/07/03 07:53

actorbugさんの通りにするとyaccのコンパイルエラーが解消されました! しかし、まだdo-whileを実行できません。おそらく以下のCコードに問題があるのですが、どこが問題かわかりますでしょうか?? ちなみにwhileは正常に動きますので、whileと一緒に掲載します。 --------------------------------------- case T_WHILE: l = labelno++;  //ラベル更新 printf(".L%d:\n", l);  // ラベル l を生成 emittree(ntab[i].left);  // 条件文の判定 printf(".L%d\n", l+1);  // 条件を満たさなかったら l+1 のラベルに移動 emittree(ntab[i].right);  // while文の中身を実行 printf("jmp .L%d\n", l);  // ラベル l に移動 printf(".L%d:\n", l+1);  // ラベル l+1 を生成 break; case T_DO: l = labelno++;  // ラベルを更新 printf(".L%d:\n", l);  // ラベル l を生成 emittree(ntab[i].right);  // doの部分を実行 emittree(ntab[i].left);  // whileの条件文を実行 break;  // 条件を満たさなかったら終了 printf("jmp .L%d\n", l);  // ラベル l に移動 } ----------------------------------- 長文失礼しました。問題点がわかりそうでしたら指摘をお願いいたします。
actorbug

2022/07/03 13:42 編集

正直コード生成系はさっぱりですが、emittree(ntab[i].left);直後にbreakしたら駄目なのは分かります。 現在実行中のコードと生成中のコードの区別がついていないのではないでしょうか。
actorbug

2022/07/03 20:57

yaccの記述も、どういう理屈で解釈されるか「理解」できていれば簡単に書けたはずです。 case T_DO:についても、case T_WHILE:の動作原理を「理解」できていれば簡単に書けます。 他人に頼っていたら、いつまでたっても自力で書けるようにはなりません。 まずはT_WHILEを本当の意味で「理解」できるよう努力することをお勧めします。
j0ker_9

2022/07/04 02:05

T_WHILEは上記のコメントで動作を正しく説明できていると考えています。T_WHILEの本当の意味はコメントの内容とは違うのでしょうか?

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。