| 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;
/* ... */
}
|
この問の解答については、まだ公開を控えます。