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

📄 lex.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Lexical analyzer for GNU CHILL. -*- C -*-   Copyright (C) 1992, 93, 1994, 1998 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 the	 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.  */#include "config.h"#include "system.h"#include <setjmp.h>#include <sys/stat.h>#include "tree.h"#include "input.h"#include "lex.h"#include "ch-tree.h"#include "flags.h"#include "parse.h"#include "obstack.h"#include "toplev.h"#ifdef DWARF_DEBUGGING_INFO#include "dwarfout.h"#endif#ifdef MULTIBYTE_CHARS#include <locale.h>#endif/* include the keyword recognizers */#include "hash.h"FILE* finput;#if 0static int	last_token = 0;/* Sun's C compiler warns about the safer sequence    do { .. } while 0    when there's a 'return' inside the braces, so don't use it */#define RETURN_TOKEN(X) { last_token = X; return (X); }#endif/* This is set non-zero to force incoming tokens to lowercase. */extern int ignore_case;extern int module_number;extern int serious_errors;/* This is non-zero to recognize only uppercase special words. */extern int special_UC;extern struct obstack permanent_obstack;extern struct obstack temporary_obstack;/* forward declarations */static void close_input_file         PROTO((char *));static tree convert_bitstring        PROTO((char *));static tree convert_integer          PROTO((char *));static void maybe_downcase           PROTO((char *));static int  maybe_number             PROTO((char *));static tree equal_number             PROTO((void));static void handle_use_seizefile_directive PROTO((int));static int  handle_name		     PROTO((tree));static char *readstring              PROTO((int, int *));static void read_directive	     PROTO((void));static tree read_identifier	     PROTO((int));static tree read_number              PROTO((int));static void skip_c_comment           PROTO((void));static void skip_line_comment        PROTO((void));static int  skip_whitespace          PROTO((void));static tree string_or_char           PROTO((int, char *));/* next variables are public, because ch-actions uses them *//* the default grantfile name, set by lang_init */tree default_grant_file = 0;/* These tasking-related variables are NULL at the start of each    compiler pass, and are set to an expression tree if and when   a compiler directive is parsed containing an expression.   The NULL state is significant;  it means 'no user-specified   signal_code (or whatever) has been parsed'. *//* process type, set by <> PROCESS_TYPE = number <> */tree process_type = NULL_TREE;/* send buffer default priority,   set by <> SEND_BUFFER_DEFAULT_PRIORITY = number <> */tree send_buffer_prio = NULL_TREE;/* send signal default priority,   set by <> SEND_SIGNAL_DEFAULT_PRIORITY = number <> */tree send_signal_prio = NULL_TREE;/* signal code, set by <> SIGNAL_CODE = number <> */tree signal_code = NULL_TREE;/* flag for range checking */int range_checking = 1;/* flag for NULL pointer checking */int empty_checking = 1;/* flag to indicate making all procedure local variables   to be STATIC */int all_static_flag = 0;/* flag to indicate -fruntime-checking command line option.   Needed for initializing range_checking and empty_checking   before pass 2 */int runtime_checking_flag = 1;/* The elements of `ridpointers' are identifier nodes   for the reserved type names and storage classes.   It is indexed by a RID_... value.  */tree ridpointers[(int) RID_MAX];/* Nonzero tells yylex to ignore \ in string constants.  */static int ignore_escape_flag = 0;static int maxtoken;		/* Current nominal length of token buffer.  */char *token_buffer;	/* Pointer to token buffer.			   Actual allocated length is maxtoken + 2.			   This is not static because objc-parse.y uses it.  *//* implement yylineno handling for flex */#define yylineno linenostatic int inside_c_comment = 0;static int saw_eol = 0; /* 1 if we've just seen a '\n' */static int saw_eof = 0; /* 1 if we've just seen an EOF */typedef struct string_list  {    struct string_list *next;    char               *str;  } STRING_LIST;/* list of paths specified on the compiler command line by -L options. */static STRING_LIST *seize_path_list = (STRING_LIST *)0;/* List of seize file names.  Each TREE_VALUE is an identifier   (file name) from a <>USE_SEIZE_FILE<> directive.   The TREE_PURPOSE is non-NULL if a USE_SEIZE_FILE directive has been   written to the grant file. */static tree files_to_seize     = NULL_TREE;/* Last node on files_to_seize list. */static tree last_file_to_seize = NULL_TREE;/* Pointer into files_to_seize list:  Next unparsed file to read. */static tree next_file_to_seize = NULL_TREE;/* The most recent use_seize_file directive. */tree use_seizefile_name = NULL_TREE;/* If non-NULL, the name of the seizefile we're currently processing. */tree current_seizefile_name = NULL_TREE;/* called to reset for pass 2 */static voidch_lex_init (){  current_seizefile_name = NULL_TREE;  lineno = 0;  saw_eol = 0;  saw_eof = 0;  /* Initialize these compiler-directive variables. */  process_type     = NULL_TREE;  send_buffer_prio = NULL_TREE;  send_signal_prio = NULL_TREE;  signal_code      = NULL_TREE;  all_static_flag  = 0;  /* reinitialize rnage checking and empty checking */  range_checking = runtime_checking_flag;  empty_checking = runtime_checking_flag;}char *init_parse (filename)     char *filename;{  int lowercase_standard_names = ignore_case || ! special_UC;  /* Open input file.  */  if (filename == 0 || !strcmp (filename, "-"))    {      finput = stdin;      filename = "stdin";    }  else    finput = fopen (filename, "r");  if (finput == 0)    pfatal_with_name (filename);#ifdef IO_BUFFER_SIZE  setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);#endif  /* Make identifier nodes long enough for the language-specific slots.  */  set_identifier_size (sizeof (struct lang_identifier));  /* Start it at 0, because check_newline is called at the very beginning     and will increment it to 1.  */  lineno = 0;  /* Initialize these compiler-directive variables. */  process_type     = NULL_TREE;  send_buffer_prio = NULL_TREE;  send_signal_prio = NULL_TREE;  signal_code      = NULL_TREE;  maxtoken         = 40;  token_buffer     = xmalloc ((unsigned)(maxtoken + 2));  init_chill_expand ();#define ENTER_STANDARD_NAME(RID, LOWER, UPPER) \  ridpointers[(int) RID] = \    get_identifier (lowercase_standard_names ? LOWER : UPPER)  ENTER_STANDARD_NAME (RID_ALL,		"all",		"ALL");  ENTER_STANDARD_NAME (RID_ASSERTFAIL,	"assertfail",	"ASSERTFAIL");  ENTER_STANDARD_NAME (RID_ASSOCIATION,	"association",	"ASSOCIATION");  ENTER_STANDARD_NAME (RID_BIN,         "bin",          "BIN");  ENTER_STANDARD_NAME (RID_BOOL,	"bool",		"BOOL");  ENTER_STANDARD_NAME (RID_BOOLS,	"bools",	"BOOLS");  ENTER_STANDARD_NAME (RID_BYTE,	"byte",		"BYTE");  ENTER_STANDARD_NAME (RID_CHAR,	"char",		"CHAR");  ENTER_STANDARD_NAME (RID_DOUBLE,	"double",	"DOUBLE");  ENTER_STANDARD_NAME (RID_DURATION,    "duration",     "DURATION");  ENTER_STANDARD_NAME (RID_DYNAMIC,	"dynamic",	"DYNAMIC");  ENTER_STANDARD_NAME (RID_ELSE,	"else",		"ELSE");  ENTER_STANDARD_NAME (RID_EMPTY,	"empty",	"EMPTY");  ENTER_STANDARD_NAME (RID_FALSE,	"false",	"FALSE");  ENTER_STANDARD_NAME (RID_FLOAT,	"float",	"FLOAT");  ENTER_STANDARD_NAME (RID_GENERAL,	"general",	"GENERAL");  ENTER_STANDARD_NAME (RID_IN,		"in",		"IN");  ENTER_STANDARD_NAME (RID_INLINE,	"inline",	"INLINE");  ENTER_STANDARD_NAME (RID_INOUT,	"inout",	"INOUT");  ENTER_STANDARD_NAME (RID_INSTANCE,	"instance",	"INSTANCE");  ENTER_STANDARD_NAME (RID_INT,		"int",		"INT");  ENTER_STANDARD_NAME (RID_LOC,		"loc",		"LOC");  ENTER_STANDARD_NAME (RID_LONG,	"long",		"LONG");  ENTER_STANDARD_NAME (RID_LONG_REAL,	"long_real",	"LONG_REAL");  ENTER_STANDARD_NAME (RID_NULL,	"null",		"NULL");  ENTER_STANDARD_NAME (RID_OUT,		"out",		"OUT");  ENTER_STANDARD_NAME (RID_OVERFLOW,	"overflow",	"OVERFLOW");  ENTER_STANDARD_NAME (RID_PTR,		"ptr",		"PTR");  ENTER_STANDARD_NAME (RID_READ,	"read",		"READ");  ENTER_STANDARD_NAME (RID_REAL,	"real",		"REAL");  ENTER_STANDARD_NAME (RID_RANGE,	"range",	"RANGE");  ENTER_STANDARD_NAME (RID_RANGEFAIL,	"rangefail",	"RANGEFAIL");  ENTER_STANDARD_NAME (RID_RECURSIVE,	"recursive",	"RECURSIVE");  ENTER_STANDARD_NAME (RID_SHORT,	"short",	"SHORT");  ENTER_STANDARD_NAME (RID_SIMPLE,	"simple",	"SIMPLE");  ENTER_STANDARD_NAME (RID_TIME,        "time",         "TIME");  ENTER_STANDARD_NAME (RID_TRUE,	"true",		"TRUE");  ENTER_STANDARD_NAME (RID_UBYTE,	"ubyte",	"UBYTE");  ENTER_STANDARD_NAME (RID_UINT,	"uint",		"UINT");  ENTER_STANDARD_NAME (RID_ULONG,	"ulong",	"ULONG");  ENTER_STANDARD_NAME (RID_UNSIGNED,	"unsigned",	"UNSIGNED");  ENTER_STANDARD_NAME (RID_USHORT,	"ushort",	"USHORT");  ENTER_STANDARD_NAME (RID_VOID,	"void",		"VOID");  return filename;}voidfinish_parse (){  if (finput != NULL)    fclose (finput);}static int yywrap ();#define YY_PUTBACK_SIZE 5#define YY_BUF_SIZE 1000static char yy_buffer[YY_PUTBACK_SIZE + YY_BUF_SIZE];static char *yy_cur = yy_buffer + YY_PUTBACK_SIZE;static char *yy_lim = yy_buffer + YY_PUTBACK_SIZE;int yy_refill (){  char *buf = yy_buffer + YY_PUTBACK_SIZE;  int c, result;  bcopy (yy_cur - YY_PUTBACK_SIZE, yy_buffer, YY_PUTBACK_SIZE);  yy_cur = buf; retry:  if (saw_eof)    {      if (yywrap ())	return EOF;      saw_eof = 0;      goto retry;    }  result = 0;  while (saw_eol)    {      c = check_newline ();      if (c == EOF)        {	  saw_eof = 1;	  goto retry;	}      else if (c != '\n')	{	  saw_eol = 0;	  buf[result++] = c;	}    }    while (result < YY_BUF_SIZE)    {      c = getc(finput);      if (c == EOF)        {	  saw_eof = 1;	  break;	}      buf[result++] = c;            /* Because we might switch input files on a compiler directive	 (that end with '>', don't read past a '>', just in case. */      if (c == '>')	break;            if (c == '\n')	{#ifdef YYDEBUG	  extern int yydebug;	  if (yydebug)            fprintf (stderr, "-------------------------- finished Line %d\n",		     yylineno);#endif	  saw_eol = 1;	  break;	}    }  yy_lim = yy_cur + result;  return yy_lim > yy_cur ? *yy_cur++ : EOF;}#define input() (yy_cur < yy_lim ? *yy_cur++ : yy_refill ())#define unput(c) (*--yy_cur = (c))int starting_pass_2 = 0;intyylex (){  int nextc;  int len;  char* tmp;  int base;  int ch; retry:  ch = input ();  if (starting_pass_2)    {      starting_pass_2 = 0;      unput (ch);      return END_PASS_1;    }  switch (ch)    {    case ' ': case '\t': case '\n': case '\f': case '\b': case '\v': case '\r':      goto retry;    case '[':      return LPC;    case ']':      return RPC;    case '{':      return LC;    case '}':      return RC;    case '(':      nextc = input ();      if (nextc == ':')	return LPC;      unput (nextc);      return LPRN;    case ')':      return RPRN;    case ':':      nextc = input ();      if (nextc == ')')	return RPC;      else if (nextc == '=')	return ASGN;      unput (nextc);      return COLON;    case ',':      return COMMA;    case ';':      return SC;    case '+':      return PLUS;    case '-':      nextc = input ();      if (nextc == '>')	return ARROW;      if (nextc == '-')	{	  skip_line_comment ();	  goto retry;	}      unput (nextc);      return SUB;    case '*':      return MUL;    case '=':      return EQL;    case '/':      nextc = input ();      if (nextc == '/')	return CONCAT;      else if (nextc == '=')	return NE;      else if (nextc == '*')	{	  skip_c_comment ();	  goto retry;	}      unput (nextc);      return DIV;    case '<':      nextc = input ();      if (nextc == '=')	return LTE;      if (nextc == '>')	{	  read_directive ();	  goto retry;	}      unput (nextc);      return LT;    case '>':      nextc = input ();      if (nextc == '=')	return GTE;      unput (nextc);      return GT;    case 'D': case 'd':      base = 10;      goto maybe_digits;    case 'B': case 'b':      base = 2;      goto maybe_digits;    case 'H': case 'h':      base = 16;      goto maybe_digits;    case 'O': case 'o':      base = 8;      goto maybe_digits;    case 'C': case 'c':      nextc = input ();      if (nextc == '\'')	{	  int byte_val = 0;	  char *start;	  int len = 0;  /* Number of hex digits seen. */	  for (;;)	    {	      ch = input ();	      if (ch == '\'')		break;	      if (ch == '_')		continue;	      if (!ISXDIGIT (ch))           /* error on non-hex digit */		{		  if (pass == 1)		    error ("invalid C'xx' ");		  break;		}	      if (ch >= 'a')		ch -= ' ';	      ch -= '0';	      if (ch > 9)		ch -= 7;	      byte_val *= 16;	      byte_val += (int)ch;	      if (len & 1) /* collected two digits, save byte */		obstack_1grow (&temporary_obstack, (char) byte_val);	      len++;	    }	  start = obstack_finish (&temporary_obstack);	  yylval.ttype = string_or_char (len >> 1, start);	  obstack_free (&temporary_obstack, start);	  return len == 2 ? SINGLECHAR : STRING;	}      unput (nextc);      goto letter;    maybe_digits:      nextc = input ();      if (nextc == '\'')	{	  char *start;	  obstack_1grow (&temporary_obstack, ch);	  obstack_1grow (&temporary_obstack, nextc);	  for (;;)	    {	      ch = input ();	      if (ISALNUM (ch))		obstack_1grow (&temporary_obstack, ch);	      else if (ch != '_')		break;	    }	  obstack_1grow (&temporary_obstack, '\0');	  start = obstack_finish (&temporary_obstack);	  if (ch != '\'')	    {	      unput (ch);	      yylval.ttype = convert_integer (start); /* Pass base? */	      return NUMBER;	    }	  else	    {	      yylval.ttype = convert_bitstring (start);	      return BITSTRING;	    }	}      unput (nextc);      goto letter;    case 'A':                                   case 'E':    case 'F':  case 'G':             case 'I':  case 'J':    case 'K':  case 'L':  case 'M':  case 'N':    case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':    case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':

⌨️ 快捷键说明

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