⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.y

📁 UC Library Extensions UnderC comes with a pocket implementation of the standard C++ libraries, wh
💻 Y
📖 第 1 页 / 共 2 页
字号:
/* PARSER.Y * C++ Grammar * UnderC C++ interpreter * Steve Donovan, 2001 * This is GPL'd software, and the usual disclaimers apply. * See LICENCE*/%{/* *SJD* essential prototypes for C++ compilation */int yylex();int yyerror(const char *s);#include <stdlib.h>#define xmalloc malloc#define MSDOS#include "common.h"using namespace Parser;using namespace Expressions;#define YYERROR_VERBOSE 1#define YYDEBUG 1//#define YYPURE /* some shortcuts */typedef Stack<bool,40> BoolStack;BoolStack als(false);BoolStack dcl_stack;BoolStack typedef_stack;bool dump_it = false;PEntry last_type_entry;PExpr gFunInit = NULL;  // used to flag pure virtual methods...void dcl_set(bool yes, bool comma_flag) { dcl_stack.push(state.in_declaration); if (dcl_stack.depth() > 40) outln("runaway dcl stack"); state.in_declaration = yes; als.push(comma_flag);  /* force ',' _not_ to be COMMA */}void dcl_reset() {  state.in_declaration = dcl_stack.pop(); als.pop();}void force_comma_flag() {  als.clear(); dcl_stack.clear(); dcl_set(false,false);}bool in_arg_list()   { return als.TOS();}inline void enter_arglist() { dcl_set(false); }void leave_arglist() { dcl_reset(); }string tag_name; /* A fiddle */bool IEF=false;/*BoolStack ief_stack;*/void IEF_set()   { /*ief_stack.push(IEF);*/ IEF=true; }void IEF_reset() { IEF=false; /*ief_stack.pop();*/ } void ttpush(TType t) { tpush(AsType(t)); }void raise_error(string msg) { int yyerror(const char *); if (state.err != "") { msg = state.err; state.err = ""; } state.reset(); als.clear(); als.push(false);  yyerror(msg.c_str());}bool check_error(){ if (state.err != "") {    raise_error(state.err);	state.err = "";	return true; } return false;}%}%union{  int    val;   long   ctype;  char*  str;  Entry* entry;  Expr*  expression;  ExprList *elist;  Class *classptr;  TypeList *typelist;}%token <str>   TOKEN%token <entry> IDEN,CONSTANT,TYPENAME,TYPENAME_FUNCTION,TEMPLATE_NAME, TEMPLATE_NAME_EXPR,%token <classptr> THIS_CLASSNAME%token FLOAT,DOUBLE,UNSIGNED,INT,SHORT,LONG,CHAR,VOID,BOOL%token TYPEDEF,CLASS,STRUCT,ENUM,OPERATOR,GOTO,UNION%token <val> STATIC_CAST,CONST_CAST,DYNAMIC_CAST,REINTERPRET_CAST, STRUCT_X, CLASS_X, STRUCT_Y, CLASS_Y, UNION_Y%token IF,ELSE,WHILE,DO,FOR,SWITCH,CASE,RETURN,CONTINUE,BREAK,OPERATOR,DEFAULT%token NAMESPACE,USING,TRY,CATCH,THROW,TEMPLATE,EXTERN%token THREEDOT, TYPEOF, EXPLICIT, FRIEND, LAMBDA, FAKE_INIT_LIST%token <val> CONST,STATIC,STDCALL,API,VIRTUAL,PRIVATE,PROTECTED,PUBLIC,CLASS,STRUCT,UNION/* C++ operators, in increasing order of precedence */%left COMMA%right <val> ASSIGN,MUL_A,DIV_A,MOD_A,ADD_A,MINUS_A,SHL_A,SHR_A,BAND_A,BOR_A,XOR_A%left ARITH_IF%left LOG_OR%left LOG_AND%left BIN_OR%left BIN_XOR%left BIN_AND%left EQUAL, NOT_EQUAL%left LESS_THAN, LEQ, GREATER, GEQ%left LSHIFT,RSHIFT%left PLUS,MINUS%left STAR,DIVIDE,MODULO%left MEMBER_ARROW, MEMBER_DOT%right NEW,DELETE,TYPECAST,DEREF,ADDR,UPLUS,UMINUS,LOG_NOT,BIN_NOT,INCR,DECR,SIZEOF%left TYPE_CONSTRUCT,FUN_CALL,ARRAY,ARROW,DOT%left  BINARY_SCOPE%right UNARY_SCOPE%type <val> assign_op, poss_array%type <ctype> tname_expr, tname_exp2, token, type_expr, type_expression,type_bracket,function_front%type <ctype> typename_function, typename_class, typename_expr, template_class, template_expr, templ_item%type <ctype> conversion_operator, class_parm, scope, pointer_expr%type <val> poss_unsigned, poss_int,poss_const,typecast_type%type <val> access_modifier,poss_access_modifier,class_or_struct,poss_derived, template_class_header, struct_or_class_x,%type <val> class_or_struct_ex%type <str> poss_tag, class_name, poss_class_name, class_id, class_item, template_class_name, token_or_typename/* these should be 'expression'!! */%type <expression> _expr,expr,poss_int_const,poss_initialization,poss_size,condition,poss_expr,brace_item%type <expression> array_expr%type <entry> scoped_name%type <elist> expr_list,function_arg_list,poss_function_arg_list,init_list,brace_list, brace_expr%type <classptr> this_classname%type <typelist> template_type_list, templ_item_list%%program: statement_list ;statement_list: /*empty*/ |  statement                {statement_end();} | statement_list statement  {statement_end();};block: '{'  { state.init_block(PLAIN_BLOCK); IEF_set(); }  statement_list  '}' { state.finalize_block(); IEF_reset();} ;statement: ';' /* empty statement */   | block  | declaration           | function_declaration  | function_definition   | friend_declaration  | expr ';'             {expression_end($1);}  | typedef_stmt  | access_specifier  | if_stmt  | if_else_stmt  | while_stmt  | do_stmt  | for_stmt  | switch_stmt  | return_stmt  | case_label  | break_stmt  | continue_stmt  | goto_stmt  | goto_label  | template_class_declaration  | template_function_declaration  | try_catch_stmt  | throw_stmt  | namespace_declaration  | using_directive  | using_declaration  | extern_c_declaration  | error ';'   { raise_error("Error in statement"); YYABORT; };declaration:  mod_type_name tname_expr_list ';'    {     Type dt = tpop();	dcl_reset();	state.check_dcl_init(dt); };typedef_stmt:  TYPEDEF  { state.in_typedef = true; }   declaration_stmt  { state.in_typedef = false; };declaration_stmt:  declaration| function_declaration; /* constructor/destructors */this_classname:  THIS_CLASSNAME   {   dcl_set();   state.token_stack.push($1->constructor_name());   tpush(t_void);   state.in_construct_destruct = IsConstructor;   $$ = $1;  };construct_destruct:  this_classname {}       | BIN_NOT this_classname   {  state.token_stack.TOS() = $2->destructor_name();  state.in_construct_destruct = IsDestructor;};conversion_operator: OPERATOR  mod_type_name tname_exp2 arg_list {    state.token_stack.push(CONVERSION_OPNAME);   ttpush($3); $$ = $3;  };function_front:  mod_type_name tname_expr arg_list poss_const poss_initialization  { $$=$2; stots($$); state.member_is_const = $4; gFunInit = $5; };explicit_mod: EXPLICIT { state.modifier = Explicit; };ctor_dtor_dcl: construct_destruct arg_list ';'    {     state.declare_function(t_void,state.token_stack.pop());   tpop();   check_error(); };function_declaration: function_front ';'   {   state.declare_function(AsType($1),state.token_stack.pop(), gFunInit);    dcl_reset();   gFunInit = NULL;   tpop();   check_error(); }| ctor_dtor_dcl| explicit_mod ctor_dtor_dcl| conversion_operator ';'  {     state.declare_function(AsType($1),state.token_stack.pop());	tpop();	check_error();  };/***** extern "C" ******//* *fix 1.1.4  *   - plain 'extern' is no longer confused with 'extern "C"'! *   - 'extern "C"' no longer has to be followed by a block*/extern_c_declaration:   extern_qualifier any_declaration            { state.extern_flag = false; }| extern_c '{' statement_list '}'             { state.extern_flag_C = false; }| extern_c any_declaration                    { state.extern_flag_C = false; };any_declaration:  function_declaration| declaration;extern_c:   EXTERN CONSTANT { state.extern_flag_C = true; };extern_qualifier:   EXTERN          { state.extern_flag = true; };/***********************Function definitions ***/function_definition:  function_front block  { }| ctor_dtor{}| explicit_mod ctor_dtor{}| conversion_operator block{};ctor_dtor:   construct_destruct arg_list poss_class_init_list block;/* w/ constructors and init lists, we construct the function first   (before the init list) and then initialize the function */poss_class_init_list: /*EMPTY*/ | ':'     {   state.init_block(CONSTRUCTOR_BLOCK);  }   class_init_list    {  check_error(); state.in_method = true; };/*add 1.2.7 Fake syntax __init_list__ used to fool parser when grabbing init list + body */class_init_list:   FAKE_INIT_LIST|   class_init_item|  class_init_item COMMA class_init_list;class_init_item:  typename_function function_arg_list    { 	 ((Class*)state.context().parent_context())	    ->add_class_init_list(AsType($1).as_class()->entry(),$2);	/* fix 1.2.3a Can crash UC if we don't catch errors in the init list */	 if (check_error()) YYABORT;  	}|  IDEN function_arg_list    { ((Class*)state.context().parent_context())	      ->add_class_init_list($1,$2);	 if (check_error()) YYABORT;    };/***********************General type expressions***/type_expr: mod_type_name tname_expr { $$ = $2;  };poss_const: /*EMPTY*/ { $$=0; } | CONST { $$=1; };mod_type_name:  type_name                      {dcl_set();}| modifiers type_name            {dcl_set();}| CONST type_name                {dcl_set(); tots().make_const();} | modifiers CONST type_name      {dcl_set(); tots().make_const();};modifiers:    STATIC  {state.modifier = Static;  } | VIRTUAL {state.modifier = Virtual; } | STDCALL {state.modifier = Stdcall; } | API     {state.modifier = Api;     };open_parens:  '(' {dcl_set(false);};close_parens: ')' {dcl_reset();};type_name: typename_class                 { ttpush($1);  }   | TYPEOF open_parens expr close_parens   { tpush(typeof_op($3)); } | integer                                { }  | UNSIGNED integer                       { tots().make_unsigned(); } | UNSIGNED                               { tpush(t_int); tots().make_unsigned(); } | FLOAT                                  { tpush(t_float);  } | DOUBLE                                 { tpush(t_double); } | BOOL                                   { tpush(t_bool); }  | VOID                                   { tpush(t_void); } | class_declaration                      { } | enum_stmt                              { };poss_unsigned: /*empty*/  { $$=0; }   | UNSIGNED            { $$=1; };poss_int: /*empty*/       { $$=0; }   | INT                 { $$=1; };integer: INT         { tpush(t_int);   }  | SHORT            { tpush(t_short); }   | LONG             { tpush(t_long);  } /*  | SHORT  INT       { tpush(t_short); }   | LONG   INT       { tpush(t_long);  } */  | CHAR             { tpush(t_char);  };pointer_expr:'(' STAR token ')' { $$ = incr_ptr($3); };array_expr:   '[' {dcl_set(false);}	 poss_int_const	']' %prec ARRAY  { dcl_reset(); $$ = $3; };tname_expr:  /*empty*/          { $$=ttots(); state.token_stack.push(""); }  | token                       { $$=$1;   }  | pointer_expr arg_list       { Type t = AsType($1); t.decr_pointer(); $$ = AsTType(state.signature_type(t));     }  | '(' scope STAR token ')' end_scope  arg_list                                 /* fix 1.2.3a Set the class type for this method ptr declaration first */                                { state.class_dcl = AsType($2); $$ = AsTType(state.signature_type(AsType($4)));  }   | STAR poss_const tname_expr  { $$ = incr_ptr($3);         }  | ADDR  tname_expr            { $$ = make_ref($2);         }  | scope token end_scope       { $$ = $2;   state.class_dcl = AsType($1); }  | scope conversion_operator    end_scope                   { $$ = $2;   state.class_dcl = AsType($1); }  | tname_expr array_expr       { $$ = make_array($1,$2); check_error();   }  | pointer_expr array_expr     { $$ = make_array($1,$2); check_error();   }   | error { raise_error("Error in type expression"); YYABORT; };/* conversion_operator requires special consideration! */tname_exp2:  /*empty*/    { $$ = ttots(); }  |  STAR tname_exp2      { $$ = incr_ptr($2); }  |  ADDR tname_exp2      { $$ = make_ref($2); };token: TOKEN { $$=ttots(); state.token_stack.push($1); };/**** Function prototype lists *******/begin_list: '(' { dcl_set(false); state.begin_args(); };end_list: ')' { dcl_reset(); };arg_list:  begin_list type_list end_list /*%prec FUN_CALL     */;type_list: /*empty*/ | type_expr_init                  | type_expr_init ',' type_list   | THREEDOT {    state.add_to_arg_list(t_void,"...",0); };  type_expr_init:  type_expr poss_initialization{    state.add_to_arg_list(AsType($1),state.token_stack.pop(),$2);  tpop();  dcl_reset();};/**** Declarative item ******/init_tname_expr: tname_expr poss_initialization  {  string name = state.token_stack.pop();  Type t = AsType($1);  temp_context()->reserved_space(t.size());  state.add_variable(t,name,$2,state.modifier);  if (check_error()) YYABORT;  }  ;tname_expr_list: /*empty*/ | init_tname_expr | init_tname_expr ',' tname_expr_list ;poss_int_const: /*empty*/ { $$=NULL; } | expr {$$=$1;}/* Initializations occur in a declarative context, so it's * important that they reset/set this state properly  */init_assign: ASSIGN { dcl_set(false); };poss_initialization: /*empty*/               { $$=NULL; }  | init_assign    expr  { dcl_reset(); $$=$2; }  | init_list  { $$=expr_list_op($1,true); }  | init_assign '{'    { enter_arglist();}     brace_list '}'      {leave_arglist(); dcl_reset(); $$=expr_list_op($4,false); }   | ':' CONSTANT  { $$ = new Expr(ECONST,t_void,$2,NULL); };/* ----array initialization------ */brace_expr: '{'  brace_list '}' { $$ = $2; };brace_item: _expr { $$ = $1; }  | brace_expr    { $$ = expr_list_op($1,false); } ;brace_list: brace_item        { $$ = new ExprList; $$->push_back($1);  }  | brace_list ',' brace_item { $$ = $1; $$->push_back($3); } ;/* brace_list: expr_list { $$=$1; }; simplified *//****** CLASSES AND STRUCTS *******//* *change 1.1.4 this is now defined as a part of a declaration, as C intended */access_modifier: PUBLIC      {$$=Public;} | PRIVATE   {$$=Private;}  | PROTECTED {$$=Protected;};poss_access_modifier: /*EMPTY*/ { $$=Default; } | access_modifier;class_or_struct: CLASS | STRUCT | UNION;class_or_struct_ex: CLASS_Y  { $$ = CLASS; }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -