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

📄 parse.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Parser for GNU CHILL (CCITT High-Level Language)  -*- C -*-   Copyright (C) 1992, 1993, 1998, 1999 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */          /* * This is a two-pass parser.  In pass 1, we collect declarations, * ignoring actions and most expressions.  We store only the * declarations and close, open and re-lex the input file to save * main memory.  We anticipate that the compiler will be processing * *very* large single programs which are mechanically generated, * and so we want to store a minimum of information between passes. * * yylex detects the end of the main input file and returns the * END_PASS_1 token.  We then re-initialize each CHILL compiler  * module's global variables and re-process the input file. The  * grant file is output.  If the user has requested it, GNU CHILL  * exits at this time - its only purpose was to generate the grant * file. Optionally, the compiler may exit if errors were detected  * in pass 1. * * As each symbol scope is entered, we install its declarations into * the symbol table. Undeclared types and variables are announced * now. * * Then code is generated. */#include "config.h"#include "system.h"#include "tree.h"#include "ch-tree.h"#include "lex.h"#include "actions.h"#include "tasking.h"#include "parse.h"#include "toplev.h"/* Since parsers are distinct for each language, put the    language string definition here.  (fnf) */char *language_string = "GNU CHILL";/* Common code to be done before expanding any action. */#define INIT_ACTION { \	if (! ignoring) emit_line_note (input_filename, lineno); }/* Pop a scope for an ON handler. */#define POP_USED_ON_CONTEXT pop_handler(1)/* Pop a scope for an ON handler that wasn't there. */#define POP_UNUSED_ON_CONTEXT pop_handler(0)#define PUSH_ACTION push_action()/* Cause the `yydebug' variable to be defined.  */#define YYDEBUG 1extern struct rtx_def* gen_label_rtx	      PROTO((void));extern void emit_jump                         PROTO((struct rtx_def *));extern struct rtx_def* emit_label             PROTO((struct rtx_def *));/* This is a hell of a lot easier than getting expr.h included in   by parse.c.  */extern struct rtx_def *expand_expr  	PROTO((tree, struct rtx_def *,					       enum machine_mode, int));static int parse_action				PROTO((void));extern int  lineno;extern char *input_filename;extern tree generic_signal_type_node;extern tree signal_code;extern int all_static_flag;extern int ignore_case;     #if 0static int  quasi_signal = 0;  /* 1 if processing a quasi signal decl */#endifint parsing_newmode;                       /* 0 while parsing SYNMODE; 					      1 while parsing NEWMODE. */int expand_exit_needed = 0;/* Gets incremented if we see errors such that we don't want to run pass 2. */int serious_errors = 0;static tree current_fieldlist;/* We don't care about expressions during pass 1, except while we're   parsing the RHS of a SYN definition, or while parsing a mode that   we need.  NOTE:  This also causes mode expressions to be ignored. */int  ignoring = 1;              /* 1 to ignore expressions *//* True if we have seen an action not in a (user) function. */int seen_action = 0;int build_constructor = 0;/* The action_nesting_level of the current procedure body. */ int proc_action_level = 0;/* This is the identifier of the label that prefixes the current action,   or NULL if there was none.  It is cleared at the end of an action,   or when starting a nested action list, so get it while you can! */static tree label      = NULL_TREE;        /* for statement labels */#if 0static tree current_block;#endifint in_pseudo_module = 0;int pass = 0;                           /* 0 for init_decl_processing,					   1 for pass 1, 2 for pass 2 *//* re-initialize global variables for pass 2 */static voidch_parse_init (){  expand_exit_needed = 0;  label = NULL_TREE;             /* for statement labels */  current_module = NULL;  in_pseudo_module = 0;}static voidcheck_end_label (start, end)     tree start, end;{  if (end != NULL_TREE)    {      if (start == NULL_TREE && pass == 1)	error ("there was no start label to match the end label '%s'",	       IDENTIFIER_POINTER(end));      else if (start != end && pass == 1)	error ("start label '%s' does not match end label '%s'",	       IDENTIFIER_POINTER(start),	       IDENTIFIER_POINTER(end));    }}/* * given a tree which is an id, a type or a decl,  * return the associated type, or issue an error and * return error_mark_node. */treeget_type_of (id_or_decl)     tree id_or_decl;{  tree type = id_or_decl;  if (id_or_decl == NULL_TREE      || TREE_CODE (id_or_decl) == ERROR_MARK)    return error_mark_node;  if (pass == 1 || ignoring == 1)    return id_or_decl;  if (TREE_CODE (type) == IDENTIFIER_NODE)    {      type = lookup_name (id_or_decl);      if (type == NULL_TREE)	{	  error ("`%s' not declared", IDENTIFIER_POINTER (id_or_decl));	  type = error_mark_node;	}    }  if (TREE_CODE (type) == TYPE_DECL)    type = TREE_TYPE (type);  return type;           /* was a type all along */}static voidend_function (){  if (CH_DECL_PROCESS (current_function_decl))    {       /* finishing a process */      if (! ignoring)	{	  tree result = 	    build_chill_function_call	      (lookup_name (get_identifier ("__stop_process")),	       NULL_TREE);	  expand_expr_stmt (result);	  emit_line_note (input_filename, lineno);	}    }  else    {      /* finishing a procedure.. */      if (! ignoring)	{	  if (result_never_set	      && TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl)))	      != VOID_TYPE)	    warning ("No RETURN or RESULT in procedure");	  chill_expand_return (NULL_TREE, 1);	}    }  finish_chill_function ();  pop_chill_function_context (); }static treebuild_prefix_clause (id)     tree id;{  if (!id)    {      if (current_module && current_module->name)	{ char *module_name = IDENTIFIER_POINTER (current_module->name);	  if (module_name[0] && module_name[0] != '_')	    return current_module->name;	}      error ("PREFIXED clause with no prelix in unlabeled module");    }  return id;}voidpossibly_define_exit_label (label)     tree label;{  if (label)    define_label (input_filename, lineno, munge_exit_label (label));}#define MAX_LOOK_AHEAD 2static enum terminal terminal_buffer[MAX_LOOK_AHEAD+1];YYSTYPE yylval;static YYSTYPE val_buffer[MAX_LOOK_AHEAD+1];/*enum terminal current_token, lookahead_token;*/#define TOKEN_NOT_READ dummy_last_terminal#ifdef __GNUC____inline__#endifstatic enum terminalPEEK_TOKEN(){  if (terminal_buffer[0] == TOKEN_NOT_READ)    {      terminal_buffer[0] = yylex();      val_buffer[0] = yylval;    }  return terminal_buffer[0];}#define PEEK_TREE() val_buffer[0].ttype#define PEEK_TOKEN1() peek_token_(1)#define PEEK_TOKEN2() peek_token_(2)static intpeek_token_ (i)     int i;{  if (i > MAX_LOOK_AHEAD)    fatal ("internal error - too much lookahead");  if (terminal_buffer[i] == TOKEN_NOT_READ)    {      terminal_buffer[i] = yylex();      val_buffer[i] = yylval;    }  return terminal_buffer[i];}static voidpushback_token (code, node)     int code;     tree node;{  int i;  if (terminal_buffer[MAX_LOOK_AHEAD] != TOKEN_NOT_READ)    fatal ("internal error - cannot pushback token");  for (i = MAX_LOOK_AHEAD; i > 0; i--)    {       terminal_buffer[i] = terminal_buffer[i - 1];       val_buffer[i] = val_buffer[i - 1];  }  terminal_buffer[0] = code;  val_buffer[0].ttype = node;}static voidforward_token_(){  int i;  for (i = 0; i < MAX_LOOK_AHEAD; i++)    {      terminal_buffer[i] = terminal_buffer[i+1];      val_buffer[i] = val_buffer[i+1];    }  terminal_buffer[MAX_LOOK_AHEAD] = TOKEN_NOT_READ;}#define FORWARD_TOKEN() forward_token_()/* Skip the next token.   if it isn't TOKEN, the parser is broken. */voidrequire(token)     enum terminal token;{  if (PEEK_TOKEN() != token)    {      char buf[80];      sprintf (buf, "internal parser error - expected token %d", (int)token);      fatal(buf);    }  FORWARD_TOKEN();}intcheck_token (token)     enum terminal token;{  if (PEEK_TOKEN() != token)    return 0;  FORWARD_TOKEN ();  return 1;}/* return 0 if expected token was not found,   else return 1.*/intexpect(token, message)     enum terminal token;     char *message;{  if (PEEK_TOKEN() != token)    {      if (pass == 1)	error(message ? message : "syntax error");      return 0;    }  else    FORWARD_TOKEN();  return 1;}/* define a SYNONYM __PROCNAME__ (__procname__) which holds   the name of the current procedure.   This should be quit the same as __FUNCTION__ in C */static voiddefine__PROCNAME__ (){  char *fname;  tree string;  tree procname;  if (current_function_decl == NULL_TREE)    fname = "toplevel";  else    fname = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));  string = build_chill_string (strlen (fname), fname);  procname = get_identifier (ignore_case ? "__procname__" : "__PROCNAME__");  push_syndecl (procname, NULL_TREE, string);}/* Forward declarations. */static tree parse_expression ();static tree parse_primval ();static tree parse_mode PROTO((void));static tree parse_opt_mode PROTO((void));static tree parse_untyped_expr ();static tree parse_opt_untyped_expr ();static int parse_definition PROTO((int));static void parse_opt_actions ();static void parse_body PROTO((void));static tree parse_if_expression_body PROTO((void));static tree parse_opt_handler PROTO((void));static treeparse_opt_name_string (allow_all)     int allow_all; /* 1 if ALL is allowed as a postfix */{  enum terminal token = PEEK_TOKEN();  tree name;  if (token != NAME)    {      if (token == ALL && allow_all)	{	  FORWARD_TOKEN ();	  return ALL_POSTFIX;	}      return NULL_TREE;    }  name = PEEK_TREE();  for (;;)    {      FORWARD_TOKEN ();      token = PEEK_TOKEN();      if (token != '!')	return name;      FORWARD_TOKEN();      token = PEEK_TOKEN();      if (token == ALL && allow_all)	return get_identifier3(IDENTIFIER_POINTER (name), "!", "*");      if (token != NAME)	{	  if (pass == 1)	    error ("'%s!' is not followed by an identifier",		   IDENTIFIER_POINTER (name));	  return name;	}      name = get_identifier3(IDENTIFIER_POINTER(name),			     "!", IDENTIFIER_POINTER(PEEK_TREE()));    }}static treeparse_simple_name_string (){  enum terminal token = PEEK_TOKEN();  tree name;  if (token != NAME)    {      error ("expected a name here");      return error_mark_node;    }  name = PEEK_TREE ();  FORWARD_TOKEN ();  return name;}static treeparse_name_string (){  tree name = parse_opt_name_string (0);  if (name)    return name;  if (pass == 1)    error ("expected a name string here");  return error_mark_node;}static treeparse_defining_occurrence (){  if (PEEK_TOKEN () == NAME)    {      tree id = PEEK_TREE();      FORWARD_TOKEN ();      return id;    }  return NULL;}/* Matches: <name_string>   Returns if pass 1: the identifier.   Returns if pass 2: a decl or value for identifier. */static treeparse_name (){  tree name = parse_name_string ();  if (pass == 1 || ignoring)    return name;  else    {      tree decl = lookup_name (name);      if (decl == NULL_TREE)	{	  error ("`%s' undeclared", IDENTIFIER_POINTER (name));	  return error_mark_node;	}      else if (TREE_CODE (TREE_TYPE (decl)) == ERROR_MARK)	return error_mark_node;      else if (TREE_CODE (decl) == CONST_DECL)	return DECL_INITIAL (decl);      else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)	return convert_from_reference (decl);      else	return decl;    } }static treeparse_optlabel(){  tree label = parse_defining_occurrence();  if (label != NULL)    expect(COLON, "expected a ':' here");  return label;}static voidparse_semi_colon (){  enum terminal token = PEEK_TOKEN ();  if (token == SC)    FORWARD_TOKEN ();  else if (pass == 1)    (token == END ? pedwarn : error) ("expected ';' here");  label = NULL_TREE;}static voidparse_opt_end_label_semi_colon (start_label)     tree start_label;{  if (PEEK_TOKEN() == NAME)    {      tree end_label = parse_name_string ();      check_end_label (start_label, end_label);    }  parse_semi_colon ();}static void

⌨️ 快捷键说明

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