AC | B | D | E | |
a | B | B | B | B |
b | AC | D | E | AC |
この状態遷移表を用いて、引数として渡された文字列が、正規表現 (a|b)*abbにマッチするならば 1をそうでなければ 0を返す関数 int ababb(char*)を定義せよ。
#define AC 0 #define B 1 #define D 2 #define E 3 int table[2][4] = {{B, B, B, B}, {AC, D, E, AC}}; /* 遷移表を配列として表現 */ int ababb(char* str) { int state=AC; while(*str) { char c = *str; state=table[c-'a'][state]; str++; } return state==E; } |
%{ /* 動作記述のなかで用いる関数の定義や宣言をここに書く。 */ /* 次の 2行は決まり文句 */ #define YY_SKIP_YYWRAP int yywrap() { return 1; } %} %% /* ここに動作記述を書く。*/ /* ECHOはマッチした文字列をそのまま出力するマクロ */ [hH]ello { printf("sawadi"); } . { ECHO; } /* その他の文字はそのまま出力 */ %% /* その他の関数の定義などをここに書く。*/ int main () { return yylex(); } |
%{ /* 動作記述のなかで用いる関数の定義や宣言をここに書く。 */ void ansi(int d) { /* 出力する文字の色を変える */ printf("\033[%dm", d); } /* 次の 2行は決まり文句 */ #define YY_SKIP_YYWRAP int yywrap() { return 1; } %} %% /* ここに動作記述を書く。*/ /* ECHOはマッチした文字列をそのまま出力するマクロ */ "/*".*"*/" { ansi(31); ECHO; ansi(0); } "." { ECHO; exit(1); } . { ECHO; } /* その他の文字はそのまま出力 */ %% /* その他の関数の定義などをここに書く。*/ int main () { return yylex(); } |
この問題については、第2回レポートで再度提出してもらうことにします。 その時、「/* / */」や「/* * */」が赤色になるかどうかについても、 確認してください。
int op_index(int token) { /* 表を引きやすいように連続した数値に写す。*/ switch (token) { case BGN: return 0; case '+': return 1; case '-': return 2; case '*': return 3; case '/': return 4; case '(': return 5; case ')': return 6; case NUM: return 7; case END: return 8; default: printf("不正な構文要素 (%d)。\n", token); exit(1); return 0; } } char prec_table[8][8] = { /* 演算子順位表 */ /* 行に ENDがないこと、列に BGNがないことに注意。*/ /* '+', '-', '*', '/', '(', ')', NUM, END */ /* BGN */ {LT, LT, LT, LT, LT, ERR, LT, EQ}, /* '+' */ {GT, GT, LT, LT, LT, GT, LT, GT}, /* '-' */ {GT, GT, LT, LT, LT, GT, LT, GT}, /* '*' */ {GT, GT, GT, GT, LT, GT, LT, GT}, /* '/' */ {GT, GT, GT, GT, LT, GT, LT, GT}, /* '(' */ {LT, LT, LT, LT, LT, EQ, LT, ERR}, /* ')' */ {GT, GT, GT, GT, ERR, GT, ERR, GT}, /* NUM */ {GT, GT, GT, GT, ERR, GT, ERR, GT}, }; /* 中略 */ switch (data2.token) { case '+': /* Expr -> Expr + Expr */ /* printf("Expr -> Expr '+' Expr\n"); */ yylval = d1+d2; push(Expr, yylval); break; case '-': /* Expr -> Expr - Expr */ /* printf("Expr -> Expr '-' Expr\n"); */ yylval = d1-d2; push(Expr, yylval); break; case '*': /* Expr -> Expr * Expr */ /* printf("Expr -> Expr '*' Expr\n"); */ yylval = d1*d2; push(Expr, yylval); break; case '/': /* Expr -> Expr / Expr */ /* printf("Expr -> Expr '/' Expr\n"); */ yylval = d1/d2; push(Expr, yylval); break; default: printf("エラー: 不正な演算子 (%d)。\n", data2.token); return 1; } |
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <math.h> /* 中略 */ int op_index(int token) { /* 表を引きやすいように連続した数値に写す。*/ switch (token) { case BGN: return 0; case '+': return 1; case '-': return 2; case '*': return 3; case '/': return 4; case '^': return 5; case '(': return 6; case ')': return 7; case NUM: return 8; case END: return 9; default: printf("不正な構文要素 (%d)。\n", token); exit(1); return 0; } } char prec_table[9][9] = { /* 演算子順位表 */ /* 行に ENDがないこと、列に BGNがないことに注意。*/ /* '+', '-', '*', '/', '^', '(', ')', NUM, END */ /* BGN */ {LT, LT, LT, LT, LT, LT, ERR, LT, EQ}, /* '+' */ {GT, GT, LT, LT, LT, LT, GT, LT, GT}, /* '-' */ {GT, GT, LT, LT, LT, LT, GT, LT, GT}, /* '*' */ {GT, GT, GT, GT, LT, LT, GT, LT, GT}, /* '/' */ {GT, GT, GT, GT, LT, LT, GT, LT, GT}, /* '^' */ {GT, GT, GT, GT, LT, LT, GT, LT, GT}, /* '(' */ {LT, LT, LT, LT, LT, LT, EQ, LT, ERR}, /* ')' */ {GT, GT, GT, GT, GT, ERR, GT, ERR, GT}, /* NUM */ {GT, GT, GT, GT, GT, ERR, GT, ERR, GT}, }; /* ... */ switch (data2.token) { /* ... */ case '^': /* Expr -> Expr ^ Expr */ /* printf("Expr -> Expr '^' Expr\n"); */ yylval = pow(d1,d2); push(Expr, yylval); break; /* ... */ } |
この問の解答については、まだ公開を控えます。