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

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

新規登録して質問してみよう
ただいま回答率
85.44%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

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

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

コンパイラ

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

Q&A

1回答

954閲覧

C言語自作コンパイラ 代入した変数名をプロンプトに表示

j0ker_9

総合スコア1

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

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

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

コンパイラ

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

0グッド

0クリップ

投稿2022/07/04 08:43

C言語の自作コンパイラを作成しているのですが、変数に値を格納した後、その値を表示する際に代入した変数名も同時にプロンプトに表示されるようにしたいです。以下に関連ファイルと実行例を記載します。また、表示量を減らすために必要のないであろう範囲は省略しました。

lex

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

yacc

1%token NUM; 2%token IDENT; 3%token READ; 4%token PRINT; 5%left '+' '-'; 6%left '*' '/'; 7%% 8 9prog : IDENT '{' stlist'}' { dotree($3); return 0; } 10; 11stlist : { $$ = 0; } 12| stlist stat { $$ = node(T_STLIST, $1, $2); } 13; 14stat :var '=' expr ';' { $$ = node(T_ASSIGN, $1, $3); } 15| READ var ';' { $$ = node(T_READ, $2, 0); } 16| PRINT expr ';' { $$ = node(T_PRINT, $2, 0); } 17| '{' stlist '}' { $$ = $2; } 18; 19cond : expr '<' expr { $$ = node(T_LT, $1, $3); } 20| expr '>' expr { $$ = node(T_GT, $1, $3); } 21; 22expr : term { $$ = $1; } 23| expr '+' term { $$ = node(T_ADD, $1, $3); } 24| expr '-' term { $$ = node(T_SUB, $1, $3); } 25; 26term: prim{ $$ = $1; } 27| term '*' prim { $$ = node(T_MUL, $1, $3); } 28| term '/' prim { $$ = node(T_DIV, $1, $3); } 29| term '%' prim { $$ = node(T_REM, $1, $3); } 30; 31prim : NUM { $$ = node(T_NUM, atoi(yytext), 0); } 32| var { $$ = node(T_VAR, $1, 0); } 33| '(' expr ')' { $$ = $2; } 34; 35var : IDENT { $$ = lookup(yytext); } 36;

C

