%{
/*{{定型コード:y.tab.y(宣言部,%{〜%}内)======================================*/
#ifdef  PIECE
#include "app.h"
#else //PIECE
#include "winapp.h"
#endif//PIECE
/* パーサースタックの初期値を定義します。
 * sizeof(YYSTYPE)*YYINITDEPTH) がスタック上に確保されます。
 * デフォルトでは200と定義されており、P/ECEには大きすぎます。
 * P/ECEに適切な、小さなサイズ(16)に、再定義しました。
 * パーサースタックが不足した場合は、自動的に拡張されるので、問題ありません。
 */
#define YYINITDEPTH 16
///* エラー報告関数を定義します。 */	→{{2015/03/06:'-e'オプション対応のためにwinapp.cへ移動しました。}}
//void yyerror(const char* fmt, ...) {
//  fprintf(stderr, "### error at line %d : ", yylineno);
//  { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); }
//  fputc('\n', stderr); }
/*}}定型コード:y.tab.y(宣言部,%{〜%}内)======================================*/
%}

%union {
	int   v_num;
	char* v_lab;
}
%token T_DEF
%token T_REPEAT
%token T_END
%token T_WAIT
%token T_EVENT
%token <v_num> T_NUM
%token <v_lab> T_LAB
%token T_EOL

%left '|'
%left '^'
%left '&'
%left '<' '>'
%left '+' '-'
%left '*' '/'
%nonassoc T_UPL T_UMI
%type <v_num> expr

%%

all
		: pre_blank
		| all block
		;
pre_blank
		: /* empty */
		| pre_blank T_EOL
		;
block
		: def             cmds end						//ループ無し
		| def      repeat cmds end						//全体ループ
		| def cmds repeat cmds end						//部分ループ
		| error eols					{ yyerrok; }		//全てのシンタクスエラーを報告するために継続する。
		;
def
		: T_DEF T_LAB eols				{ inst_def($2); }
		|       T_LAB eols				{ inst_def($1); }	//省略記法
		;
repeat
		: T_REPEAT eols					{ inst_repeat(); }
		;
end
		: T_END eols					{ inst_end(); }
		;
cmd
		: T_WAIT  expr eols				{ inst_wait($2); }
		| T_EVENT expr eols				{ inst_event($2); }
		| T_EVENT      eols				{ inst_event(1); }	//省略記法
		;
cmds
		:      cmd
		| cmds cmd
		;
eols
		:      T_EOL
		| eols T_EOL
		;
expr
		: T_NUM
		| '(' expr ')'					{ $$ =  $2; }
		| '+' expr %prec T_UPL				{ $$ =  $2; }
		| '-' expr %prec T_UMI				{ $$ = -$2; }
		| expr '+' expr					{ $$ = $1 + $3; }
		| expr '-' expr					{ $$ = $1 - $3; }
		| expr '*' expr					{ $$ = $1 * $3; }
		| expr '/' expr					{ $$ = $1 / $3; }
		| expr '&' expr					{ $$ = $1 & $3; }
		| expr '^' expr					{ $$ = $1 ^ $3; }
		| expr '|' expr					{ $$ = $1 | $3; }
		| expr '<' expr					{ $$ = $1 << $3; }
		| expr '>' expr					{ $$ = $1 >> $3; }
		;

%%
