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

📄 slparse.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	     _SLparse_error ("Binary op stack overflow", ctok, 0);	     return;	  }	op_stack [op_num] = type;	level_stack [op_num] = level;	op_num++;	get_token (ctok);	unary_expression (ctok);	type = ctok->type;     }   while (op_num > 0)     append_token_of_type(op_stack[--op_num]);}/* unary-expression: *	 postfix-expression *	 ++ postfix-expression *	 -- postfix-expression *	 case unary-expression *	 OP3 unary-expression *	 (OP3: + - ~ & not @) * * Note:  This grammar permits: case case case WHATEVER */static void unary_expression (_SLang_Token_Type *ctok){   unsigned char save_unary_ops [16];   unsigned int num_unary_ops;   unsigned char type;   _SLang_Token_Type *last_token;   num_unary_ops = 0;   while (SLang_Error == 0)     {	type = ctok->type;	switch (type)	  {	   case PLUSPLUS_TOKEN:	   case MINUSMINUS_TOKEN:	     get_token (ctok);	     postfix_expression (ctok);	     check_for_lvalue (type, NULL);	     goto out_of_switch;	   case ADD_TOKEN:	     get_token (ctok);	       /* skip it-- it's unary here */	     break;	   case SUB_TOKEN:	     (void) get_token (ctok);	     if (IS_INTEGER_TOKEN (ctok->type))	       {		  ctok->v.long_val = -ctok->v.long_val;		  break;	       }	     if (num_unary_ops == 16)	       goto stack_overflow_error;	     save_unary_ops [num_unary_ops++] = CHS_TOKEN;	     break;	   case DEREF_TOKEN:	   case BNOT_TOKEN:	   case NOT_TOKEN:	   case CASE_TOKEN:	     if (num_unary_ops == 16)	       goto stack_overflow_error;	     save_unary_ops [num_unary_ops++] = type;	     get_token (ctok);	     break;	     /* Try to avoid ->postfix_expression->primary_expression	      * subroutine calls.	      */	   case STRING_TOKEN:	     append_token (ctok);	     get_token (ctok);	     goto out_of_switch;	   default:	     postfix_expression (ctok);	     goto out_of_switch;	  }     }   out_of_switch:   if (num_unary_ops == 0)     return;   if ((DEREF_TOKEN == save_unary_ops[num_unary_ops - 1])       && (NULL != (last_token = get_last_token ()))       && (IS_ASSIGN_TOKEN(last_token->type)))     {	/* FIXME: Priority=medium	 * This needs generalized so that things like @a.y = 1 will work properly.	 */	if ((num_unary_ops != 1)	    || (last_token->type != _SCALAR_ASSIGN_TOKEN))	  {	     SLang_verror (SL_NOT_IMPLEMENTED, 			   "Only derefence assignments to simple variables are possible");	     return;	  }	last_token->type += (_DEREF_ASSIGN_TOKEN - _SCALAR_ASSIGN_TOKEN);	return;     }   while (num_unary_ops)     {	num_unary_ops--;	append_token_of_type (save_unary_ops [num_unary_ops]);     }   return;   stack_overflow_error:   _SLparse_error ("Too many unary operators.", ctok, 0);}static int combine_namespace_tokens (_SLang_Token_Type *a, _SLang_Token_Type *b){   char *sa, *sb, *sc;   unsigned int lena, lenb;   unsigned long hash;   /* This is somewhat of a hack.  Combine the TWO identifier names    * (NAMESPACE) and (name) into the form NAMESPACE->name.  Then when the    * byte compiler compiles the object it will not be found.  It will then    * check for this hack and make the appropriate namespace lookup.    */   sa = a->v.s_val;   sb = b->v.s_val;   lena = strlen (sa);   lenb = strlen (sb);   sc = SLmalloc (lena + lenb + 3);   if (sc == NULL)     return -1;   strcpy (sc, sa);   strcpy (sc + lena, "->");   strcpy (sc + lena + 2, sb);   sb = _SLstring_make_hashed_string (sc, lena + lenb + 2, &hash);   SLfree (sc);   if (sb == NULL)     return -1;   /* I can free this string because no other token should be referencing it.    * (num_refs == 1).    */   _SLfree_hashed_string (sa, lena, a->hash);   a->v.s_val = sb;   a->hash = hash;   return 0;}static void append_identifier_token (_SLang_Token_Type *ctok){   _SLang_Token_Type *last_token;   append_token (ctok);   if (NAMESPACE_TOKEN != get_token (ctok))     return;   if (IDENT_TOKEN != get_token (ctok))     {	_SLparse_error ("Expecting name-space identifier", ctok, 0);	return;     }   last_token = get_last_token ();   if (-1 == combine_namespace_tokens (last_token, ctok))     return;   (void) get_token (ctok);}static int get_identifier_expr_token (_SLang_Token_Type *ctok){   _SLang_Token_Type next_token;   if (IDENT_TOKEN != get_identifier_token (ctok))     return -1;   init_token (&next_token);   if (NAMESPACE_TOKEN != get_token (&next_token))     {	unget_token (&next_token);	return IDENT_TOKEN;     }   if (IDENT_TOKEN != get_identifier_token (&next_token))     {	free_token (&next_token);	return -1;     }   if (-1 == combine_namespace_tokens (ctok, &next_token))     {	free_token (&next_token);	return -1;     }   free_token (&next_token);   return IDENT_TOKEN;}/* postfix-expression: *	 primary-expression *	 postfix-expression [ expression ] *	 postfix-expression ( function-args-expression ) *	 postfix-expression . identifier *       postfix-expression ^ unary-expression *	 postfix-expression ++ *	 postfix-expression -- *	 postfix-expression = simple-expression *	 postfix-expression += simple-expression *	 postfix-expression -= simple-expression * * primary-expression: *	literal *	identifier-expr *	( expression_opt ) * 	[ inline-array-expression ] * 	&identifier-expr *      struct-definition *      __tmp(identifier-expr) * * identifier-expr: *      identifier *      identifier->identifier */static void postfix_expression (_SLang_Token_Type *ctok){   unsigned int start_pos, end_pos;   unsigned char type;   if (Token_List == NULL)     return;   start_pos = Token_List->len;   switch (ctok->type)     {      case IDENT_TOKEN:	append_identifier_token (ctok);	break;      case CHAR_TOKEN:      case SHORT_TOKEN:      case INT_TOKEN:      case LONG_TOKEN:      case UCHAR_TOKEN:      case USHORT_TOKEN:      case UINT_TOKEN:      case ULONG_TOKEN:      case STRING_TOKEN:      case BSTRING_TOKEN:#ifdef SLANG_HAS_FLOAT      case DOUBLE_TOKEN:      case FLOAT_TOKEN:#endif#ifdef SLANG_HAS_COMPLEX      case COMPLEX_TOKEN:#endif	append_token (ctok);	get_token (ctok);	break;      case OPAREN_TOKEN:	if (CPAREN_TOKEN != get_token (ctok))	  {	     expression (ctok);	     if (ctok->type != CPAREN_TOKEN)	       _SLparse_error("Expecting )", ctok, 0);	  }	get_token (ctok);	break;      case BAND_TOKEN:	if (IDENT_TOKEN != get_identifier_expr_token (ctok))	  break;	ctok->type = _REF_TOKEN;	append_token (ctok);	get_token (ctok);	break;      case OBRACKET_TOKEN:	get_token (ctok);	inline_array_expression (ctok);	break;      case NO_OP_LITERAL:	/* This token was introduced by try_multiple_assignment.  There,	 * a new token_list was pushed and (expression) was evaluated.	 * NO_OP_LITERAL represents the result of expression.  However,	 * we need to tweak the start_pos variable to point to the beginning	 * of the token list to complete the equivalence.	 */	start_pos = 0;	get_token (ctok);	break;      case STRUCT_TOKEN:	get_token (ctok);	struct_declaration (ctok);	break;      case TMP_TOKEN:	get_token (ctok);	if (ctok->type == OPAREN_TOKEN)	  {	     if (IDENT_TOKEN == get_identifier_expr_token (ctok))	       {		  ctok->type = TMP_TOKEN;		  append_token (ctok);		  get_token (ctok);		  if (ctok->type == CPAREN_TOKEN)		    {		       get_token (ctok);		       break;		    }	       }	  }	_SLparse_error ("Expecting form __tmp(NAME)", ctok, 0);	break;      default:	if (IS_INTERNAL_FUNC(ctok->type))	  {	     append_token (ctok);	     get_token (ctok);	  }	else	  _SLparse_error("Expecting a PRIMARY", ctok, 0);     }   while (SLang_Error == 0)     {	end_pos = Token_List->len;	type = ctok->type;	switch (type)	  {	   case OBRACKET_TOKEN:	       /* X[args] ==> [args] X ARRAY */	     get_token (ctok);	     append_token_of_type (ARG_TOKEN);	     if (ctok->type != CBRACKET_TOKEN) 	       array_index_expression (ctok);	     if (ctok->type != CBRACKET_TOKEN)	       {		  _SLparse_error ("Expecting ']'", ctok, 0);		  return;	       }	     get_token (ctok);	     /* append_token_of_type (EARG_TOKEN); -- ARRAY_TOKEN implicitely does this */	     token_list_element_exchange (start_pos, end_pos);	     append_token_of_type (ARRAY_TOKEN);	     break;	   case OPAREN_TOKEN:	     /* f(args) ==> args f */	     if (CPAREN_TOKEN != get_token (ctok))	       {		  function_args_expression (ctok, 1);		  token_list_element_exchange (start_pos, end_pos);	       }	     else get_token (ctok);	     break;	   case DOT_TOKEN:	     /* S.a ==> "a" S DOT	      * This means that if S is X[b], then X[b].a ==> a b X ARRAY DOT	      * and f(a).X[b].c ==> "c" b "X" a f . ARRAY .	      * Also, f(a).X[b] = g(x); ==> x g b "X" a f .	      */	     if (IDENT_TOKEN != get_identifier_token (ctok))	       return;	     ctok->type = DOT_TOKEN;	     append_token (ctok);	     get_token (ctok);	     break;	   case PLUSPLUS_TOKEN:	   case MINUSMINUS_TOKEN:	     check_for_lvalue (type, NULL);	     get_token (ctok);	     break;	   case ASSIGN_TOKEN:	   case PLUSEQS_TOKEN:	   case MINUSEQS_TOKEN:	   case TIMESEQS_TOKEN:	   case DIVEQS_TOKEN:	   case BOREQS_TOKEN:	   case BANDEQS_TOKEN:	     check_for_lvalue (type, NULL);	     get_token (ctok);	     simple_expression (ctok);	     token_list_element_exchange (start_pos, end_pos);	     break;	   case POW_TOKEN:	     get_token (ctok);	     unary_expression (ctok);	     append_token_of_type (POW_TOKEN);	     break;	   default:	     return;	  }     }}static void function_args_expression (_SLang_Token_Type *ctok, int handle_num_args){   unsigned char last_type, this_type;   if (handle_num_args) append_token_of_type (ARG_TOKEN);   last_type = COMMA_TOKEN;   while (SLang_Error == 0)     {	this_type = ctok->type;	switch (this_type)	  {	   case COMMA_TOKEN:	     if (last_type == COMMA_TOKEN)	       append_token_of_type (_NULL_TOKEN);	     get_token (ctok);	     break;	   case CPAREN_TOKEN:	     if (last_type == COMMA_TOKEN)	       append_token_of_type (_NULL_TOKEN);	     if (handle_num_args) append_token_of_type (EARG_TOKEN);	     get_token (ctok);	     return;	   default:	     simple_expression (ctok);	     if ((ctok->type != COMMA_TOKEN)		 && (ctok->type != CPAREN_TOKEN))	       {		  _SLparse_error ("Expecting ')'", ctok, 0);		  break;	       }	  }	last_type = this_type;     }}static int check_for_lvalue (unsigned char eqs_type, _SLang_Token_Type *ctok){   unsigned char type;   if ((ctok == NULL)       && (NULL == (ctok = get_last_token ())))     return -1;   type = ctok->type;   eqs_type -= ASSIGN_TOKEN;   if (type == IDENT_TOKEN)     eqs_type += _SCALAR_ASSIGN_TOKEN;   else if (type == ARRAY_TOKEN)     eqs_type += _ARRAY_ASSIGN_TOKEN;   else if (type == DOT_TOKEN)     eqs_type += _STRUCT_ASSIGN_TOKEN;   else     {	_SLparse_error ("Expecting LVALUE", ctok, 0);	return -1;     }   ctok->type = eqs_type;   return 0;}static void array_index_expression (_SLang_Token_Type *ctok){   unsigned int num_commas;   num_commas = 0;   while (1)     {	switch (ctok->type)	  {	   case COLON_TOKEN:	     if (num_commas)	       _SLparse_error ("Misplaced ':'", ctok, 0);	     return;	     	   case TIMES_TOKEN:	     append_token_of_type (_INLINE_WILDCARD_ARRAY_TOKEN);	     get_token (ctok);	     break;	     	   case COMMA_TOKEN:	     _SLparse_error ("Misplaced ','", ctok, 0);	     return;	     	   default:	     simple_expression (ctok);	  }		if (ctok->type != COMMA_TOKEN)	  return;	num_commas++;	get_token (ctok);     }}/* inline-array-expression: *    array_index_expression *    simple_expression : simple_expression *    simple_expression : simple_expression : simple_expression */static void inline_array_expression (_SLang_Token_Type *ctok){   int num_colons = 0;   append_token_of_type (ARG_TOKEN);   if (ctok->type == COLON_TOKEN)	       /* [:...] */     append_token_of_type (_NULL_TOKEN);   else if (ctok->type != CBRACKET_TOKEN)      array_index_expression (ctok);   if (ctok->type == COLON_TOKEN)     {	num_colons++;	if ((COLON_TOKEN == get_token (ctok))	    || (ctok->type == CBRACKET_TOKEN))	  append_token_of_type (_NULL_TOKEN);	else	  simple_expression (ctok);	if (ctok->type == COLON_TOKEN)	  {	     num_colons++;	     get_token (ctok);	     simple_expression (ctok);	  }     }   if (ctok->type != CBRACKET_TOKEN)     {	_SLparse_error ("Expecting ']'", ctok, 0);	return;     }   /* append_token_of_type (EARG_TOKEN); */   if (num_colons)     append_token_of_type (_INLINE_IMPLICIT_ARRAY_TOKEN);   else     append_token_of_type (_INLINE_ARRAY_TOKEN);   get_token (ctok);}static void do_multiple_assignment (_SLang_Token_Type *ctok){   _SLang_Token_Type *s;   unsigned int i, k, len;   unsigned char assign_type;   assign_type = ctok->type;   /* The LHS token list has already been pushed.  Here we do the RHS    * so push to another token list, process it, then come back to    * LHS for assignment.    */   if (NULL == push_token_list ())     return;   get_token (ctok);   expression (ctok);   compile_token_list ();   if (SLang_Error)     return;   /* Finally compile the LHS of the assignment expression    * that has been saved.    */   s = Token_List->stack;   len = Token_List->len;   if (len == 0)     {	compile_token_of_type (POP_TOKEN);	return;     }   while (len > 0)     {	/* List is of form:	 *    a , b, c d e, f , g , , , h ,	 * The missing expressions will be replaced by a POP	 * ,,a	 */	/* Start from back looking for a COMMA */	k = len - 1;	if (s[k].type == COMMA_TOKEN)	  {	     compile_token_of_type (POP_TOKEN);	     len = k;	     continue;	  }	if (-1 == check_for_lvalue (assign_type, s + k))	  return;	i = 0;	while (1)	  {	     if (s[k].type == COMMA_TOKEN)	       {		  i = k + 1;		  break;	       }	     if (k == 0)	       break;	     k--;	  }	while (i < len)	  {	     compile_token (s + i);	     i++;	  }	len = k;     }   if (s[0].type == COMMA_TOKEN)     compile_token_of_type (POP_TOKEN);}

⌨️ 快捷键说明

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