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

📄 slparse.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) 1998, 1999, 2001, 2002, 2003 John E. Davis * This file is part of the S-Lang library. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */#include "slinclud.h"#include "slang.h"#include "_slang.h"static SLang_Load_Type *LLT;int _SLang_Compile_Line_Num_Info;static void free_token (_SLang_Token_Type *t){   register unsigned int nrefs = t->num_refs;   if (nrefs == 0)     return;   if (nrefs == 1)     {	if (t->free_sval_flag)	  {	     if (t->type == BSTRING_TOKEN)	       SLbstring_free (t->v.b_val);	     else	       _SLfree_hashed_string (t->v.s_val, strlen (t->v.s_val), t->hash);	     t->v.s_val = NULL;	  }     }   t->num_refs = nrefs - 1;}static void init_token (_SLang_Token_Type *t){   memset ((char *) t, 0, sizeof (_SLang_Token_Type));#if _SLANG_HAS_DEBUG_CODE   t->line_number = -1;#endif}/* Allow room for one push back of a token.  This is necessary for * multiple assignment. */static unsigned int Use_Next_Token;static _SLang_Token_Type Next_Token;#if _SLANG_HAS_DEBUG_CODEstatic int Last_Line_Number = -1;#endifstatic int unget_token (_SLang_Token_Type *ctok){   if (SLang_Error)     return -1;   if (Use_Next_Token != 0)     {	_SLparse_error ("unget_token failed", ctok, 0);	return -1;     }   Use_Next_Token++;   Next_Token = *ctok;   init_token (ctok);   return 0;}static int get_token (_SLang_Token_Type *ctok){   if (ctok->num_refs)     free_token (ctok);   if (Use_Next_Token)     {	Use_Next_Token--;	*ctok = Next_Token;	return ctok->type;     }   return _SLget_token (ctok);}static int compile_token (_SLang_Token_Type *t){#if _SLANG_HAS_DEBUG_CODE   if (_SLang_Compile_Line_Num_Info       && (t->line_number != Last_Line_Number)       && (t->line_number != -1))     {	_SLang_Token_Type tok;	tok.type = LINE_NUM_TOKEN;	tok.v.long_val = Last_Line_Number = t->line_number;	(*_SLcompile_ptr) (&tok);     }#endif   (*_SLcompile_ptr) (t);   return 0;}typedef struct{#define USE_PARANOID_MAGIC	0#if USE_PARANOID_MAGIC   unsigned long magic;#endif   _SLang_Token_Type *stack;   unsigned int len;   unsigned int size;}Token_List_Type;#define MAX_TOKEN_LISTS 16static Token_List_Type Token_List_Stack [MAX_TOKEN_LISTS];static unsigned int Token_List_Stack_Depth = 0;static Token_List_Type *Token_List = NULL;static void init_token_list (Token_List_Type *t){   t->size = 0;   t->len = 0;   t->stack = NULL;#if USE_PARANOID_MAGIC   t->magic = 0xABCDEF12;#endif}static void free_token_list (Token_List_Type *t){   _SLang_Token_Type *s;   if (t == NULL)     return;#if USE_PARANOID_MAGIC   if (t->magic != 0xABCDEF12)     {	SLang_doerror ("Magic error.");	return;     }#endif   s = t->stack;   if (s != NULL)     {	_SLang_Token_Type *smax = s + t->len;	while (s != smax)	  {	     if (s->num_refs) free_token (s);	     s++;	  }	SLfree ((char *) t->stack);     }   memset ((char *) t, 0, sizeof (Token_List_Type));}static Token_List_Type *push_token_list (void){   if (Token_List_Stack_Depth == MAX_TOKEN_LISTS)     {	_SLparse_error ("Token list stack size exceeded", NULL, 0);	return NULL;     }   Token_List = Token_List_Stack + Token_List_Stack_Depth;   Token_List_Stack_Depth++;   init_token_list (Token_List);   return Token_List;}static int pop_token_list (int do_free){   if (Token_List_Stack_Depth == 0)     {	if (SLang_Error == 0)	  _SLparse_error ("Token list stack underflow", NULL, 0);	return -1;     }   Token_List_Stack_Depth--;   if (do_free) free_token_list (Token_List);   if (Token_List_Stack_Depth != 0)     Token_List = Token_List_Stack + (Token_List_Stack_Depth - 1);   else     Token_List = NULL;   return 0;}static int check_token_list_space (Token_List_Type *t, unsigned int delta_size){   _SLang_Token_Type *st;   unsigned int len;#if USE_PARANOID_MAGIC   if (t->magic != 0xABCDEF12)     {	SLang_doerror ("Magic error.");	return -1;     }#endif   len = t->len + delta_size;   if (len <= t->size) return 0;   if (delta_size < 4)     {	delta_size = 4;	len = t->len + delta_size;     }   st = (_SLang_Token_Type *) SLrealloc((char *) t->stack,					len * sizeof(_SLang_Token_Type));   if (st == NULL)     {	_SLparse_error ("Malloc error", NULL, 0);	return -1;     }   memset ((char *) (st + t->len), 0, delta_size);   t->stack = st;   t->size = len;   return 0;}static int append_token (_SLang_Token_Type *t){   if (-1 == check_token_list_space (Token_List, 1))     return -1;   Token_List->stack [Token_List->len] = *t;   Token_List->len += 1;   t->num_refs = 0;		       /* stealing it */   return 0;}static int append_token_of_type (unsigned char t){   _SLang_Token_Type *tok;   if (-1 == check_token_list_space (Token_List, 1))     return -1;   /* The memset when the list was created ensures that the other fields    * are properly initialized.    */   tok = Token_List->stack + Token_List->len;   init_token (tok);   tok->type = t;   Token_List->len += 1;   return 0;}static _SLang_Token_Type *get_last_token (void){   unsigned int len;   if ((Token_List == NULL)       || (0 == (len = Token_List->len)))     return NULL;   len--;   return Token_List->stack + len;}/* This function does NOT free the list. */static int compile_token_list_with_fun (int dir, Token_List_Type *list,					int (*f)(_SLang_Token_Type *)){   _SLang_Token_Type *t0, *t1;   if (list == NULL)     return -1;   if (f == NULL)     f = compile_token;   t0 = list->stack;   t1 = t0 + list->len;   if (dir < 0)     {	/* backwards */	while ((SLang_Error == 0) && (t1 > t0))	  {	     t1--;	     (*f) (t1);	  }	return 0;     }   /* forward */   while ((SLang_Error == 0) && (t0 < t1))     {	(*f) (t0);	t0++;     }   return 0;}static int compile_token_list (void){   if (Token_List == NULL)     return -1;   compile_token_list_with_fun (1, Token_List, NULL);   pop_token_list (1);   return 0;}/* Take all elements in the list from pos2 to the end and exchange them * with the elements at pos1, e.g., * ...ABCDEabc ==> ...abcABCDE * where pos1 denotes A and pos2 denotes a. */static int token_list_element_exchange (unsigned int pos1, unsigned int pos2){   _SLang_Token_Type *s, *s1, *s2;   unsigned int len, nloops;   if (Token_List == NULL)     return -1;   s = Token_List->stack;   len = Token_List->len;   if ((s == NULL) || (len == 0)       || (pos2 >= len))     return -1;   /* This may not be the most efficient algorithm but the number to swap    * is most-likely going to be small, e.g, 3    * The algorithm is to rotate the list.  The particular rotation    * direction was chosen to make insert_token fast.    * It works like:    * @ ABCabcde --> BCabcdeA --> CabcdeAB -->  abcdefAB    * which is optimal for Abcdef sequence produced by function calls.    *    * Profiling indicates that nloops is almost always 1, whereas the inner    * loop can loop many times (e.g., 9 times).    */   s2 = s + (len - 1);   s1 = s + pos1;   nloops = pos2 - pos1;   while (nloops)     {	_SLang_Token_Type save;	s = s1;	save = *s;	while (s < s2)	  {	     *s = *(s + 1);	     s++;	  }	*s = save;	nloops--;     }   return 0;}#if 0static int insert_token (_SLang_Token_Type *t, unsigned int pos){   if (-1 == append_token (t))     return -1;   return token_list_element_exchange (pos, Token_List->len - 1);}#endifstatic void compile_token_of_type (unsigned char t){   _SLang_Token_Type tok;#if _SLANG_HAS_DEBUG_CODE   tok.line_number = -1;#endif   tok.type = t;   compile_token(&tok);}static void statement (_SLang_Token_Type *);static void compound_statement (_SLang_Token_Type *);static void expression_with_parenthesis (_SLang_Token_Type *);static void handle_semicolon (_SLang_Token_Type *);static void statement_list (_SLang_Token_Type *);static void variable_list (_SLang_Token_Type *, unsigned char);static void struct_declaration (_SLang_Token_Type *);static void define_function_args (_SLang_Token_Type *);static void typedef_definition (_SLang_Token_Type *);static void function_args_expression (_SLang_Token_Type *, int);static void expression (_SLang_Token_Type *);static void expression_with_commas (_SLang_Token_Type *, int);static void simple_expression (_SLang_Token_Type *);static void unary_expression (_SLang_Token_Type *);static void postfix_expression (_SLang_Token_Type *);static int check_for_lvalue (unsigned char, _SLang_Token_Type *);/* static void primary_expression (_SLang_Token_Type *); */static void block (_SLang_Token_Type *);static void inline_array_expression (_SLang_Token_Type *);static void array_index_expression (_SLang_Token_Type *);static void do_multiple_assignment (_SLang_Token_Type *);static void try_multiple_assignment (_SLang_Token_Type *);#if 0static void not_implemented (char *what){   char err [256];   sprintf (err, "Expression not implemented: %s", what);   _SLparse_error (err, NULL, 0);}#endifstatic void rpn_parse_line (_SLang_Token_Type *tok){   do     {	  /* multiple RPN tokens possible when the file looks like:	   * . <end of line>	   * . <end of line>	   */	if (tok->type != RPN_TOKEN)	  compile_token (tok);	free_token (tok);     }   while (EOF_TOKEN != _SLget_rpn_token (tok));}static int get_identifier_token (_SLang_Token_Type *tok){   if (IDENT_TOKEN == get_token (tok))     return IDENT_TOKEN;   _SLparse_error ("Expecting identifier", tok, 0);   return tok->type;}static void define_function (_SLang_Token_Type *ctok, unsigned char type){   _SLang_Token_Type fname;      switch (type)     {      case STATIC_TOKEN:	type = DEFINE_STATIC_TOKEN;	break;	      case PUBLIC_TOKEN:	type = DEFINE_PUBLIC_TOKEN;	break;	      case PRIVATE_TOKEN:	type = DEFINE_PRIVATE_TOKEN;     }   init_token (&fname);   if (IDENT_TOKEN != get_identifier_token (&fname))     {	free_token (&fname);	return;     }   compile_token_of_type(OPAREN_TOKEN);   get_token (ctok);   define_function_args (ctok);   compile_token_of_type(FARG_TOKEN);   if (ctok->type == OBRACE_TOKEN)     compound_statement(ctok);   else if (ctok->type != SEMICOLON_TOKEN)     {	_SLparse_error("Expecting {", ctok, 0);	free_token (&fname);	return;     }   fname.type = type;   compile_token (&fname);   free_token (&fname);}/* statement: *	 compound-statement *	 if ( expression ) statement *	 if ( expression ) statement else statement *	 !if ( expression ) statement *	 loop ( expression ) statement *	 _for ( expression ) statement *       foreach ( expression ) statement *       foreach (expression ) using (expression-list) statement *	 while ( expression ) statement *	 do statement while (expression) ; *	 for ( expressionopt ; expressionopt ; expressionopt ) statement *	 ERROR_BLOCK statement *	 EXIT_BLOCK statement *	 USER_BLOCK0 statement *	 USER_BLOCK1 statement *	 USER_BLOCK2 statement *	 USER_BLOCK3 statement *	 USER_BLOCK4 statement *	 forever statement *	 break ; *	 continue ; *	 return expressionopt ; *	 variable variable-list ; *	 struct struct-decl ; *	 define identifier function-args ; *	 define identifier function-args compound-statement *	 switch ( expression ) statement *	 rpn-line *	 at-line *	 push ( expression ) *	 ( expression ) = expression ; *	 expression ; *       expression : *//* Note: This function does not return with a new token.  It is up to the * calling routine to handle that. */static void statement (_SLang_Token_Type *ctok){   unsigned char type;   if (SLang_Error)     return;   LLT->parse_level += 1;   switch (ctok->type)     {      case OBRACE_TOKEN:	compound_statement (ctok);	break;      case IF_TOKEN:      case IFNOT_TOKEN:	type = ctok->type;	get_token (ctok);	expression_with_parenthesis (ctok);	block (ctok);	if (ELSE_TOKEN != get_token (ctok))	  {	     compile_token_of_type (type);	     unget_token (ctok);	     break;	  }	get_token (ctok);	block (ctok);	if (type == IF_TOKEN) type = ELSE_TOKEN; else type = NOTELSE_TOKEN;	compile_token_of_type (type);	break;      /* case IFNOT_TOKEN: */      case LOOP_TOKEN:      case _FOR_TOKEN:	type = ctok->type;	get_token (ctok);	expression_with_parenthesis (ctok);	block (ctok);	compile_token_of_type (type);	break;      case FOREACH_TOKEN:	get_token (ctok);	expression_with_parenthesis (ctok);	if (NULL == push_token_list ())	  break;	append_token_of_type (ARG_TOKEN);	if (ctok->type == USING_TOKEN)	  {	     if (OPAREN_TOKEN != get_token (ctok))	       {		  _SLparse_error ("Expected 'using ('", ctok, 0);		  break;	       }	     get_token (ctok);	     function_args_expression (ctok, 0);	  }	append_token_of_type (EARG_TOKEN);	compile_token_list ();	block (ctok);	compile_token_of_type (FOREACH_TOKEN);	break;      case WHILE_TOKEN:	get_token (ctok);	compile_token_of_type (OBRACE_TOKEN);	expression_with_parenthesis (ctok);	compile_token_of_type (CBRACE_TOKEN);	block (ctok);	compile_token_of_type (WHILE_TOKEN);	break;      case DO_TOKEN:	get_token (ctok);	block (ctok);	if (WHILE_TOKEN != get_token (ctok))	  {	     _SLparse_error("Expecting while", ctok, 0);	     break;	  }	get_token (ctok);	compile_token_of_type (OBRACE_TOKEN);	expression_with_parenthesis (ctok);	compile_token_of_type (CBRACE_TOKEN);	compile_token_of_type (DOWHILE_TOKEN);	handle_semicolon (ctok);	break;      case FOR_TOKEN:	/* Look for (exp_opt ; exp_opt ; exp_opt ) */	if (OPAREN_TOKEN != get_token (ctok))	  {	     _SLparse_error("Expecting (.", ctok, 0);	     break;	  }	if (NULL == push_token_list ())	  break;	append_token_of_type (OBRACE_TOKEN);	if (SEMICOLON_TOKEN != get_token (ctok))	  {	     expression (ctok);	     if (ctok->type != SEMICOLON_TOKEN)	       {		  _SLparse_error("Expecting ;", ctok, 0);		  break;	       }	  }	append_token_of_type (CBRACE_TOKEN);	append_token_of_type (OBRACE_TOKEN);	if (SEMICOLON_TOKEN != get_token (ctok))	  {	     expression (ctok);	     if (ctok->type != SEMICOLON_TOKEN)	       {		  _SLparse_error("Expecting ;", ctok, 0);		  break;

⌨️ 快捷键说明

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