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

📄 reader.c

📁 GNU的词法/语法分析器bison源码
💻 C
📖 第 1 页 / 共 2 页
字号:
| The previous action turns out the be a mid-rule action.  Attach it || to the current rule, i.e., create a dummy symbol, attach it this   || mid-rule action, and append this dummy nonterminal to the current  || rule.                                                              |`-------------------------------------------------------------------*/voidgrammar_midrule_action (void){  /* Since the action was written out with this rule's number, we must     give the new rule this number by inserting the new rule before     it.  */  /* Make a DUMMY nonterminal, whose location is that of the midrule     action.  Create the MIDRULE.  */  location dummy_location = current_rule->action_location;  symbol *dummy = dummy_symbol_get (dummy_location);  symbol_list *midrule = symbol_list_new (dummy, dummy_location);  /* Make a new rule, whose body is empty, before the current one, so     that the action just read can belong to it.  */  ++nrules;  ++nritems;  /* Attach its location and actions to that of the DUMMY.  */  midrule->location = dummy_location;  midrule->action = current_rule->action;  midrule->action_location = dummy_location;  current_rule->action = NULL;  if (previous_rule_end)    previous_rule_end->next = midrule;  else    grammar = midrule;  /* End the dummy's rule.  */  previous_rule_end = symbol_list_new (NULL, dummy_location);  previous_rule_end->next = current_rule;  midrule->next = previous_rule_end;  /* Insert the dummy nonterminal replacing the midrule action into     the current rule.  */  grammar_current_rule_symbol_append (dummy, dummy_location);}/* Set the precedence symbol of the current rule to PRECSYM. */voidgrammar_current_rule_prec_set (symbol *precsym, location loc){  if (current_rule->ruleprec)    complain_at (loc, _("only one %s allowed per rule"), "%prec");  current_rule->ruleprec = precsym;}/* Attach dynamic precedence DPREC to the current rule. */voidgrammar_current_rule_dprec_set (int dprec, location loc){  if (! glr_parser)    warn_at (loc, _("%s affects only GLR parsers"), "%dprec");  if (dprec <= 0)    complain_at (loc, _("%s must be followed by positive number"), "%dprec");  else if (current_rule->dprec != 0)    complain_at (loc, _("only one %s allowed per rule"), "%dprec");  current_rule->dprec = dprec;}/* Attach a merge function NAME with argument type TYPE to current   rule. */voidgrammar_current_rule_merge_set (uniqstr name, location loc){  if (! glr_parser)    warn_at (loc, _("%s affects only GLR parsers"), "%merge");  if (current_rule->merger != 0)    complain_at (loc, _("only one %s allowed per rule"), "%merge");  current_rule->merger =    get_merge_function (name, current_rule->sym->type_name, loc);}/* Attach SYM to the current rule.  If needed, move the previous   action as a mid-rule action.  */voidgrammar_current_rule_symbol_append (symbol *sym, location loc){  if (current_rule->action)    grammar_midrule_action ();  ++nritems;  grammar_symbol_append (sym, loc);}/* Attach an ACTION to the current rule.  If needed, move the previous   action as a mid-rule action.  */voidgrammar_current_rule_action_append (const char *action, location loc){  if (current_rule->action)    grammar_midrule_action ();  current_rule->action = action;  current_rule->action_location = loc;}/*---------------------------------------------------------------.| Convert the rules into the representation using RRHS, RLHS and || RITEM.                                                         |`---------------------------------------------------------------*/static voidpackgram (void){  unsigned int itemno = 0;  rule_number ruleno = 0;  symbol_list *p = grammar;  ritem = xnmalloc (nritems, sizeof *ritem);  rules = xnmalloc (nrules, sizeof *rules);  while (p)    {      symbol *ruleprec = p->ruleprec;      rules[ruleno].user_number = ruleno;      rules[ruleno].number = ruleno;      rules[ruleno].lhs = p->sym;      rules[ruleno].rhs = ritem + itemno;      rules[ruleno].prec = NULL;      rules[ruleno].dprec = p->dprec;      rules[ruleno].merger = p->merger;      rules[ruleno].precsym = NULL;      rules[ruleno].location = p->location;      rules[ruleno].useful = true;      rules[ruleno].action = p->action;      rules[ruleno].action_location = p->action_location;      p = p->next;      while (p && p->sym)	{	  /* item_number = symbol_number.	     But the former needs to contain more: negative rule numbers. */	  ritem[itemno++] = symbol_number_as_item_number (p->sym->number);	  /* A rule gets by default the precedence and associativity	     of the last token in it.  */	  if (p->sym->class == token_sym && default_prec)	    rules[ruleno].prec = p->sym;	  if (p)	    p = p->next;	}      /* If this rule has a %prec,         the specified symbol's precedence replaces the default.  */      if (ruleprec)	{	  rules[ruleno].precsym = ruleprec;	  rules[ruleno].prec = ruleprec;	}      ritem[itemno++] = rule_number_as_item_number (ruleno);      ++ruleno;      if (p)	p = p->next;    }  if (itemno != nritems)    abort ();  if (trace_flag & trace_sets)    ritem_print (stderr);}/*------------------------------------------------------------------.| Read in the grammar specification and record it in the format     || described in gram.h.  All actions are copied into ACTION_OBSTACK, || in each case forming the body of a C function (YYACTION) which    || contains a switch statement to decide which action to execute.    |`------------------------------------------------------------------*/voidreader (void){  /* Initialize the symbol table.  */  symbols_new ();  /* Construct the accept symbol. */  accept = symbol_get ("$accept", empty_location);  accept->class = nterm_sym;  accept->number = nvars++;  /* Construct the error token */  errtoken = symbol_get ("error", empty_location);  errtoken->class = token_sym;  errtoken->number = ntokens++;  /* Construct a token that represents all undefined literal tokens.     It is always token number 2.  */  undeftoken = symbol_get ("$undefined", empty_location);  undeftoken->class = token_sym;  undeftoken->number = ntokens++;  /* Initialize the obstacks. */  obstack_init (&pre_prologue_obstack);  obstack_init (&post_prologue_obstack);  finput = xfopen (grammar_file, "r");  gram_in = finput;  gram__flex_debug = trace_flag & trace_scan;  gram_debug = trace_flag & trace_parse;  scanner_initialize ();  gram_parse ();  /* If something went wrong during the parsing, don't try to     continue.  */  if (complaint_issued)    return;  /* Grammar has been read.  Do some checking */  if (nrules == 0)    fatal (_("no rules in the input grammar"));  /* Report any undefined symbols and consider them nonterminals.  */  symbols_check_defined ();  /* If the user did not define her ENDTOKEN, do it now. */  if (!endtoken)    {      endtoken = symbol_get ("$end", empty_location);      endtoken->class = token_sym;      endtoken->number = 0;      /* Value specified by POSIX.  */      endtoken->user_token_number = 0;    }  /* Insert the initial rule, which line is that of the first rule     (not that of the start symbol):     accept: %start EOF.  */  {    symbol_list *p = symbol_list_new (accept, empty_location);    p->location = grammar->location;    p->next = symbol_list_new (startsymbol, empty_location);    p->next->next = symbol_list_new (endtoken, empty_location);    p->next->next->next = symbol_list_new (NULL, empty_location);    p->next->next->next->next = grammar;    nrules += 1;    nritems += 3;    grammar = p;  }  if (! (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars))    abort ();  xfclose (finput);  /* Assign the symbols their symbol numbers.  Write #defines for the     token symbols into FDEFINES if requested.  */  symbols_pack ();  /* Convert the grammar into the format described in gram.h.  */  packgram ();  /* The grammar as a symbol_list is no longer needed. */  LIST_FREE (symbol_list, grammar);}

⌨️ 快捷键说明

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