X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/b0ce6046682724c333e1444c86dfcfe3d51d8264..0846f581e81ccd73ea43f2a1dc73fd79ffc86b75:/src/lex.c diff --git a/src/lex.c b/src/lex.c index 2c7b3793..65082a81 100644 --- a/src/lex.c +++ b/src/lex.c @@ -23,28 +23,37 @@ #include "files.h" #include "getopt.h" /* for optarg */ #include "symtab.h" +#include "options.h" #include "lex.h" -#include "xalloc.h" #include "complain.h" #include "gram.h" #include "quote.h" /* Buffer for storing the current token. */ -struct obstack token_obstack; +static struct obstack token_obstack; const char *token_buffer = NULL; bucket *symval; int numval; -static int unlexed; /* these two describe a token to be reread */ -static bucket *unlexed_symval; /* by the next call to lex */ +/* these two describe a token to be reread */ +static token_t unlexed = tok_undef; +/* by the next call to lex */ +static bucket *unlexed_symval = NULL; void -init_lex (void) +lex_init (void) { obstack_init (&token_obstack); - unlexed = -1; + unlexed = tok_undef; +} + + +void +lex_free (void) +{ + obstack_free (&token_obstack, NULL); } @@ -313,7 +322,7 @@ literalchar (struct obstack *out, int *pcode, char term) void -unlex (int token) +unlex (token_t token) { unlexed = token; unlexed_symval = symval; @@ -356,12 +365,12 @@ lex (void) /* Just to make sure. */ token_buffer = NULL; - if (unlexed >= 0) + if (unlexed != tok_undef) { + token_t res = unlexed; symval = unlexed_symval; - c = unlexed; - unlexed = -1; - return c; + unlexed = tok_undef; + return res; } c = skip_white_space (); @@ -417,7 +426,6 @@ lex (void) case '\'': /* parse the literal token and compute character code in code */ - translations = -1; { int code, discode; @@ -445,7 +453,6 @@ lex (void) case '\"': /* parse the literal string token and treat as an identifier */ - translations = -1; { int code; /* ignored here */ @@ -463,32 +470,40 @@ lex (void) } case ',': + token_buffer = ","; return tok_comma; case ':': + token_buffer = ":"; return tok_colon; case ';': + token_buffer = ";"; return tok_semicolon; case '|': + token_buffer = "|"; return tok_bar; case '{': + token_buffer = "{"; return tok_left_curly; case '=': + obstack_1grow (&token_obstack, c); do { c = getc (finput); + obstack_1grow (&token_obstack, c); if (c == '\n') lineno++; } while (c == ' ' || c == '\n' || c == '\t'); + obstack_1grow (&token_obstack, '\0'); + token_buffer = obstack_finish (&token_obstack); if (c == '{') { - token_buffer = "={"; return tok_left_curly; } else @@ -505,71 +520,41 @@ lex (void) return parse_percent_token (); default: + obstack_1grow (&token_obstack, c); + obstack_1grow (&token_obstack, '\0'); + token_buffer = obstack_finish (&token_obstack); return tok_illegal; } } -/* the following table dictates the action taken for the various % - directives. A set_flag value causes the named flag to be set. A - retval action returns the code. */ -struct percent_table_struct -{ - const char *name; - void *set_flag; - int retval; -}; +/* This function is a strcmp, which doesn't differentiate `-' and `_' + chars. */ -struct percent_table_struct percent_table[] = +static int +option_strcmp (const char *left, const char *right) { - { "token", NULL, tok_token }, - { "term", NULL, tok_token }, - { "nterm", NULL, tok_nterm }, - { "type", NULL, tok_type }, - { "guard", NULL, tok_guard }, - { "union", NULL, tok_union }, - { "expect", NULL, tok_expect }, - { "thong", NULL, tok_thong }, - { "start", NULL, tok_start }, - { "left", NULL, tok_left }, - { "right", NULL, tok_right }, - { "nonassoc", NULL, tok_nonassoc }, - { "binary", NULL, tok_nonassoc }, - { "prec", NULL, tok_prec }, - { "locations", &locations_flag, tok_noop }, /* -l */ - { "no_lines", &no_lines_flag, tok_noop }, /* -l */ - { "raw", NULL, tok_obsolete }, /* -r */ - { "token_table", &token_table_flag, tok_noop }, /* -k */ - { "yacc", &yacc_flag, tok_noop }, /* -y */ - { "fixed_output_files",&yacc_flag, tok_noop }, /* -y */ - { "defines", &defines_flag, tok_noop }, /* -d */ - { "no_parser", &no_parser_flag, tok_noop }, /* -n */ -#if 0 - /* For the time being, this is not enabled yet, while it's possible - though, since we use obstacks. The only risk is with semantic - parsers which will output an `include' of an output file: be sure - that the naem included is indeed the name of the output file. */ - { "output_file", &spec_outfile, tok_setopt }, /* -o */ - { "file_prefix", &spec_file_prefix, tok_setopt }, /* -b */ - { "name_prefix", &spec_name_prefix, tok_setopt }, /* -p */ -#endif - { "verbose", &verbose_flag, tok_noop }, /* -v */ - { "debug", &debug_flag, tok_noop }, /* -t */ - { "semantic_parser", &semantic_parser, tok_noop }, - { "pure_parser", &pure_parser, tok_noop }, - - { NULL, NULL, tok_illegal} -}; + const unsigned char *l, *r; + int c; + + assert (left); + assert (right); + l = (const unsigned char *)left; + r = (const unsigned char *)right; + while (((c = *l - *r++) == 0 && *l != '\0') + || ((*l == '-' || *l == '_') && (*r == '_' || *r == '-'))) + l++; + return c; +} /* Parse a token which starts with %. Assumes the % has already been read and discarded. */ -int +token_t parse_percent_token (void) { - int c; - struct percent_table_struct *tx; + const struct option_table_struct *tx; - c = getc (finput); + int c = getc (finput); switch (c) { @@ -601,8 +586,8 @@ parse_percent_token (void) obstack_1grow (&token_obstack, '%'); while (isalpha (c) || c == '_' || c == '-') { - if (c == '-') - c = '_'; + if (c == '_') + c = '-'; obstack_1grow (&token_obstack, c); c = getc (finput); } @@ -612,8 +597,9 @@ parse_percent_token (void) token_buffer = obstack_finish (&token_obstack); /* table lookup % directive */ - for (tx = percent_table; tx->name; tx++) - if (strcmp (token_buffer + 1, tx->name) == 0) + for (tx = option_table; tx->name; tx++) + if ((tx->access == opt_percent || tx->access == opt_both) + && option_strcmp (token_buffer + 1, tx->name) == 0) break; if (tx->set_flag) @@ -622,7 +608,7 @@ parse_percent_token (void) return tok_noop; } - switch (tx->retval) + switch (tx->ret_val) { case tok_setopt: *((char **) (tx->set_flag)) = optarg; @@ -632,7 +618,11 @@ parse_percent_token (void) case tok_obsolete: fatal (_("`%s' is no longer supported"), token_buffer); break; + + default: + /* Other cases do not apply here. */ + break; } - return tx->retval; + return tx->ret_val; }