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

📄 reader.c

📁 bison 2.0 主要可以用来做语法分析用的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Input parser for Bison   Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003   Free Software Foundation, Inc.   This file is part of Bison, the GNU Compiler Compiler.   Bison 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.   Bison 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 Bison; see the file COPYING.  If not, write to   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.  */#include "system.h"#include <quotearg.h>#include "complain.h"#include "conflicts.h"#include "files.h"#include "getargs.h"#include "gram.h"#include "muscle_tab.h"#include "output.h"#include "reader.h"#include "symlist.h"#include "symtab.h"static symbol_list *grammar = NULL;static bool start_flag = false;merger_list *merge_functions;/* Has %union been seen?  */bool typed = false;/* Should rules have a default precedence?  */bool default_prec = true;/*-----------------------.| Set the start symbol.  |`-----------------------*/voidgrammar_start_symbol_set (symbol *sym, location loc){  if (start_flag)    complain_at (loc, _("multiple %s declarations"), "%start");  else    {      start_flag = true;      startsymbol = sym;      startsymbol_location = loc;    }}/*----------------------------------------------------------------.| There are two prologues: one before %union, one after.  Augment || the current one.                                                |`----------------------------------------------------------------*/voidprologue_augment (const char *prologue, location loc){  struct obstack *oout =    !typed ? &pre_prologue_obstack : &post_prologue_obstack;  obstack_fgrow1 (oout, "]b4_syncline([[%d]], [[", loc.start.line);  MUSCLE_OBSTACK_SGROW (oout,			quotearg_style (c_quoting_style, loc.start.file));  obstack_sgrow (oout, "]])[\n");  obstack_sgrow (oout, prologue);}/*-------------------------------------------------------------------.| Return the merger index for a merging function named NAME, whose   || arguments have type TYPE.  Records the function, if new, in        || MERGER_LIST.							     |`-------------------------------------------------------------------*/static intget_merge_function (uniqstr name, uniqstr type, location loc){  merger_list *syms;  merger_list head;  int n;  if (! glr_parser)    return 0;  if (type == NULL)    type = uniqstr_new ("");  head.next = merge_functions;  for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1)    if (UNIQSTR_EQ (name, syms->next->name))      break;  if (syms->next == NULL)    {      syms->next = xmalloc (sizeof syms->next[0]);      syms->next->name = uniqstr_new (name);      syms->next->type = uniqstr_new (type);      syms->next->next = NULL;      merge_functions = head.next;    }  else if (!UNIQSTR_EQ (type, syms->next->type))    warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),	     name, type, syms->next->type);  return n;}/*--------------------------------------.| Free all merge-function definitions.	|`--------------------------------------*/voidfree_merger_functions (void){  merger_list *L0;  if (! glr_parser)    return;  L0 = merge_functions;  while (L0 != NULL)    {      merger_list *L1 = L0->next;      free (L0);      L0 = L1;    }}/*-------------------------------------------------------------------.| Parse the input grammar into a one symbol_list structure.  Each    || rule is represented by a sequence of symbols: the left hand side   || followed by the contents of the right hand side, followed by a     || null pointer instead of a symbol to terminate the rule.  The next  || symbol is the lhs of the following rule.                           ||                                                                    || All actions are copied out, labelled by the rule number they apply || to.                                                                ||                                                                    || Bison used to allow some %directives in the rules sections, but    || this is no longer consider appropriate: (i) the documented grammar || doesn't claim it, (ii), it would promote bad style, (iii), error   || recovery for %directives consists in skipping the junk until a `%' || is seen and helrp synchronizing.  This scheme is definitely wrong  || in the rules section.                                              |`-------------------------------------------------------------------*//* The (currently) last symbol of GRAMMAR. */symbol_list *grammar_end = NULL;/* Append SYM to the grammar.  */voidgrammar_symbol_append (symbol *sym, location loc){  symbol_list *p = symbol_list_new (sym, loc);  if (grammar_end)    grammar_end->next = p;  else    grammar = p;  grammar_end = p;}/* The rule currently being defined, and the previous rule.   CURRENT_RULE points to the first LHS of the current rule, while   PREVIOUS_RULE_END points to the *end* of the previous rule (NULL).  */symbol_list *current_rule = NULL;symbol_list *previous_rule_end = NULL;/*----------------------------------------------.| Create a new rule for LHS in to the GRAMMAR.  |`----------------------------------------------*/voidgrammar_rule_begin (symbol *lhs, location loc){  if (!start_flag)    {      startsymbol = lhs;      startsymbol_location = loc;      start_flag = true;    }  /* Start a new rule and record its lhs.  */  ++nrules;  ++nritems;  previous_rule_end = grammar_end;  grammar_symbol_append (lhs, loc);  current_rule = grammar_end;  /* Mark the rule's lhs as a nonterminal if not already so.  */  if (lhs->class == unknown_sym)    {      lhs->class = nterm_sym;      lhs->number = nvars;      ++nvars;    }  else if (lhs->class == token_sym)    complain_at (loc, _("rule given for %s, which is a token"), lhs->tag);}/* Check that the last rule (CURRENT_RULE) is properly defined.  For   instance, there should be no type clash on the default action.  */static voidgrammar_current_rule_check (void){  symbol *lhs = current_rule->sym;  char const *lhs_type = lhs->type_name;  symbol *first_rhs = current_rule->next->sym;  /* If there is an action, then there is nothing we can do: the user     is allowed to shoot herself in the foot.  */  if (current_rule->action)    return;  /* Don't worry about the default action if $$ is untyped, since $$'s     value can't be used.  */  if (! lhs_type)    return;  /* If $$ is being set in default way, report if any type mismatch.  */  if (first_rhs)    {      const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";      if (!UNIQSTR_EQ (lhs_type, rhs_type))	warn_at (current_rule->location,		 _("type clash on default action: <%s> != <%s>"),		 lhs_type, rhs_type);    }  /* Warn if there is no default for $$ but we need one.  */  else    warn_at (current_rule->location,	     _("empty rule for typed nonterminal, and no action"));}/*-------------------------------------.| End the currently being grown rule.  |`-------------------------------------*/voidgrammar_rule_end (location loc){  /* Put an empty link in the list to mark the end of this rule  */  grammar_symbol_append (NULL, grammar_end->location);  current_rule->location = loc;  grammar_current_rule_check ();}/*-------------------------------------------------------------------.

⌨️ 快捷键说明

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