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

📄 gram.y

📁 这是一个C程序分析工具
💻 Y
📖 第 1 页 / 共 4 页
字号:
   mod_decisions = 0;   mod_conditions = 0;   mod_functions = 0;   is_else = is_if = FALSE;   looking_for_tag = FALSE;   is_within_function = FALSE;   current_operator = "";   current_keyword = "";   current_identifier = "";   current_type_name = "";}/*   Returns 1 if the indicated option character was specified on the   command line. E.g., for -S, it would return 1 for option('S'). If   option character is immediately followed by a decimal integer, this   function will instead return the value of that number, e.g. for -S3,   it would return 3. NOTE: 0 would be ambiguous, e.g., -S0, because 0   would also be returned if -S were not specified.*/int option(int opt_char){   char *opt_str = str_option(opt_char);   return opt_str == NULL ? 0 : strlen(opt_str) == 0 ? 1 : atoi(opt_str);}/*   Returns pointer to the part of an option following the option character.   E.g., for -Xabc=def, it would point to the "abc=def" part.*/char *str_option(int opt_char){   unsigned i;   /* (Skip the command itself, argv[0].) */   for (i = 1; i < cmd_line_argc; ++i)      if (strchr(OPT_INTRO_CHARS, cmd_line_argv[i][0]) != NULL)         if (cmd_line_argv[i][OPTION_START] == opt_char)            break;   return i < cmd_line_argc ? &cmd_line_argv[i][OPTION_STRING_START] : NULL;}/*   Return pointer to the name of the next input file in the argv array   starting with the argument that p_i points to. An input file name is   distinguished from the command-line options by not starting with one   of characters in the OPT_INTRO_CHARS string.   NOTE: argument 0 is the name of the command, not the first argument,   per se.*/char *get_next_input_file(unsigned *p_i){   for (++*p_i; *p_i < cmd_line_argc &&         strchr(OPT_INTRO_CHARS, cmd_line_argv[*p_i][0]) != NULL; ++*p_i)      ;   return *p_i < cmd_line_argc ? cmd_line_argv[*p_i] : NULL;}/*   Return pointer to the original name of the next input file in the   argv array starting with the argument that p_i points to. An original   name is specified as a command-line option. That is how an original   name is distinguished from the name of an actual input file   NOTE: argument 0 is the name of the command, not the first argument,   per se.*/char *get_next_input_file_orig_name(unsigned *p_i){   for (++*p_i; *p_i < cmd_line_argc; ++*p_i)      if (strchr(OPT_INTRO_CHARS, cmd_line_argv[*p_i][0]) != NULL &&            cmd_line_argv[*p_i][OPTION_START] == SUBST_FILE_OPT_CHAR)         break;   return *p_i < cmd_line_argc ?         &cmd_line_argv[*p_i][OPTION_STRING_START] : NULL;}/* Returns pointer to current module (file) name. */char *mod_name(void){   return input_file_orig_name;}/* Process the command-line options that affect the start of Metre. */static void check_starting_options(void){   static char *output_file_name;   char *script_file_name;   /* Get options from file rather than command line? */   script_file_name = str_option(SCRIPT_FILE_OPT_CHAR);   if (script_file_name != NULL)      get_options_from_file(script_file_name);   /* Interleave the input with the output? */   display_input = option(COPY_INPUT_OPT_CHAR);   /*      Name of listing file to contain output. This for those OS's that don't      support command-line redirection, e.g., VMS.   */   output_file_name = str_option(LISTING_OPT_CHAR);   if (output_file_name != NULL && strlen(output_file_name) > 0)   {      out_fp = fopen(output_file_name, "w");      if (out_fp == NULL)      {         out_fp = stdout;     /* Restore to previous, good output file. */         int_fatal(E_CANT_OPEN_LISTING_FILE);   /* Die. */      }   }}/*   Build a "fake" argument list and count, copy command name (argv[0])   to it, then append the options that are in the file to it. (Sneaky,   aren't I?) (Perhaps the arguments from the file should be appended   to whatever is on the command line. Maybe next time.)*/static void get_options_from_file(char *file){   FILE *cmd_fp;   /*      If other options on command line, generate warning but continue.      Note: 2 = the command itself + the file option.   */   if (cmd_line_argc > 2)      int_warn(W_OPTIONS_IGNORED);   /* Attempt to open the specified script file. */   if (strlen(file) == 0 || (cmd_fp = fopen(file, "r")) == NULL)      int_fatal(E_CANT_OPEN_COMMAND_FILE);   else   {      ARG *args = NULL, *args_tail = NULL;      char buf[BUFSIZ];      /*         Initialize argc to 1 for the command name which is carried over         from the orginal argv.      */      cmd_line_argc = 1;      /* Loop for each line of input. */      while (fgets(buf, sizeof buf, cmd_fp) != NULL)      {         char *start;   /* Buffer address 1st time through loop, then NULL. */         char *token;   /* Pointer to token in buffer. */         /* Loop for each token in this line of input. */         for (start = buf; (token = strtok(start, WHITE_SPACE_CHARS)) != NULL;               start = NULL)         {            ARG *arg;            /*               Allocate buffers for this argument and its string               (including its '\0' terminator).            */            if ((arg = (ARG *)malloc(sizeof *arg)) == NULL)               int_fatal(E_NO_HEAP);            if ((arg->string = (char *)malloc(strlen(token) + 1)) == NULL)               int_fatal(E_NO_HEAP);            /* Copy argument into string buffer. */            strcpy(arg->string, token);            /* Attach this argument to end of argument linked list. */            if (args_tail == NULL)               args = arg;            else               args_tail->next = arg;            args_tail = arg;            arg->next = NULL;            ++cmd_line_argc;         }      }      /* Allocate buffer for argv array then move arguments from linked list. */      build_new_argv(args);   }}/* Build a new list of "command-line arguments" pointed to by cmd_line_argv. */static void build_new_argv(ARG *args){   unsigned i;   char *argv_cmd_name;   /* Save pointer to command name from original argv. */   argv_cmd_name = cmd_line_argv[0];   /* Allocate buffer to hold array of pointers to arguments. */   cmd_line_argv = (char **)malloc(cmd_line_argc * sizeof *cmd_line_argv);   if (cmd_line_argv == NULL)      int_fatal(E_NO_HEAP);   /* Restore pointer to command name. */   cmd_line_argv[0] = argv_cmd_name;   /*      Fill in new argv from linked list of arguments, freeing list      entries but not the strings from the list.  (Skip the place for      the "command" argument.)   */   for (i = 1; i < cmd_line_argc; ++i)   {      ARG *arg;      cmd_line_argv[i] = args->string;      arg = args->next;      free(args);      args = arg;   }}/* Print name, version, and copyright notice. */static void print_banner(void){   fprintf(out_fp, "METRE Version %s  ", metre_version);   fputs("Copyright (c) 1993-1995 by Paul Long  All rights reserved.\n", out_fp);}/* Print Metre command-usage information. */static void print_help(void){   fprintf(out_fp, "Syntax: %s [ option | file ]...\n", command_name);   fprintf(out_fp, "-%cxxx=[xxx] Define identifier          "         "-%cxxx       Name of output file\n",         DEFINE_OPT_CHAR, LISTING_OPT_CHAR);   fprintf(out_fp, "-%cxxx       Substitute file name       "         "-%c          Copy input to output\n",         SUBST_FILE_OPT_CHAR, COPY_INPUT_OPT_CHAR);   fprintf(out_fp, "-%c          Suppress warnings          "         "-%c          This help\n", NO_WARNINGS_OPT_CHAR, HELP_OPT_CHAR);   fprintf(out_fp, "-%cxxx       Response file\n", SCRIPT_FILE_OPT_CHAR);   /* Fire the project-help trigger. */   ZERO(int_prj);   int_prj.help = TRUE;   fire_prj();   int_prj.help = FALSE;}/* Called at the beginning of a function definition. */static void stat_func_begin(void){   /* Fire the beginning-of-function trigger. */   ZERO(int_fcn);   int_fcn.begin = TRUE;   fire_fcn();   int_fcn.begin = FALSE;   /* Initialize variables relating to a function. */   depth = 0;   is_within_function = TRUE;   fcn_decisions = 0;   fcn_conditions = 0;   previous_statements_line_number = 0;   /* Install starting counts. Replaced with deltas at end-of-function. */   int_fcn.lines.white = int_mod.lines.white;   int_fcn.lines.com = int_mod.lines.com;   int_fcn.lines.code = int_mod.lines.code;   int_fcn.lines.total = lineno();}/* Called at the end of a function definition. */static void stat_func_end(void){   /*      Replace initial counts with their deltas to arrive at totals for      the function.   */   int_fcn.lines.white = int_mod.lines.white - int_fcn.lines.white;   int_fcn.lines.com = int_mod.lines.com - int_fcn.lines.com;   int_fcn.lines.code = int_mod.lines.code - int_fcn.lines.code;   int_fcn.lines.total = lineno() - int_fcn.lines.total;   ++mod_functions;                 /* Increment function count. */   /* Accumulate function decision and condition counts into module counts. */   mod_decisions += fcn_decisions;   mod_conditions += fcn_conditions;   /*      Install the rest of the function-related information into the      function structure and fire the end-of-function trigger.   */   int_fcn.decisions = fcn_decisions;   int_fcn.conditions = fcn_conditions;   int_fcn.end = TRUE;   fire_fcn();   ZERO(int_fcn);   /*      Clear variables that would otherwise indicate that we are still      parsing a function.   */   strcpy(function_name, "");   is_within_function = FALSE;}/*   Returns pointer to current function name, or an empty string if not   in a function.*/char *fcn_name(void){   return function_name;}/*   Increment the number of statements for the current line. This   function is called whenever a statement is encountered. If the   current line number is the same as when the last statement was   encountered and if this is not the special situation of "else if,"   the counter is incremented.*/static void check_multiple_statements(void){   if (previous_statements_line_number == lineno())      if (is_else && is_if)         ;        /* do nothing */      else         ++int_lin.statements;   else      previous_statements_line_number = lineno();   is_else = is_if = FALSE;}/*   This is true for all of the fire_*() functions: Copy the internal   structure to the exported structure, allow the triggers to fire in   the rules() function, then zero-fill the exported structure so that   unrelated rules won't execute when other triggers are fired.*/void fire_prj(void){   prj = int_prj;   rules();   ZERO(prj);}void fire_mod(void){   mod = int_mod;   rules();   ZERO(mod);}static void fire_fcn(void){   fcn = int_fcn;   rules();   ZERO(fcn);}static void fire_stm(void){   stm = int_stm;   rules();   ZERO(stm);}void fire_lin(void){   lin = int_lin;   rules();   ZERO(lin);}void fire_lex(void){   lex = int_lex;   rules();   ZERO(lex);}void fire_grm(void){   grm = int_grm;   rules();   ZERO(grm);}/* Fire the operator trigger. */static void fire_operator(void){   current_operator = token();   int_grm.is_operator = TRUE;   fire_grm();   int_grm.is_operator = FALSE;   current_operator = "";}/* Fire the keyword trigger. */static void fire_keyword(void){   current_keyword = token();   int_grm.is_keyword = TRUE;   fire_grm();   int_grm.is_keyword = FALSE;   current_keyword = "";}/* Fire the identifier trigger. */static void fire_identifier(void){   current_identifier = token();   int_grm.is_identifier = TRUE;   fire_grm();   int_grm.is_identifier = FALSE;   current_identifier = "";}/* Fire the declarator trigger. */static void fire_declarator(void){   int_grm.is_declarator = TRUE;   fire_grm();   int_grm.is_declarator = FALSE;}/* Fire the type-name trigger. */static void fire_type_name(void){   current_type_name = token();   int_grm.is_type_name = TRUE;   fire_grm();   int_grm.is_type_name = FALSE;   current_type_name = "";}/* Fire the grammar trigger with is_constant set to TRUE. */static void found_constant(void){   int_grm.is_constant = TRUE;   fire_grm();   ZERO(int_grm);}/* Fire the grammar trigger with is_string set to TRUE. */static void found_string(void){   int_grm.is_string = TRUE;   fire_grm();   ZERO(int_grm);}/* Indicate a function call. */static void function_call(void){   int_grm.is_call = TRUE;   fire_grm();   ZERO(int_grm);}/* Indicate an expression statement. Can be empty, i.e. just ";". */static void found_expression_statement(BOOLEAN is_empty){   check_multiple_statements();   ++int_fcn.low;          /* Low-level statement. */   /* Used to consider adjacent case labels as one decision point. */   not_case_label();   /*      Indicate at the end of an expression, low-level statement, whether      an empty expression, then fire the end-of-statement trigger.   */   int_stm.is_expr = int_stm.is_low = int_stm.end = TRUE;   int_stm.is_empty_expr = is_empty;   int_stm.depth = depth;   fire_stm();   ZERO(int_stm);}/* Return whether the specified operator is the current operator. */BOOLEAN oper(char *op){   return grm.is_operator && strcmp(current_operator, op) == 0;}/* Return whether the specified keyword is the current keyword. */BOOLEAN keyword(char *name){   return grm.is_keyword && strcmp(current_keyword, name) == 0;}/* Return whether the specified identifier is the current identifier. */BOOLEAN identifier(char *name){   return grm.is_identifier && strcmp(current_identifier, name) == 0;}/*   Indicate the beginning of the declarations within a compound   statement, whether or not there were any, and the depth at which they   occured.*/static void before_compound_declarations(void){   int_stm.before_compound_declarations = TRUE;   int_stm.depth = depth;   fire_stm();   ZERO(int_stm);}/*   Indicate the end of the declarations within a compound statement,   whether or not there were any, and the depth at which they occured.*/static void after_compound_declarations(void){   int_stm.after_compound_declarations = TRUE;   int_stm.depth = depth;   fire_stm();   ZERO(int_stm);}/*   Indicate the beginning of an initializer (before the "=") and the   depth at which it occurs.*/static void before_initializer(void){   int_stm.before_initializer = TRUE;   int_stm.depth = depth;   fire_stm();   ZERO(int_stm);}/* Indicate the end of an initializer and the depth at which it occured. */static void after_initializer(void){   int_stm.after_initializer = TRUE;   int_stm.depth = depth;   fire_stm();   ZERO(int_stm);}/*   Return pointer to identifier that corresponds to when grammar   identifier trigger is fired.*/char *this_identifier(void){   return current_identifier;}/* Return pointer to last-encountered identifier. */char *last_identifier(void){   return last_ident;}/* Return pointer to last-encountered declarator. */char *last_declarator(void){   return last_decl;}/*   When prj.cmd_name is true, a rule may provide the name of the command   that invokes this program. The default is "METRE".*/void cmd_name(char *name){   if (name != NULL)      command_name = name;}/* Return command-line argument count. */int argc(void){   return cmd_line_argc;}/* Return pointer to command-line-argument array. */char **argv(void){   return cmd_line_argv;}

⌨️ 快捷键说明

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