home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
gnu
/
gcc-2.3.3-src.lha
/
GNU
/
src
/
amiga
/
gcc-2.3.3
/
c-lex.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-06
|
49KB
|
1,928 lines
/* Lexical analyzer for C and Objective C.
Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <errno.h>
#include <setjmp.h>
#include "config.h"
#include "rtl.h"
#include "tree.h"
#include "input.h"
#include "c-lex.h"
#include "c-tree.h"
#include "flags.h"
#include "c-parse.h"
#ifdef MULTIBYTE_CHARS
#include <stdlib.h>
#include <locale.h>
#endif
#ifndef errno
extern int errno;
#endif
/* 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];
/* Cause the `yydebug' variable to be defined. */
#define YYDEBUG 1
/* the declaration found for the last IDENTIFIER token read in.
yylex must look this up to detect typedefs, which get token type TYPENAME,
so it is left around in case the identifier is not a typedef but is
used in a context which makes it a reference to a variable. */
tree lastiddecl;
/* Nonzero enables objc features. */
int doing_objc_thang;
extern tree lookup_interface ();
extern int yydebug;
/* File used for outputting assembler code. */
extern FILE *asm_out_file;
#ifndef WCHAR_TYPE_SIZE
#ifdef INT_TYPE_SIZE
#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
#else
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#endif
#endif
/* Number of bytes in a wide character. */
#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
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. */
/* Nonzero if end-of-file has been seen on input. */
static int end_of_file;
/* Buffered-back input character; faster than using ungetc. */
static int nextchar = -1;
int check_newline ();
/* Nonzero tells yylex to ignore \ in string constants. */
static int ignore_escape_flag = 0;
/* C code produced by gperf version 2.5 (GNU C++ version) */
/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
struct resword { char *name; short token; enum rid rid; };
#define TOTAL_KEYWORDS 53
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 13
#define MIN_HASH_VALUE 7
#define MAX_HASH_VALUE 102
/* maximum key range = 96, duplicates = 0 */
#ifdef __GNUC__
__inline
#endif
static unsigned int
hash (str, len)
register char *str;
register int unsigned len;
{
static unsigned char asso_values[] =
{
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 103, 103, 1, 103, 2, 1, 24,
1, 5, 19, 39, 16, 13, 103, 1, 25, 1,
34, 34, 24, 103, 13, 12, 1, 45, 24, 7,
103, 103, 2, 103, 103, 103, 103, 103,
};
register int hval = len;
switch (hval)
{
default:
case 3:
hval += asso_values[str[2]];
case 2:
case 1:
hval += asso_values[str[0]];
}
return hval + asso_values[str[len - 1]];
}
#ifdef __GNUC__
__inline
#endif
struct resword *
is_reserved_word (str, len)
register char *str;
register unsigned int len;
{
static struct resword wordlist[] =
{
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"asm", ASM_KEYWORD, NORID},
{"",},
{"__asm", ASM_KEYWORD, NORID},
{"",},
{"__asm__", ASM_KEYWORD, NORID},
{"break", BREAK, NORID},
{"__typeof__", TYPEOF, NORID},
{"",},
{"__alignof__", ALIGNOF, NORID},
{"",},
{"__attribute__", ATTRIBUTE, NORID},
{"int", TYPESPEC, RID_INT},
{"__attribute", ATTRIBUTE, NORID},
{"__extension__", EXTENSION, NORID},
{"",},
{"__signed", TYPESPEC, RID_SIGNED},
{"",},
{"__signed__", TYPESPEC, RID_SIGNED},
{"__inline__", SCSPEC, RID_INLINE},
{"else", ELSE, NORID},
{"__inline", SCSPEC, RID_INLINE},
{"default", DEFAULT, NORID},
{"__typeof", TYPEOF, NORID},
{"while", WHILE, NORID},
{"__alignof", ALIGNOF, NORID},
{"struct", STRUCT, NORID},
{"__const", TYPE_QUAL, RID_CONST},
{"if", IF, NORID},
{"__const__", TYPE_QUAL, RID_CONST},
{"__label__", LABEL, NORID},
{"do", DO, NORID},
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
{"sizeof", SIZEOF, NORID},
{"__volatile", TYPE_QUAL, RID_VOLATILE},
{"auto", SCSPEC, RID_AUTO},
{"void", TYPESPEC, RID_VOID},
{"char", TYPESPEC, RID_CHAR},
{"static", SCSPEC, RID_STATIC},
{"case", CASE, NORID},
{"extern", SCSPEC, RID_EXTERN},
{"switch", SWITCH, NORID},
{"for", FOR, NORID},
{"inline", SCSPEC, RID_INLINE},
{"typeof", TYPEOF, NORID},
{"typedef", SCSPEC, RID_TYPEDEF},
{"short", TYPESPEC, RID_SHORT},
{"",},
{"return", RETURN, NORID},
{"enum", ENUM, NORID},
{"",},
{"double", TYPESPEC, RID_DOUBLE},
{"signed", TYPESPEC, RID_SIGNED},
{"float", TYPESPEC, RID_FLOAT},
{"",}, {"",},
{"volatile", TYPE_QUAL, RID_VOLATILE},
{"",},
{"const", TYPE_QUAL, RID_CONST},
{"",},
{"unsigned", TYPESPEC, RID_UNSIGNED},
{"",}, {"",}, {"",}, {"",},
{"continue", CONTINUE, NORID},
{"",},
{"register", SCSPEC, RID_REGISTER},
{"",}, {"",}, {"",}, {"",},
{"goto", GOTO, NORID},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"union", UNION, NORID},
{"",}, {"",}, {"",}, {"",},
{"long", TYPESPEC, RID_LONG},
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register char *s = wordlist[key].name;
if (*s == *str && !strcmp (str + 1, s + 1))
return &wordlist[key];
}
}
return 0;
}
/* Return something to represent absolute declarators containing a *.
TARGET is the absolute declarator that the * contains.
TYPE_QUALS is a list of modifiers such as const or volatile
to apply to the pointer type, represented as identifiers.
We return an INDIRECT_REF whose "contents" are TARGET
and whose type is the modifier list. */
tree
make_pointer_declarator (type_quals, target)
tree type_quals, target;
{
return build1 (INDIRECT_REF, type_quals, target);
}
void
init_lex ()
{
/* 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;
#ifdef MULTIBYTE_CHARS
/* Change to the native locale for multibyte conversions. */
setlocale (LC_CTYPE, "");
#endif
maxtoken = 40;
token_buffer = (char *) xmalloc (maxtoken + 2);
ridpointers[(int) RID_INT] = get_identifier ("int");
ridpointers[(int) RID_CHAR] = get_identifier ("c