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

📄 slparse.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	       }	  }	append_token_of_type (CBRACE_TOKEN);	append_token_of_type (OBRACE_TOKEN);	if (CPAREN_TOKEN != get_token (ctok))	  {	     expression (ctok);	     if (ctok->type != CPAREN_TOKEN)	       {		  _SLparse_error("Expecting ).", ctok, 0);		  break;	       }	  }	append_token_of_type (CBRACE_TOKEN);	compile_token_list ();	get_token (ctok);	block (ctok);	compile_token_of_type (FOR_TOKEN);	break;      case ERRBLK_TOKEN:      case EXITBLK_TOKEN:      case USRBLK0_TOKEN:      case USRBLK1_TOKEN:      case USRBLK2_TOKEN:      case USRBLK3_TOKEN:      case USRBLK4_TOKEN:      case FOREVER_TOKEN:	type = ctok->type;	get_token (ctok);	block (ctok);	compile_token_of_type (type);	break;      case BREAK_TOKEN:      case CONT_TOKEN:	compile_token_of_type (ctok->type);	get_token (ctok);	handle_semicolon (ctok);	break;      case RETURN_TOKEN:	if (SEMICOLON_TOKEN != get_token (ctok))	  {	     if (NULL == push_token_list ())	       break;	     expression (ctok);	     if (ctok->type != SEMICOLON_TOKEN)	       {		  _SLparse_error ("Expecting ;", ctok, 0);		  break;	       }	     compile_token_list ();	  }	compile_token_of_type (RETURN_TOKEN);	handle_semicolon (ctok);	break;      case STATIC_TOKEN:      case PRIVATE_TOKEN:      case PUBLIC_TOKEN:	type = ctok->type;	get_token (ctok);	if (ctok->type == VARIABLE_TOKEN)	  {	     get_token (ctok);	     variable_list (ctok, type);	     handle_semicolon (ctok);	     break;	  }	if (ctok->type == DEFINE_TOKEN)	  {	     define_function (ctok, type);	     break;	  }	_SLparse_error ("Expecting 'variable' or 'define'", ctok, 0);	break;      case VARIABLE_TOKEN:	get_token (ctok);	variable_list (ctok, OBRACKET_TOKEN);	handle_semicolon (ctok);	break;      case TYPEDEF_TOKEN:	get_token (ctok);	if (NULL == push_token_list ())	  break;	typedef_definition (ctok);	compile_token_list ();	handle_semicolon (ctok);	break;      case DEFINE_TOKEN:	define_function (ctok, DEFINE_TOKEN);	break;      case SWITCH_TOKEN:	get_token (ctok);	expression_with_parenthesis (ctok);	while ((SLang_Error == 0)	       && (OBRACE_TOKEN == ctok->type))	  {	     compile_token_of_type (OBRACE_TOKEN);	     compound_statement (ctok);	     compile_token_of_type (CBRACE_TOKEN);	     get_token (ctok);	  }	compile_token_of_type (SWITCH_TOKEN);	unget_token (ctok);	break;      case EOF_TOKEN:	break;#if 0      case PUSH_TOKEN:	get_token (ctok);	expression_list_with_parenthesis (ctok);	handle_semicolon (ctok);	break;#endif      case SEMICOLON_TOKEN:	handle_semicolon (ctok);	break;      case RPN_TOKEN:	if (POUND_TOKEN == get_token (ctok))	  _SLcompile_byte_compiled ();	else if (ctok->type != EOF_TOKEN)	  rpn_parse_line (ctok);	break;      case OPAREN_TOKEN:	       /* multiple assignment */	try_multiple_assignment (ctok);	if (ctok->type == COLON_TOKEN)	  compile_token_of_type (COLON_TOKEN);	else handle_semicolon (ctok);	break;      default:	if (NULL == push_token_list ())	  break;	expression (ctok);	compile_token_list ();	if (ctok->type == COLON_TOKEN)	  compile_token_of_type (COLON_TOKEN);	else handle_semicolon (ctok);	break;     }   LLT->parse_level -= 1;}static void block (_SLang_Token_Type *ctok){   compile_token_of_type (OBRACE_TOKEN);   statement (ctok);   compile_token_of_type (CBRACE_TOKEN);}/* * statement-list: *	 statement *	 statement-list statement */static void statement_list (_SLang_Token_Type *ctok){   while ((SLang_Error == 0)	  && (ctok->type != CBRACE_TOKEN)	  && (ctok->type != EOF_TOKEN))     {	statement(ctok);	get_token (ctok);     }}/* compound-statement: *	 { statement-list } */static void compound_statement (_SLang_Token_Type *ctok){   /* ctok->type is OBRACE_TOKEN here */   get_token (ctok);   statement_list(ctok);   if (CBRACE_TOKEN != ctok->type)     {	_SLparse_error ("Expecting '}'", ctok, 0);	return;     }}/* This function is only called from statement. */static void expression_with_parenthesis (_SLang_Token_Type *ctok){   if (ctok->type != OPAREN_TOKEN)     {	_SLparse_error("Expecting (", ctok, 0);	return;     }   if (NULL == push_token_list ())     return;   get_token (ctok);   expression (ctok);   if (ctok->type != CPAREN_TOKEN)     _SLparse_error("Expecting )", ctok, 0);   compile_token_list ();   get_token (ctok);}static void handle_semicolon (_SLang_Token_Type *ctok){   if ((ctok->type == SEMICOLON_TOKEN)       || (ctok->type == EOF_TOKEN))     return;   _SLparse_error ("Expecting ;", ctok, 0);}void _SLparse_start (SLang_Load_Type *llt){   _SLang_Token_Type ctok;   SLang_Load_Type *save_llt;   unsigned int save_use_next_token;   _SLang_Token_Type save_next_token;   Token_List_Type *save_list;#if _SLANG_HAS_DEBUG_CODE   int save_last_line_number = Last_Line_Number;   Last_Line_Number = -1;#endif   save_use_next_token = Use_Next_Token;   save_next_token = Next_Token;   save_list = Token_List;   save_llt = LLT;   LLT = llt;   init_token (&Next_Token);   Use_Next_Token = 0;   init_token (&ctok);   get_token (&ctok);   llt->parse_level = 0;   statement_list (&ctok);   if ((SLang_Error == 0)       && (ctok.type != EOF_TOKEN))     _SLparse_error ("Parse ended prematurely", &ctok, 0);      if (SLang_Error)     {	if (SLang_Error < 0)	       /* severe error */	  save_list = NULL;	while (Token_List != save_list)	  {	     if (-1 == pop_token_list (1))	       break;		       /* ??? when would this happen? */	  }     }   free_token (&ctok);   LLT = save_llt;   if (Use_Next_Token)     free_token (&Next_Token);   Use_Next_Token = save_use_next_token;   Next_Token = save_next_token;#if _SLANG_HAS_DEBUG_CODE   Last_Line_Number = save_last_line_number;#endif}/* variable-list: * 	variable-decl * 	variable-decl variable-list * * variable-decl: * 	identifier * 	identifier = simple-expression */static void variable_list (_SLang_Token_Type *name_token, unsigned char variable_type){   int declaring;   _SLang_Token_Type tok;   if (name_token->type != IDENT_TOKEN)     {	_SLparse_error ("Expecting a variable name", name_token, 0);	return;     }   declaring = 0;   do     {	if (declaring == 0)	  {	     declaring = 1;	     compile_token_of_type (variable_type);	  }	compile_token (name_token);	init_token (&tok);	if (ASSIGN_TOKEN == get_token (&tok))	  {	     compile_token_of_type (CBRACKET_TOKEN);	     declaring = 0;	     get_token (&tok);	     push_token_list ();	     simple_expression (&tok);	     compile_token_list ();	     name_token->type = _SCALAR_ASSIGN_TOKEN;	     compile_token (name_token);	  }	free_token (name_token);	*name_token = tok;     }   while ((name_token->type == COMMA_TOKEN)	  && (IDENT_TOKEN == get_token (name_token)));   if (declaring) compile_token_of_type (CBRACKET_TOKEN);}/* struct-declaration: * 	struct { struct-field-list }; * * struct-field-list: * 	struct-field-name , struct-field-list * 	struct-field-name * * Generates code: "field-name-1" ... "field-name-N" N STRUCT_TOKEN */static void struct_declaration (_SLang_Token_Type *ctok){   int n;   _SLang_Token_Type num_tok;   if (ctok->type != OBRACE_TOKEN)     {	_SLparse_error ("Expecting {", ctok, 0);	return;     }   n = 0;   while (IDENT_TOKEN == get_token (ctok))     {	n++;	ctok->type = STRING_TOKEN;	append_token (ctok);	if (COMMA_TOKEN != get_token (ctok))	  break;     }   if (ctok->type != CBRACE_TOKEN)     {	_SLparse_error ("Expecting }", ctok, 0);	return;     }   if (n == 0)     {	_SLparse_error ("struct requires at least 1 field", ctok, 0);	return;     }   init_token (&num_tok);   num_tok.type = INT_TOKEN;   num_tok.v.long_val = n;   append_token (&num_tok);   append_token_of_type (STRUCT_TOKEN);   get_token (ctok);}/* struct-declaration: * 	typedef struct { struct-field-list } Type_Name; * * struct-field-list: * 	struct-field-name , struct-field-list * 	struct-field-name * * Generates code: "field-name-1" ... "field-name-N" N STRUCT_TOKEN typedef */static void typedef_definition (_SLang_Token_Type *t){   if (t->type != STRUCT_TOKEN)     {	_SLparse_error ("Expecting `struct'", t, 0);	return;     }   get_token (t);   struct_declaration (t);   if (t->type != IDENT_TOKEN)     {	_SLparse_error ("Expecting identifier", t, 0);	return;     }   t->type = STRING_TOKEN;   append_token (t);   append_token_of_type (TYPEDEF_TOKEN);   get_token (t);}/* function-args: * 	( args-dec-opt ) * * args-decl-opt: * 	identifier * 	args-decl , identifier */static void define_function_args (_SLang_Token_Type *ctok){   if (CPAREN_TOKEN == get_token (ctok))     {	get_token (ctok);	return;     }   compile_token_of_type(OBRACKET_TOKEN);   while ((SLang_Error == 0)	  && (ctok->type == IDENT_TOKEN))     {	compile_token (ctok);	if (COMMA_TOKEN != get_token (ctok))	  break;	get_token (ctok);     }   if (CPAREN_TOKEN != ctok->type)     {	_SLparse_error("Expecting )", ctok, 0);	return;     }   compile_token_of_type(CBRACKET_TOKEN);   get_token (ctok);}void try_multiple_assignment (_SLang_Token_Type *ctok){   /* This is called with ctok->type == OPAREN_TOKEN.  We have no idea    * what follows this.  There are various possibilities such as:    * @  () = x;    * @  ( expression ) = x;    * @  ( expression ) ;    * @  ( expression ) OP expression;    * @  ( expression ) [expression] = expression;    * and only the first two constitute a multiple assignment.  The last    * two forms create the difficulty.    *    * Here is the plan.  First parse (expression) and then check next token.    * If it is an equal operator, then it will be parsed as a multiple    * assignment.  In fact, that is the easy part.    *    * The hard part stems from the fact that by parsing (expression), we    * have effectly truncated the parse if (expression) is part of a binary    * or unary expression.  Somehow, the parsing must be resumed.  The trick    * here is to use a dummy literal that generates no code: NO_OP_LITERAL    * Using it, we just call 'expression' and proceed.    */   if (NULL == push_token_list ())     return;   get_token (ctok);   if (ctok->type != CPAREN_TOKEN)     {	expression_with_commas (ctok, 1);	if (ctok->type != CPAREN_TOKEN)	  {	     _SLparse_error ("Expecting )", ctok, 0);	     return;	  }     }   switch (get_token (ctok))     {      case ASSIGN_TOKEN:      case PLUSEQS_TOKEN:      case MINUSEQS_TOKEN:      case TIMESEQS_TOKEN:      case DIVEQS_TOKEN:      case BOREQS_TOKEN:      case BANDEQS_TOKEN:	do_multiple_assignment (ctok);	pop_token_list (1);	break;      default:	unget_token (ctok);	ctok->type = NO_OP_LITERAL;	expression (ctok);	compile_token_list ();	break;     }}/* Note:  expression never gets compiled directly.  Rather, it gets *        appended to the token list and then compiled by a calling *        routine. *//* expression: *	 simple_expression *	 simple-expression , expression *       <none> */static void expression_with_commas (_SLang_Token_Type *ctok, int save_comma){   while (SLang_Error == 0)     {	if (ctok->type != COMMA_TOKEN)	  {	     if (ctok->type == CPAREN_TOKEN)	       return;	     simple_expression (ctok);	     if (ctok->type != COMMA_TOKEN)	       break;	  }	if (save_comma) append_token (ctok);	get_token (ctok);     }}static void expression (_SLang_Token_Type *ctok){   expression_with_commas (ctok, 0);}/* priority levels of binary operations */static unsigned char Binop_Level[] ={/* ADD_TOKEN */		2,/* SUB_TOKEN */		2,/* MUL_TOKEN */		1,/* DIV_TOKEN */		1,/* LT_TOKEN */		4,/* LE_TOKEN */		4,/* GT_TOKEN */		4,/* GE_TOKEN */		4,/* EQ_TOKEN */		5,/* NE_TOKEN */		5,/* AND_TOKEN */		9,/* OR_TOKEN */		10,/* MOD_TOKEN */		1,/* BAND_TOKEN */	6,/* SHL_TOKEN */		3,/* SHR_TOKEN */		3,/* BXOR_TOKEN */	7,/* BOR_TOKEN */		8,/* POUND_TOKEN */	1  /* Matrix Multiplication */};/* % Note: simple-expression groups operators OP1 at same level.  The * % actual implementation will not do this. * simple-expression: *	 unary-expression *	 binary-expression BINARY-OP unary-expression *       andelse xxelse-expression-list *       orelse xxelse-expression-list * * xxelse-expression-list: * 	{ expression } * 	xxelse-expression-list { expression } * binary-expression: *      unary-expression *      unary-expression BINARY-OP binary-expression */static void simple_expression (_SLang_Token_Type *ctok){   unsigned char type;   unsigned char op_stack [64];   unsigned char level_stack [64];   unsigned char level;   unsigned int op_num;   switch (ctok->type)     {      case ANDELSE_TOKEN:      case ORELSE_TOKEN:	type = ctok->type;	if (OBRACE_TOKEN != get_token (ctok))	  {	     _SLparse_error ("Expecting '{'", ctok, 0);	     return;	  }	while (ctok->type == OBRACE_TOKEN)	  {	     append_token (ctok);	     get_token (ctok);	     expression (ctok);	     if (CBRACE_TOKEN != ctok->type)	       {		  _SLparse_error("Expecting }", ctok, 0);		  return;	       }	     append_token (ctok);	     get_token (ctok);	  }	append_token_of_type (type);	return;	/* avoid unary-expression if possible */      case STRING_TOKEN:	append_token (ctok);	get_token (ctok);	break;      default:	unary_expression (ctok);	break;     }   if (SEMICOLON_TOKEN == (type = ctok->type))     return;   op_num = 0;   while ((SLang_Error == 0)	  && (IS_BINARY_OP(type)))     {	level = Binop_Level[type - FIRST_BINARY_OP];	while ((op_num > 0) && (level_stack [op_num - 1] <= level))	  append_token_of_type (op_stack [--op_num]);	if (op_num >= sizeof (op_stack) - 1)	  {

⌨️ 快捷键说明

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