📄 readnfg.yy
字号:
%{//// $Source: /home/gambit/CVS/gambit/sources/game/readnfg.yy,v $// $Date: 2002/08/26 05:50:10 $// $Revision: 1.2 $//// DESCRIPTION:// Parser for reading normal form savefiles//// This file is part of Gambit// Copyright (c) 2002, The Gambit Project//// This program 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 of the License, or// (at your option) any later version.//// This program 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 this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//#include <ctype.h>#include "base/gmisc.h"#include "base/gstream.h"#include "base/glist.h"#include "math/rational.h"#include "nfg.h"#include "nfplayer.h"#include "nfstrat.h"static gInput *infile;static gText last_name; static gNumber last_number;static gText title, comment; static Nfg *N; static int ncont, pl, cont;static gList<gText> names;static gList<gNumber> numbers; static gList<gText> stratnames;static NFOutcome *outcome; static bool CreateNfg(const gList<gText> &, const gList<gNumber> &, const gList<gText> &);static void SetPayoff(int cont, int pl, const gNumber &);void nfg_yyerror(char *);int nfg_yylex(void);%}%token LBRACE%token RBRACE%token SLASH%token NAME%token VARNAME%token NUMBER%%nfgfile: header { if (!CreateNfg(names, numbers, stratnames)) return 1; names.Flush(); numbers.Flush(); stratnames.Flush(); N->SetTitle(title); N->SetComment(comment); } body { return 0; }header: NAME { title = last_name; pl = 0; } playerlist stratlist commentopt playerlist: LBRACE players RBRACEplayers: player | players playerplayer: NAME { names.Append(last_name); }stratlist: dimensionality | stratnameliststratnamelist: LBRACE playerstrlist RBRACEplayerstrlist: playerstrats | playerstrlist playerstratsplayerstrats: LBRACE { pl++; numbers.Append(0); } stratnames RBRACEstratnames: stratname | stratnames stratnamestratname: NAME { stratnames.Append(last_name); numbers[pl] += 1; }commentopt: | NAME { comment = last_name; }dimensionality: LBRACE intlist RBRACEintlist: integer | intlist integerinteger: NUMBER { numbers.Append(last_number); }body: payoffbody | outcomebodypayoffbody: { cont = 1; pl = 1; } payofflistpayofflist: payoff | payofflist payoffpayoff: NUMBER { if (pl > N->NumPlayers()) { cont++; pl = 1; } if (cont > ncont) YYERROR; SetPayoff(cont, pl, last_number); pl++; }outcomebody: outcomelist { cont = 1; } contingencylistoutcomelist: LBRACE RBRACE | LBRACE outcomes RBRACEoutcomes: outcome | outcomes outcomeoutcome: LBRACE NAME { outcome = N->NewOutcome(); outcome->SetName(last_name); pl = 1; } outcpaylist RBRACEoutcpaylist: outcpay | outcpaylist commaopt outcpayoutcpay: NUMBER { if (pl > N->NumPlayers()) YYERROR; N->SetPayoff(outcome, pl++, last_number); } commaopt: | ',' contingencylist: contingency | contingencylist contingencycontingency: NUMBER { if (cont > ncont) YYERROR; if (last_number != gNumber(0)) { N->SetOutcome(cont++, N->Outcomes()[last_number]); } else { N->SetOutcome(cont++, 0); } } %%void nfg_yyerror(char *) { }int nfg_yylex(void){ char c, d; while (1) { do { *infile >> c; } while (isspace(c)); if (c == '/') { *infile >> d; if (d == '/') { do { *infile >> d; } while (d != '\n'); } else if (d == '*') { int done = 0; while (!done) { do { *infile >> d; } while (d != '*'); *infile >> d; if (d == '/') done = 1; } } else { infile->unget(d); return SLASH; } } else break; } if (isalpha(c)) { last_name = c; *infile >> c; while (isalpha(c)) { last_name += c; *infile >> c; } infile->unget(c); return VARNAME; } if (c == '"') { infile->unget(c); *infile >> last_name; return NAME; } else if (isdigit(c) || c == '-') { infile->unget(c); *infile >> last_number; return NUMBER; } switch (c) { case '-': *infile >> c; if (isdigit(c)) { infile->unget(c); *infile >> last_number; last_number = -last_number; return NUMBER; } else { infile->unget(c); return '-'; } case '{': return LBRACE; case '}': return RBRACE; default: return c; }}bool CreateNfg(const gList<gText> &players, const gList<gNumber> &dims, const gList<gText> &strats){ if (players.Length() != dims.Length()) return false; gArray<int> dim(dims.Length()); ncont = 1; int i; for (i = 1; i <= dim.Length(); i++) { dim[i] = (int) dims[i]; ncont *= dim[i]; if (dim[i] <= 0) return false; } N = new Nfg(dim); int strat = 1; for (i = 1; i <= dim.Length(); i++) { N->Players()[i]->SetName(players[i]); if (strats.Length() > 0) for (int j = 1; j <= dim[i]; j++) N->Strategies(i)[j]->SetName(strats[strat++]); } return true;}void SetPayoff(int cont, int pl, const gNumber &value){ if (pl == 1) N->SetOutcome(cont, N->NewOutcome()); N->SetPayoff(N->GetOutcome(cont), pl, value);}static int ParseNfgFile(void){ infile->seekp(0); static char *prologue = { "NFG 1 " }; char c; for (unsigned int i = 0; i < strlen(prologue); i++) { infile->get(c); if (c != prologue[i]) return 1; } infile->get(c); switch (c) { case 'D': break; case 'R': break; default: return 1; } int ret = nfg_yyparse(); N->SetIsDirty(false); return ret; }int ReadNfgFile(gInput &p_file, Nfg *&p_nfg){ assert(!p_nfg); infile = &p_file; N = p_nfg; if (ParseNfgFile()) { if (p_nfg) { delete p_nfg; p_nfg = 0; } return 0; } p_nfg = N; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -