%{
/*{{定型コード: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
/* エラー報告関数を定義します。 */
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_END
%token T_WAIT
%token T_STOP
%token T_PLAY
%token T_VOL
%token T_PAN
%token <v_num> T_NUM
%token <v_lab> T_LAB
%token T_EOL

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

%%

all
	: /* empty */
	| all line
	;
line
	:       T_EOL
	| inst  T_EOL
	| error T_EOL					{ yyerrok; }		/* 全てのシンタクスエラーを報告するために継続する */
	;
inst
	: T_DEF T_LAB					{ inst_def($2); }
	|       T_LAB					{ inst_def($1); }	/* 省略記法 */
	//
	| T_END						{ inst_end(); }
	//
	| T_WAIT expr					{ inst_wait($2); }
	//
	| T_STOP expr					{ inst_stop($2); }
	//
	| T_PLAY expr ',' expr ',' expr ',' expr	{ inst_play_m($2, $4, $6, $8); }
	| T_PLAY expr ',' expr ',' expr			{ inst_play_s($2, $4, $6); }
	//
	| T_VOL expr ',' expr				{ inst_vol($2, $4); }
	//
	| T_PAN expr ',' expr				{ inst_pan($2, $4); }
	;
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; }
	;

%%
