いよいよ動作テストです。
動作テストと言うと、ハラハラドキドキしますよね。
~ソースコード~
スキャナ
► スポイラーを表示
CODE:
%{
#include
#include
#include "basic_basic_bison.h"
#pragma warning(disable:4996)
// extern YYLTYPE yylloc;
%}
nonzero [1-9]
digit [[:digit:]]
wspace [[:blank:]]
alpha [[:alpha:]]
alnum [[:alnum:]]
integer ({nonzero}{digit}*)|0
variable [_[:alpha:]][_[:alnum:]]*
%%
{integer} {
printf("found integer\n");
/*
next_location();
yylloc.last_column += yyleng;
yylval = atof(yytext);
//*/
return num_literal_token;
}
{variable} {
printf("found variable\n");
/*
next_location();
yylloc.last_column += yyleng;
//*/
return variable_token;
}
= {
printf("found '='\n");
/*
next_location();
yylloc.last_column += 1;
//*/
return '=';
}
\+ {
printf("found '+'\n");
/*
next_location();
yylloc.last_column += 1;
//*/
return '+';
}
- {
printf("found '-'\n");
/*
next_location();
yylloc.last_column += 1;
//*/
return '-';
}
\* {
printf("found '*'\n");
/*
next_location();
yylloc.last_column += 1;
//*/
return '*';
}
\/ {
printf("found '/'\n");
/*
next_location();
yylloc.last_column += 1;
//*/
return '/';
}
; {
printf("found ';'\n");
/*
next_location();
yylloc.last_column += 1;
//*/
return ';';
}
> {
printf("finished\n");
return 0;
}
%%
int yywrap(void)
{
return 1;
}
パーサ
► スポイラーを表示
CODE:
%defines
%{
#include
#include
#include
//#define YYSTYPE double
void yyerror(const char* s);
int yylex(void);
%}
%token num_literal_token
%token variable_token
%%
input : /* empty */
| input line
{
printf("bison:found input\n");
}
;
line : formula ';'
| ';'
{
printf("bison:found line\n");
}
;
formula : variable_token '=' formula
| formula '+' formula
| formula '-' formula
| formula '*' formula
| formula '/' formula
| val
{
printf("bison:found formula\n");
}
;
val : num_literal_token
| variable_token
{
printf("bison:found val\n");
}
;
%%
#if 0
/* トークン解析関数 */
int yylex(void)
{
#if 0
int c;
/* 空白、タブは飛ばす */
while((c = getchar()) == ' ' || c == '\t')
;
/* 数値を切り出す */
if(c == '.' || isdigit(c))
{
ungetc(c, stdin);
scanf("%lf", &yylval);
return NUM;
}
/* EOF を返す */
if(c == EOF)
return 0;
/* 文字を返す */
return c;
#endif
}
#endif
/* エラー表示関数 */
void yyerror(const char* s)
{
printf("bison:error=> %s\n", s);
}
int main(void)
{
/* 構文解析関数 yyparse */
yyparse();
getchar();
return 0;
}
テスト結果

この辺りはこちらの期待通りに動作してくれているようですね。
もっとも、演算子の優先順位を指定していないため、((((variable=1)+2)+3)+4)+5;という順序で評価されてしまってはいますが、これはしかたありませんね。

これは少し期待とは違った結果となりました。
var = 5
は;がありませんから、構文エラーになってほしかったのですが…。
その一方で
var
の方は構文エラーになっていますね。
おそらく;とは関係ない理由で構文エラーになっているのでしょう。
よく見ると、変数を 構文val として評価してもらえていないようです。
この辺りが原因ではないかと思います。
というわけで、次回は期待通りに動くように修正ですね。
それでは、楽しいプログラミングライフを!