view Bison-Flex/BasicCompiler-StackBase/script-parser.yy @ 2:fbe42292d479

upload test
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 10 May 2011 06:43:55 +0900
parents a3ea4c73696b
children
line wrap: on
line source

%skeleton "lalr1.cc"
%define "parser_class_name" "script_parser"
%defines
%{
#ifdef  _MSC_VER
#pragma warning(disable: 4800)
#pragma warning(disable: 4267)
#endif

#include <string>
#include "node.h"
class compiler;
%}
// The parsing context.
%parse-param { compiler& driver }
%lex-param   { compiler& driver }
%locations
//%expect 7
%initial-action
{
	// ロケーション初期化
	@$.begin.filename = @$.end.filename = &driver.get_filename();
};
// %debug
%error-verbose
// Symbols.
%union
{
	int                 ival;
	std::string        *sval;

	CArgs              *args;
	CNode              *expr;
	CAssign            *assign;
}
%{
#include "compiler.h"
%}

%token        END_OF_FILE    0 "end of file"
%token <ival> TK_IVAL          "ival"
%token <sval> TK_IDENTIFIER    "identifier"
%token        TK_EQ            "=="
%token        TK_NE            "!="
%token        TK_GE            ">="
%token        TK_LE            "<="
%token        TK_NEWLINE       "\n"

%token        TK_IF            "if"
%token        TK_THEN          "then"
%token        TK_ELSE          "else"
%token        TK_ENDIF         "endif"
%token        TK_FOR           "for"
%token        TK_TO            "to"
%token        TK_NEXT          "next"
%token        TK_WHILE         "while"
%token        TK_WEND          "wend"
%token        TK_END           "end"
%token        TK_RAND          "rand"
%token        TK_PRINT         "print"

%type <expr>		expr
%type <expr>		comp_expr
%type <expr>		value
%type <assign>		assign
%type <args>		args

%destructor { delete $$; } "identifier"

%destructor { delete $$; } args
%destructor { delete $$; } assign
%destructor { delete $$; } value
%destructor { delete $$; } expr
%destructor { delete $$; } comp_expr

%left '+' '-';
%left '*' '/' '%';
%left NEG;
%%
%start unit;

unit				: states
					| unit states
					;

states				: statement "\n"
					| "\n"
					;

statement			: "end"									{ driver.EndStatement(@1); }
					| assign								{ driver.AssignStatement(@1, $1); }
					| "if" comp_expr "then"					{ driver.IfStatement(@1, $2); }
					| "else"								{ driver.ElseStatement(@1); }
					| "endif"								{ driver.EndifStatement(@1); }
					| "for" assign "to" expr "step" expr	{ driver.ForStatement(@1, $2, $4, $6); }
					| "for" assign "to" expr				{ driver.ForStatement(@1, $2, $4, NULL); }
					| "next"								{ driver.NextStatement(@1); }
					| "while" comp_expr						{ driver.WhileStatement(@1, $2); }
					| "wend"								{ driver.WendStatement(@1); }
					| "print" args							{ driver.PrintStatement(@1, $2); }
					| error									/* エラーの場合 */
					;

assign				: value '=' expr				{ $$ = new CAssign(@1, '=', $1, $3); }
					;

comp_expr			: expr "==" expr				{ $$ = CNode::MakeNode(driver, @1, OP_EQ, $1, $3); }
					| expr "!=" expr				{ $$ = CNode::MakeNode(driver, @1, OP_NE, $1, $3); }
					| expr '>'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_GT, $1, $3); }
					| expr ">=" expr				{ $$ = CNode::MakeNode(driver, @1, OP_GE, $1, $3); }
					| expr '<'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_LT, $1, $3); }
					| expr "<=" expr				{ $$ = CNode::MakeNode(driver, @1, OP_LE, $1, $3); }
					;

expr				: expr '-'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_MINUS, $1, $3); }
					| expr '+'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_PLUS, $1, $3); }
					| expr '*'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_TIMES, $1, $3); }
					| expr '/'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_DIVIDE, $1, $3); }
					| expr '%'  expr				{ $$ = CNode::MakeNode(driver, @1, OP_MOD, $1, $3); }
					| '-' expr %prec NEG			{ $$ = CNode::MakeNode(driver, @1, OP_NEG, $2); }
					| '(' expr ')'					{ $$ = $2; }
					| value							{ $$ = $1; }
					| "ival"						{ $$ = new CNode(@1, OP_CONST, $1); }
					| "rand" '(' expr ')'			{ $$ = new CNode(@1, OP_RANDFUNC, $3); }
					;

value				: "identifier"					{ $$ = new CValueNode(@1, $1); }
					;

args				: expr							{ $$ = new CArgs(@1, $1); }
					| args ',' expr					{ $$ = $1->Add(@3, $3); }
					;

%%
void yy::script_parser::error(const yy::script_parser::location_type& l, const std::string& m)
{
	driver.error(l, m);
}