1#include <stdio.h> 2struct stab { 3 int val; 4 char name[20]; } stab[100]; 5int stabuse = 0; 6struct node { 7 int type, left, right; } ntab[400]; 8int ntabuse = 1; 9#define T_STLIST 1 10#define T_ASSIGN 2 11#define T_READ 3 12#define T_PRINT 4 13#define T_ADD 5 14#define T_REM 9 15#define T_NUM 10 16#define T_VAR 11 17#define T_LT 14 18#define T_GT 15 19int lookup(char*); 20int node(int, int, int); 21void dotree(int); 22extern char *yytext; 23#include "y.tab.c" 24#include "lex.yy.c" 25 26int main() { 27 yyparse(); 28 return 0; 29} 30int lookup(char *s) { 31 int i; 32 for(i = 0; i < stabuse; ++i) 33 if(strcmp(stab[i].name, s) == 0) return i; 34 if(stabuse >= 99) { 35 printf("table overflow.\n"); exit(1); } 36 strcpy(stab[stabuse].name, s); return stabuse++; 37} 38int node(int t, int l, int r) { 39 int i = ntabuse++; 40 ntab[i].type = t; 41 ntab[i].left = l; 42 ntab[i].right = r; 43 return i; 44} 45void dotree(int i) { 46 int stk; 47 printf(" .section .rodata\n"); 48 printf(".Lprompt: .string\"> \"\n");   /* ここの変更が必要、、、? 49 printf(".Lread: .string\"%%ld\"\n"); 50 printf(".Lprint: .string\"%%ld\\n\"\n"); 51 printf(" .text\n"); 52 printf(".global main\n"); 53 printf("main:\n"); 54 printf(" pushq %%rbp\n"); 55 printf(" movq %%rsp,%%rbp\n"); 56 stk = (8*stabuse + 15) / 16; 57 stk *= 16; 58 printf(" subq $%d,%%rsp\n", stk); 59 emittree(i); 60 printf(" leave\n"); 61 printf(" ret\n"); 62} 63 64void emittree(int i) 65{ 66 static int labelno = 1; 67 int l; 68 switch(ntab[i].type) { 69 case T_STLIST: if(ntab[i].left) emittree(ntab[i].left); 70 emittree(ntab[i].right); 71 break; 72 case T_READ: printf(" movq $.Lprompt,%%rdi\n"); 73 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 74 printf(" call printf\n"); 75 printf(" leaq %d(%%rbp),%%rsi\n", -(ntab[i].left+1)*8); 76 printf(" movq $.Lread,%%rdi\n"); 77 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 78 printf(" call scanf\n"); 79 break; 80 case T_PRINT: emittree(ntab[i].left); 81 printf(" popq %%rsi\n"); 82 printf(" movq $.Lprint,%%rdi\n"); 83 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 84 printf(" call printf\n"); 85 break; 86 case T_NUM: printf(" pushq $%d\n", ntab[i].left); 87 break; 88 case T_VAR: printf(" pushq %d(%%rbp)\n", -(ntab[i].left+1)*8); 89 break; 90 default: printf("NotImplemented: %d\n", ntab[i].type); 91 break; 92 case T_ASSIGN: emittree(ntab[i].right); 93 printf(" popq %d(%%rbp)\n", -(ntab[i].left+1)*8); 94 break; 95 case T_ADD: emittree(ntab[i].left); 96 emittree(ntab[i].right); 97 printf(" popq %%rdx\n"); 98 printf(" popq %%rax\n"); 99 printf(" addq %%rdx,%%rax\n"); 100 printf(" pushq %%rax\n"); 101 break; 102 case T_REM: emittree(ntab[i].left); 103 emittree(ntab[i].right); 104 printf(" popq %%rsp\n"); 105 printf(" popq %%rax\n"); 106 printf(" movq $0,%%rdx\n"); 107 printf(" idivq %%rsp\n"); 108 printf(" pushq %%rdx\n"); 109 case T_LT: emittree(ntab[i].left); 110 emittree(ntab[i].right); 111 printf(" popq %%rcx\n"); 112 printf(" popq %%rax\n"); 113 printf(" cmp %%rcx,%%rax\n"); 114 printf(" jge "); 115 break; 116 case T_GT: emittree(ntab[i].left); 117 emittree(ntab[i].right); 118 printf(" popq %%rcx\n"); 119 printf(" popq %%rax\n"); 120 printf(" cmp %%rcx,%%rax\n"); 121 printf(" jle "); 122 break; 123 } 124}

ここから下は実行ファイルとその実行例です。

example.c

1main { 2read x; 3read yee; 4print x; 5print x + yee; 6print yee; 7}

a.out

1>./a.out 2x> 4 // readでxに代入 3yee> 5 // readでxに代入 4x=4  // 代入した変数と同時に値を表示 59   // 代入した変数がない場合は無表示 6yee=5  // 代入した変数と同時に値を表示

変更すべき範囲がどのあたりなのかも検討がつかないので、ご教授いただけると幸いです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

また、表示量を減らすために必要のないであろう範囲は省略しました。

省略しても構いませんが、コンパイル可能な状態までにしてください。

C

1 case T_READ: printf(" .section .rodata\n"); 2 static int k = 0; 3 printf(".Lprompt%d: .string \"%s> \"\n", ++k, stab[ntab[i].left].name); 4 printf(" .text\n"); 5 printf(" movq $.Lprompt%d,%%rdi\n", k); 6 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 7 printf(" call printf\n"); 8 printf(" leaq %d(%%rbp),%%rsi\n", -(ntab[i].left+1)*8); 9 printf(" movq $.Lread,%%rdi\n"); 10 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 11 printf(" call scanf\n"); 12 break; 13 case T_PRINT: l = ntab[i].left; 14 if (ntab[l].type == T_VAR) { 15 static int m = 0; 16 printf(" .section .rodata\n"); 17 printf(".Lvar%d: .string \"%s=\"\n", ++m, stab[ntab[l].left].name); 18 printf(" .text\n"); 19 printf(" movq $.Lvar%d,%%rdi\n", m); 20 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 21 printf(" call printf\n"); 22 } 23 emittree(l); 24 printf(" popq %%rsi\n"); 25 printf(" movq $.Lprint,%%rdi\n"); 26 printf(" movq $0,%%rax\n"); /* 浮動小数点レジスタを使わない */ 27 printf(" call printf\n"); 28 break;

投稿2022/07/19 15:33

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問