📄 lpgparse.c
字号:
/* $Id: lpgparse.c,v 1.4 2001/10/10 14:53:10 ericb Exp $ *//* This software is subject to the terms of the IBM Jikes Compiler License Agreement available at the following URL: http://ibm.com/developerworks/opensource/jikes. Copyright (C) 1983, 1999, 2001 International Business Machines Corporation and others. All Rights Reserved. You must accept the terms of that agreement to use this software.*/static char hostfile[] = __FILE__;#include <time.h>#include <string.h>#include <ctype.h>#include "common.h"#undef scope_state#undef SCOPE_UBOUND#undef SCOPE_SIZE#include "header.h"#include "lpgsym.h"#include "lpgdef.h"#include "lpgdcl.h"#include "lpgparse.h"#define SPACE_CODE 1#define DIGIT_CODE 2#define ALPHA_CODE 3#define IsSpace(c) (code[c] == SPACE_CODE)#define IsDigit(c) (code[c] == DIGIT_CODE)#define IsAlpha(c) (code[c] == ALPHA_CODE)static char code[256] = {0};static int output_size = 80, line_no = 0;/****************************************************************************//* PROCESS_INPUT: *//****************************************************************************//* This procedures opens all relevant files and processes the input grammar.*//****************************************************************************/void process_input(void){ time_t ltime; unsigned c;/****************************************************************************//* Open input grammar file. If the file cannot be opened and that file name *//* did not have an extension, then the extension ".g" is added to the file *//* name and we try again. If no file can be found an error message is *//* issued and the program halts. *//****************************************************************************/ if ((sysgrm = fopen(grm_file, "r")) == (FILE *) NULL) { register int i; for (i = strlen(grm_file); i > 0 && grm_file[i] != '.' && grm_file[i] != '/' && /* Unix */ grm_file[i] != '\\'; /* Dos */ i--); if (grm_file[i] != '.') { strcat(grm_file, ".g"); if ((sysgrm = fopen(grm_file, "r")) == (FILE *) NULL) { fprintf(stderr, "***ERROR: Input file %s containing grammar " "is empty, undefined, or invalid\n",grm_file); exit(12); } } else { fprintf(stderr, "***ERROR: Input file %s containing grammar " "is empty, undefined, or invalid\n",grm_file); exit(12); } }#if !defined(C370) && !defined(CW) else { if (strrchr(grm_file, '.') == NULL) { sprintf(msg_line, "A file named \"%s\" with no extension " "is being opened", grm_file); PRNTWNG(msg_line); } }#endif/****************************************************************************//* Assign timeptr to the local time. *//****************************************************************************/ time(<ime); timeptr = ctime(<ime);/****************************************************************************//* Open listing file for output. *//****************************************************************************/#if defined(C370) && !defined(CW) syslis = fopen(lis_file, "w, lrecl=85, recfm=VBA");#else syslis = fopen(lis_file, "w");#endif if (syslis == (FILE *) NULL) { fprintf(stderr, "***ERROR: Listing file \"%s\" cannot be openned.\n", lis_file); exit(12); }/****************************************************************************//* Complete the initialization of the code array used to replace the *//* builtin functions isalpha, isdigit and isspace. *//****************************************************************************/ for (c = 'a'; c <= 'z'; c++) { if (isalpha(c)) code[c] = ALPHA_CODE; } for (c = 'A'; c <= 'Z'; c++) { if (isalpha(c)) code[c] = ALPHA_CODE; } for (c = '0'; c <= '9'; c++) { if (isdigit(c)) code[c] = DIGIT_CODE; } code[' '] = SPACE_CODE; code['\n'] = SPACE_CODE; code['\t'] = SPACE_CODE; code['\r'] = SPACE_CODE; code['\v'] = SPACE_CODE; code['\f'] = SPACE_CODE;/****************************************************************************//* Print heading on terminal and in listing file *//****************************************************************************/ printf("\n %s %35.24s\n", HEADER_INFO, timeptr); PR_HEADING; init_process(); process_grammar(); exit_process(); return;}/********************************************************************//* READ_INPUT: *//********************************************************************//* READ_INPUT fills the buffer from p1 to the end. *//********************************************************************/static void read_input(void){ long num_read; num_read = input_buffer + IOBUFFER_SIZE - bufend; if ((num_read = fread(bufend, 1, num_read, sysgrm)) == 0) { if (ferror(sysgrm) != 0) { fprintf(stderr, "*** Error reading input file \"%s\".\n", grm_file); exit(12); } } bufend += num_read; *bufend = '\0'; return;}/*****************************************************************************//* INIT_PROCESS: *//*****************************************************************************//* This routine is invoked to allocate space for the global structures *//* needed to process the input grammar. *//*****************************************************************************/static void init_process(void){ /******************************************************************/ /* Set up a a pool of temporary space. */ /******************************************************************/ reset_temporary_space(); terminal = (struct terminal_type *) calloc(STACK_SIZE, sizeof(struct terminal_type)); if (terminal == (struct terminal_type *) NULL) nospace(__FILE__, __LINE__); hash_table = (struct hash_type **) calloc(HT_SIZE, sizeof(struct hash_type *)); if (hash_table == (struct hash_type **) NULL) nospace(__FILE__, __LINE__); /***********************************************************************/ /* Allocate space for input buffer and read in initial data in input */ /* file. Next, invoke PROCESS_OPTION_LINES to process all lines in */ /* input file that are options line. */ /***********************************************************************/ input_buffer = (char *) calloc(IOBUFFER_SIZE + 1 + MAX_LINE_SIZE, sizeof(char)); if (input_buffer == (char *) NULL) nospace(__FILE__, __LINE__); bufend = &input_buffer[0]; read_input(); p2 = &input_buffer[0]; linestart = p2 - 1; p1 = p2; line_no++; if (*p2 == '\0') { fprintf(stderr, "Input file \"%s\" containing grammar is " "empty, undefined, or invalid\n", grm_file); exit(12); } process_options_lines(); eolt_image = OMEGA; blockb_len = strlen(blockb); blocke_len = strlen(blocke); hblockb_len = strlen(hblockb); hblocke_len = strlen(hblocke); /*****************************************************/ /* Keywords, Reserved symbols, and predefined macros */ /*****************************************************/ kdefine[0] = escape; /*Set empty first space to the default */ kterminals[0] = escape; /* escape symbol. */ kalias[0] = escape; kstart[0] = escape; krules[0] = escape; knames[0] = escape; kend[0] = escape; krule_number[0] = escape; krule_text[0] = escape; krule_size[0] = escape; knum_rules[0] = escape; knum_terminals[0] = escape; knum_non_terminals[0] = escape; knum_symbols[0] = escape; kinput_file[0] = escape; kcurrent_line[0] = escape; knext_line[0] = escape; kstart_nt[0] = escape; keolt[0] = escape; return;}/*****************************************************************************//* EXIT_PROCESS: *//*****************************************************************************//* This routine is invoked to free all space used to process the input that *//* is no longer needed. Note that for the string_table, only the unused *//* space is released. *//*****************************************************************************/static void exit_process(void){ if (string_offset > 0) { string_table = (char *) (string_table == (char *) NULL ? malloc((string_offset) * sizeof(char)) : realloc(string_table, (string_offset) * sizeof(char))); if (string_table == (char *) NULL) nospace(__FILE__, __LINE__); } ffree(terminal); ffree(hash_table); ffree(input_buffer); ffree(rulehdr); /* allocated in action LPGACT when grammar is not empty */ return;}/*****************************************************************************//* VERIFY: *//*****************************************************************************//* VERIFY takes as argument a character string and checks whether or not each*//* character is a digit. If all are digits, then 1 is returned; if not, then *//* 0 is returned. *//*****************************************************************************/static BOOLEAN verify(char *item){ while (IsDigit(*item)) item++; return (*item == '\0');}/*****************************************************************************//* TRANSLATE: *//*****************************************************************************//* TRANSLATE takes as arguments a character array, which it folds to upper *//* to uppercase and returns. *//*****************************************************************************/static char *translate(char *str, int len){ register int i; for (i = 0; i < len; i++) str[i] = TOUPPER(str[i]); return(str);} /* end translate *//**********************************************************************//* STRXEQ: *//**********************************************************************//* Compare two character strings s1 and s2 to check whether or not s2 *//* is a substring of s1. The string s2 is assumed to be in lowercase *//* and NULL terminated. However, s1 does not have to (indeed, may not)*//* be NULL terminated. *//* *//* The test below may look awkward. For example, why not use: *//* if (tolower(s1[i]) != s2[i]) ? *//* because tolower(ch) is sometimes implemented as (ch-'A'+'a') which *//* does not work when "ch" is already a lower case character. *//* *//**********************************************************************/static BOOLEAN strxeq(char *s1, char *s2){ for (; *s2 != '\0'; s1++, s2++) { if (*s1 != *s2 && *s1 != toupper(*s2)) return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -