diff Bison-Flex/Compiler-StackBase/EUC/script-parser.yy @ 0:db40c85cad7a default tip

upload sample source
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Mon, 09 May 2011 03:11:59 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Bison-Flex/Compiler-StackBase/EUC/script-parser.yy	Mon May 09 03:11:59 2011 +0900
@@ -0,0 +1,243 @@
+%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;
+%}
+%parse-param { compiler& driver }
+%lex-param   { compiler& driver }
+%locations
+%expect 1				/* if文で衝突が発生するので、1つの衝突は無視 */
+%initial-action
+{
+	// ロケーション初期化
+	@$.begin.filename = @$.end.filename = &driver.get_filename();
+} ;
+// %debug
+%error-verbose
+// Symbols.
+%union
+{
+	int                 ival;
+	std::string        *sval;
+
+	int					type;
+	CValueList         *value_list;
+	CArgList           *arglist;
+	CDeclList          *decls;
+	CStateList         *states;
+	CStatement         *statement;
+	CArgDef            *argdef;
+	CArgs              *args;
+	CValueNode         *value;
+	CNode              *expr;
+	CAssign            *assign;
+	CStateBlock        *block;
+}
+%{
+#include "compiler.h"
+%}
+
+%token        END_OF_FILE    0 "end of file"
+%token <ival> TK_IVAL          "ival"
+%token <sval> TK_IDENTIFIER    "identifier"
+%token <sval> TK_SVAL          "sval"
+%token        TK_LOGOR         "||"
+%token        TK_LOGAND        "&&"
+%token        TK_EQ            "=="
+%token        TK_NE            "!="
+%token        TK_GE            ">="
+%token        TK_LE            "<="
+%token        TK_LSHIFT        "<<"
+%token        TK_RSHIFT        ">>"
+%token        TK_ADD_ASSIGN    "+="
+%token        TK_SUB_ASSIGN    "-="
+%token        TK_MUL_ASSIGN    "*="
+%token        TK_DIV_ASSIGN    "/="
+%token        TK_MOD_ASSIGN    "%="
+
+%token        TK_IF            "if"
+%token        TK_ELSE          "else"
+%token        TK_WHILE         "while"
+%token        TK_FOR           "for"
+%token        TK_SWITCH        "switch"
+%token        TK_CASE          "case"
+%token        TK_DEFAULT       "default"
+%token        TK_BREAK         "break"
+%token        TK_RETURN        "return"
+%token        TK_INTEGER       "int"
+%token        TK_STRING        "string"
+%token        TK_VOID          "void"
+
+%type <expr>		expr
+%type <value>		value
+%type <assign>		assign
+%type <value_list>	value_list
+%type <arglist>		arglist
+%type <argdef>		arg
+%type <decls>		decls decl_list
+%type <states>		states state_list
+%type <block>		block
+%type <args>		args
+%type <statement>	statement
+%type <type>		type
+
+%destructor { delete $$; } "identifier"
+%destructor { delete $$; } "sval"
+
+%destructor { delete $$; } value_list
+%destructor { delete $$; } arglist
+%destructor { delete $$; } arg
+%destructor { delete $$; } decls decl_list
+%destructor { delete $$; } states state_list
+%destructor { delete $$; } args
+%destructor { delete $$; } block
+%destructor { delete $$; } assign
+%destructor { delete $$; } statement
+%destructor { delete $$; } value
+%destructor { delete $$; } expr
+
+%left "||";
+%left "&&";
+%nonassoc "==" "!=" '>' '<' ">=" "<=";
+%left '&' '|';
+%left "<<" ">>";
+%left '+' '-';
+%left '*' '/' '%';
+%left NEG;
+%%
+%start unit;
+
+unit				: define_or_state
+					| unit define_or_state
+					;
+
+define_or_state		: error ';'
+					| function
+					| declaration
+					;
+
+declaration			: type value_list ';'						{ driver.DefineValue(@2, $1, $2); }
+					| type "identifier" '(' ')' ';'				{ driver.DefineFunction(@2, $1, $2, NULL); }
+					| type "identifier" '(' arglist ')' ';'		{ driver.DefineFunction(@2, $1, $2, $4); }
+					| "void" "identifier" '(' ')' ';'			{ driver.DefineFunction(@2, TYPE_VOID, $2, NULL); }
+					| "void" "identifier" '(' arglist ')' ';'	{ driver.DefineFunction(@2, TYPE_VOID, $2, $4); }
+					;
+
+value_list			: value								{ $$ = new CValueList($1); }
+					| value_list ',' value				{ $$ = $1->Add($3); }
+					;
+
+arglist				: arg								{ $$ = new CArgList($1); }
+					| arglist ',' arg					{ $$ = $1->Add($3); }
+					;
+
+arg					: type								{ $$ = new CArgDef(@1, $1, NULL); }
+					| type '&'							{ $$ = new CArgDef(@1, TypeToRef($1), NULL); }
+					| type "identifier"					{ $$ = new CArgDef(@1, $1, $2); }
+					| type '&' "identifier"				{ $$ = new CArgDef(@1, TypeToRef($1), $3); }
+					| type "identifier" '[' ']'			{ $$ = new CArgDef(@1, TypeToRef($1), $2); }
+					| type '&' "identifier" '[' ']'		{ $$ = new CArgDef(@1, TypeToRef($1), $3); }
+					;
+
+function			: type "identifier" '(' ')' block				{ driver.AddFunction(@1, $1, $2, NULL, $5); }
+					| type "identifier" '(' arglist ')' block		{ driver.AddFunction(@1, $1, $2, $4, $6); }
+					| "void" "identifier" '(' ')' block				{ driver.AddFunction(@1, TYPE_VOID, $2, NULL, $5); }
+					| "void" "identifier" '(' arglist ')' block		{ driver.AddFunction(@1, TYPE_VOID, $2, $4, $6); }
+					;
+
+type				: "int"								{ $$ = TYPE_INTEGER; }
+					| "string"							{ $$ = TYPE_STRING; }
+					;
+
+block				: '{' decl_list state_list '}'		{ $$ = new CStateBlock($2, $3); }
+					;
+
+decl_list			:									{ $$ = NULL }
+					| decls								{ $$ = $1 }
+					;
+
+state_list			:									{ $$ = NULL }
+					| states							{ $$ = $1 }
+					;
+
+decls				: type value_list ';'				{ $$ = new CDeclList(new CDecl($1, $2)); }
+					| decls type value_list ';'			{ $$ = $1->Add(new CDecl($2, $3)); }
+					;
+
+states				: statement							{ $$ = new CStateList($1); }
+					| states statement					{ $$ = $1->Add($2); }
+					;
+
+statement			: ';'											{ $$ = new CNopStatement(@1); }
+					| assign ';'									{ $$ = new CAssignStatement(@1, $1); }
+					| "identifier" '(' args ')' ';'					{ $$ = new CFunctionStatement(@1, $1, $3); }
+					| "identifier" '(' ')' ';'						{ $$ = new CFunctionStatement(@1, $1, NULL); }
+					| "case" expr ':'								{ $$ = new CCaseStatement(@1, $2); }
+					| "default" ':'									{ $$ = new CDefaultStatement(@1); }
+					| "break" ';'									{ $$ = new CBreakStatement(@1); }
+					| "return" ';'									{ $$ = new CReturnStatement(@1, NULL); }
+					| "return" expr ';'								{ $$ = new CReturnStatement(@1, $2); }
+					| "if" '(' expr ')' statement					{ $$ = new CIfStatement(@1, $3, $5); }
+					| "if" '(' expr ')' statement "else" statement	{ $$ = new CIfStatement(@1, $3, $5, $7); }
+					| "for" '(' assign ';' expr ';' assign ')' statement
+																	{ $$ = new CForStatement(@1, $3, $5, $7, $9); }
+					| "while" '(' expr ')' statement				{ $$ = new CWhileStatement(@1, $3, $5); }
+					| "switch" '(' expr ')' '{' state_list '}'		{ $$ = new CSwitchStatement(@1, $3, $6); }
+					| block											{ $$ = new CBlockStatement(@1, $1); }
+					;
+
+assign				: value '=' expr				{ $$ = new CAssign(@1, '=', $1, $3); }
+					| value "+=" expr				{ $$ = new CAssign(@1, '+', $1, $3); }
+					| value "-=" expr				{ $$ = new CAssign(@1, '-', $1, $3); }
+					| value "*=" expr				{ $$ = new CAssign(@1, '*', $1, $3); }
+					| value "/=" expr				{ $$ = new CAssign(@1, '/', $1, $3); }
+					| value "%=" expr				{ $$ = new CAssign(@1, '%', $1, $3); }
+					;
+
+expr				: expr "&&" expr				{ $$ = CNode::MakeNode(driver, @2, OP_LOGAND, $1, $3); }
+					| expr "||" expr				{ $$ = CNode::MakeNode(driver, @2, OP_LOGOR, $1, $3); }
+					| expr "==" expr				{ $$ = CNode::MakeNode(driver, @2, OP_EQ, $1, $3); }
+					| expr "!=" expr				{ $$ = CNode::MakeNode(driver, @2, OP_NE, $1, $3); }
+					| expr '>'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_GT, $1, $3); }
+					| expr ">=" expr				{ $$ = CNode::MakeNode(driver, @2, OP_GE, $1, $3); }
+					| expr '<'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_LT, $1, $3); }
+					| expr "<=" expr				{ $$ = CNode::MakeNode(driver, @2, OP_LE, $1, $3); }
+					| expr '&'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_AND, $1, $3); }
+					| expr '|'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_OR, $1, $3); }
+					| expr "<<" expr				{ $$ = CNode::MakeNode(driver, @2, OP_LSHIFT, $1, $3); }
+					| expr ">>" expr				{ $$ = CNode::MakeNode(driver, @2, OP_RSHIFT, $1, $3); }
+					| expr '-'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_MINUS, $1, $3); }
+					| expr '+'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_PLUS, $1, $3); }
+					| expr '*'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_TIMES, $1, $3); }
+					| expr '/'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_DIVIDE, $1, $3); }
+					| expr '%'  expr				{ $$ = CNode::MakeNode(driver, @2, OP_MOD, $1, $3); }
+					| '-' expr %prec NEG			{ $$ = CNode::MakeNode(driver, @2, OP_NEG, $2); }
+					| '(' expr ')'					{ $$ = $2; }
+					| value							{ $$ = $1; }
+					| "ival"						{ $$ = new CNode(@1, OP_CONST, $1); }
+					| "sval"						{ $$ = new CNode(@1, OP_STRING, $1); }
+					| "identifier" '(' args ')'		{ $$ = new CFunctionNode(@1, $1, $3); }
+					| "identifier" '(' ')'			{ $$ = new CFunctionNode(@1, $1, NULL); }
+					;
+
+value				: "identifier"					{ $$ = new CValueNode(@1, $1); }
+					| "identifier" '[' expr ']'		{ $$ = new CValueNode(@1, $1, $3); }
+					;
+
+args				: expr							{ $$ = new CArgs($1); }
+					| args ',' expr					{ $$ = $1->Add($3); }
+					;
+
+%%
+void yy::script_parser::error(const yy::script_parser::location_type& l, const std::string& m)
+{
+	driver.error(l, m);
+}