yacc.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <ctype.h>
  13. #define Bungetrune Bungetc /* ok for now. */
  14. /*
  15. * all these are 32 bit
  16. */
  17. #define TBITSET ((32+NTERMS)/32) /* BOTCH?? +31 */
  18. #define BIT(a,i) ((a)[(i)>>5] & (1<<((i)&037)))
  19. #define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037)))
  20. #define NWORDS(n) (((n)+32)/32)
  21. #define PARSER "/sys/lib/yaccpar"
  22. #define PARSERS "/sys/lib/yaccpars"
  23. #define TEMPNAME "y.tmp.XXXXXX"
  24. #define ACTNAME "y.acts.XXXXXX"
  25. #define OFILE "tab.c"
  26. #define FILEU "output"
  27. #define FILED "tab.h"
  28. #define FILEDEBUG "debug"
  29. enum
  30. {
  31. /*
  32. * the following are adjustable
  33. * according to memory size
  34. */
  35. ACTSIZE = 40000,
  36. MEMSIZE = 40000,
  37. NSTATES = 2000,
  38. NTERMS = 511,
  39. NPROD = 1600,
  40. NNONTERM = 600,
  41. TEMPSIZE = 2000,
  42. CNAMSZ = 10000,
  43. LSETSIZE = 2400,
  44. WSETSIZE = 350,
  45. NAMESIZE = 50,
  46. NTYPES = 63,
  47. ISIZE = 400,
  48. PRIVATE = 0xE000, /* unicode private use */
  49. /* relationships which must hold:
  50. TBITSET ints must hold NTERMS+1 bits...
  51. WSETSIZE >= NNONTERM
  52. LSETSIZE >= NNONTERM
  53. TEMPSIZE >= NTERMS + NNONTERM + 1
  54. TEMPSIZE >= NSTATES
  55. */
  56. NTBASE = 010000,
  57. ERRCODE = 8190,
  58. ACCEPTCODE = 8191,
  59. NOASC = 0, /* no assoc. */
  60. LASC = 1, /* left assoc. */
  61. RASC = 2, /* right assoc. */
  62. BASC = 3, /* binary assoc. */
  63. /* flags for state generation */
  64. DONE = 0,
  65. MUSTDO = 1,
  66. MUSTLOOKAHEAD = 2,
  67. /* flags for a rule having an action, and being reduced */
  68. ACTFLAG = 04,
  69. REDFLAG = 010,
  70. /* output parser flags */
  71. YYFLAG1 = -1000,
  72. /* parse tokens */
  73. IDENTIFIER = PRIVATE,
  74. MARK,
  75. TERM,
  76. LEFT,
  77. RIGHT,
  78. BINARY,
  79. PREC,
  80. LCURLY,
  81. IDENTCOLON,
  82. NUMBER,
  83. START,
  84. TYPEDEF,
  85. TYPENAME,
  86. UNION,
  87. ENDFILE = 0,
  88. EMPTY = 1,
  89. WHOKNOWS = 0,
  90. OK = 1,
  91. NOMORE = -1000,
  92. };
  93. /* macros for getting associativity and precedence levels */
  94. #define ASSOC(i) ((i)&03)
  95. #define PLEVEL(i) (((i)>>4)&077)
  96. #define TYPE(i) (((i)>>10)&077)
  97. /* macros for setting associativity and precedence levels */
  98. #define SETASC(i,j) i |= j
  99. #define SETPLEV(i,j) i |= (j<<4)
  100. #define SETTYPE(i,j) i |= (j<<10)
  101. /* looping macros */
  102. #define TLOOP(i) for(i=1; i<=ntokens; i++)
  103. #define NTLOOP(i) for(i=0; i<=nnonter; i++)
  104. #define PLOOP(s,i) for(i=s; i<nprod; i++)
  105. #define SLOOP(i) for(i=0; i<nstate; i++)
  106. #define WSBUMP(x) x++
  107. #define WSLOOP(s,j) for(j=s; j<cwp; j++)
  108. #define ITMLOOP(i,p,q) for(q=pstate[i+1], p=pstate[i]; p<q; p++)
  109. #define SETLOOP(i) for(i=0; i<tbitset; i++)
  110. /* command to clobber tempfiles after use */
  111. #define ZAPFILE(x) if(x) remove(x)
  112. /* I/O descriptors */
  113. Biobuf* faction; /* file for saving actions */
  114. Biobuf* fdefine; /* file for #defines */
  115. Biobuf* fdebug; /* y.debug for strings for debugging */
  116. Biobuf* ftable; /* y.tab.c file */
  117. Biobuf* ftemp; /* tempfile to pass 2 */
  118. Biobuf* finput; /* input file */
  119. Biobuf* foutput; /* y.output file */
  120. /* communication variables between various I/O routines */
  121. char* infile; /* input file name */
  122. int numbval; /* value of an input number */
  123. char tokname[NAMESIZE+UTFmax+1]; /* input token name, slop for runes and 0 */
  124. /* structure declarations */
  125. typedef
  126. struct
  127. {
  128. int lset[TBITSET];
  129. } Lkset;
  130. typedef
  131. struct
  132. {
  133. int* pitem;
  134. Lkset* look;
  135. } Item;
  136. typedef
  137. struct
  138. {
  139. char* name;
  140. int value;
  141. } Symb;
  142. typedef
  143. struct
  144. {
  145. int* pitem;
  146. int flag;
  147. Lkset ws;
  148. } Wset;
  149. /* storage of names */
  150. char cnames[CNAMSZ]; /* place where token and nonterminal names are stored */
  151. int cnamsz = CNAMSZ; /* size of cnames */
  152. char* cnamp = cnames; /* place where next name is to be put in */
  153. int ndefout = 4; /* number of defined symbols output */
  154. char* tempname;
  155. char* actname;
  156. char ttempname[] = TEMPNAME;
  157. char tactname[] = ACTNAME;
  158. char* parser = PARSER;
  159. char* yydebug;
  160. /* storage of types */
  161. int ntypes; /* number of types defined */
  162. char* typeset[NTYPES]; /* pointers to type tags */
  163. /* token information */
  164. int ntokens = 0 ; /* number of tokens */
  165. Symb tokset[NTERMS];
  166. int toklev[NTERMS]; /* vector with the precedence of the terminals */
  167. /* nonterminal information */
  168. int nnonter = -1; /* the number of nonterminals */
  169. Symb nontrst[NNONTERM];
  170. int start; /* start symbol */
  171. /* assigned token type values */
  172. int extval = 0;
  173. char* ytabc = OFILE; /* name of y.tab.c */
  174. /* grammar rule information */
  175. int mem0[MEMSIZE] ; /* production storage */
  176. int* mem = mem0;
  177. int nprod = 1; /* number of productions */
  178. int* prdptr[NPROD]; /* pointers to descriptions of productions */
  179. int levprd[NPROD]; /* precedence levels for the productions */
  180. int rlines[NPROD]; /* line number for this rule */
  181. /* state information */
  182. int nstate = 0; /* number of states */
  183. Item* pstate[NSTATES+2]; /* pointers to the descriptions of the states */
  184. int tystate[NSTATES]; /* contains type information about the states */
  185. int defact[NSTATES]; /* the default actions of states */
  186. int tstates[NTERMS]; /* states generated by terminal gotos */
  187. int ntstates[NNONTERM]; /* states generated by nonterminal gotos */
  188. int mstates[NSTATES]; /* chain of overflows of term/nonterm generation lists */
  189. int lastred; /* the number of the last reduction of a state */
  190. /* lookahead set information */
  191. Lkset lkst[LSETSIZE];
  192. int nolook; /* flag to turn off lookahead computations */
  193. int tbitset; /* size of lookahead sets */
  194. int nlset = 0; /* next lookahead set index */
  195. int nolook = 0; /* flag to suppress lookahead computations */
  196. Lkset clset; /* temporary storage for lookahead computations */
  197. /* working set information */
  198. Wset wsets[WSETSIZE];
  199. Wset* cwp;
  200. /* storage for action table */
  201. int amem[ACTSIZE]; /* action table storage */
  202. int* memp = amem; /* next free action table position */
  203. int indgo[NSTATES]; /* index to the stored goto table */
  204. /* temporary vector, indexable by states, terms, or ntokens */
  205. int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */
  206. int lineno = 1; /* current input line number */
  207. int fatfl = 1; /* if on, error is fatal */
  208. int nerrors = 0; /* number of errors */
  209. /* statistics collection variables */
  210. int zzgoent;
  211. int zzgobest;
  212. int zzacent;
  213. int zzexcp;
  214. int zzclose;
  215. int zzrrconf;
  216. int zzsrconf;
  217. int* ggreed = lkst[0].lset;
  218. int* pgo = wsets[0].ws.lset;
  219. int* yypgo = &nontrst[0].value;
  220. int maxspr = 0; /* maximum spread of any entry */
  221. int maxoff = 0; /* maximum offset into a array */
  222. int* pmem = mem0;
  223. int* maxa;
  224. int nxdb = 0;
  225. int adb = 0;
  226. /* storage for information about the nonterminals */
  227. int** pres[NNONTERM+2]; /* vector of pointers to productions yielding each nonterminal */
  228. Lkset* pfirst[NNONTERM+2]; /* vector of pointers to first sets for each nonterminal */
  229. int pempty[NNONTERM+1]; /* vector of nonterminals nontrivially deriving e */
  230. /* random stuff picked out from between functions */
  231. int indebug = 0;
  232. Wset* zzcwp = wsets;
  233. int zzgoent = 0;
  234. int zzgobest = 0;
  235. int zzacent = 0;
  236. int zzexcp = 0;
  237. int zzclose = 0;
  238. int zzsrconf = 0;
  239. int* zzmemsz = mem0;
  240. int zzrrconf = 0;
  241. int pidebug = 0; /* debugging flag for putitem */
  242. int gsdebug = 0;
  243. int cldebug = 0; /* debugging flag for closure */
  244. int pkdebug = 0;
  245. int g2debug = 0;
  246. struct
  247. {
  248. char* name;
  249. int32_t value;
  250. } resrv[] =
  251. {
  252. {"binary", BINARY},
  253. {"left", LEFT},
  254. {"nonassoc", BINARY},
  255. {"prec", PREC},
  256. {"right", RIGHT},
  257. {"start", START},
  258. {"term", TERM},
  259. {"token", TERM},
  260. {"type", TYPEDEF},
  261. {"union", UNION},
  262. {nil, 0},
  263. };
  264. /* define functions */
  265. void main(int, char**);
  266. void others(void);
  267. char* chcopy(char*, char*);
  268. char* writem(int*);
  269. char* symnam(int);
  270. void summary(void);
  271. void error(char*, ...);
  272. void aryfil(int*, int, int);
  273. int setunion(int*, int*);
  274. void prlook(Lkset*);
  275. void cpres(void);
  276. void cpfir(void);
  277. int state(int);
  278. void putitem(int*, Lkset*);
  279. void cempty(void);
  280. void stagen(void);
  281. void closure(int);
  282. Lkset* flset(Lkset*);
  283. void cleantmp(void);
  284. void intr(void);
  285. void setup(int, char**);
  286. void finact(void);
  287. int defin(int, char*);
  288. void defout(int);
  289. char* cstash(char*);
  290. int32_t gettok(void);
  291. int fdtype(int);
  292. int chfind(int, char*);
  293. void cpyunion(void);
  294. void cpycode(void);
  295. int skipcom(void);
  296. void cpyact(int);
  297. void openup(char*, int, int, int, char*);
  298. void output(void);
  299. int apack(int*, int);
  300. void go2out(void);
  301. void go2gen(int);
  302. void precftn(int, int, int);
  303. void wract(int);
  304. void wrstate(int);
  305. void warray(char*, int*, int);
  306. void hideprod(void);
  307. void callopt(void);
  308. void gin(int);
  309. void stin(int);
  310. int nxti(void);
  311. void osummary(void);
  312. void aoutput(void);
  313. void arout(char*, int*, int);
  314. int gtnm(void);
  315. void
  316. main(int argc, char *argv[])
  317. {
  318. setup(argc, argv); /* initialize and read productions */
  319. tbitset = NWORDS(ntokens);
  320. cpres(); /* make table of which productions yield a given nonterminal */
  321. cempty(); /* make a table of which nonterminals can match the empty string */
  322. cpfir(); /* make a table of firsts of nonterminals */
  323. stagen(); /* generate the states */
  324. output(); /* write the states and the tables */
  325. go2out();
  326. hideprod();
  327. summary();
  328. callopt();
  329. others();
  330. exits(0);
  331. }
  332. /*
  333. * put out other arrays, copy the parsers
  334. */
  335. void
  336. others(void)
  337. {
  338. int c, i, j;
  339. finput = Bopen(parser, OREAD);
  340. if(finput == 0)
  341. error("cannot find parser %s", parser);
  342. warray("yyr1", levprd, nprod);
  343. aryfil(temp1, nprod, 0);
  344. PLOOP(1, i)
  345. temp1[i] = prdptr[i+1]-prdptr[i]-2;
  346. warray("yyr2", temp1, nprod);
  347. aryfil(temp1, nstate, -1000);
  348. TLOOP(i)
  349. for(j=tstates[i]; j!=0; j=mstates[j])
  350. temp1[j] = i;
  351. NTLOOP(i)
  352. for(j=ntstates[i]; j!=0; j=mstates[j])
  353. temp1[j] = -i;
  354. warray("yychk", temp1, nstate);
  355. warray("yydef", defact, nstate);
  356. /* put out token translation tables */
  357. /* table 1 has 0-256 */
  358. aryfil(temp1, 256, 0);
  359. c = 0;
  360. TLOOP(i) {
  361. j = tokset[i].value;
  362. if(j >= 0 && j < 256) {
  363. if(temp1[j]) {
  364. print("yacc bug -- cant have 2 different Ts with same value\n");
  365. print(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name);
  366. nerrors++;
  367. }
  368. temp1[j] = i;
  369. if(j > c)
  370. c = j;
  371. }
  372. }
  373. warray("yytok1", temp1, c+1);
  374. /* table 2 has PRIVATE-PRIVATE+256 */
  375. aryfil(temp1, 256, 0);
  376. c = 0;
  377. TLOOP(i) {
  378. j = tokset[i].value - PRIVATE;
  379. if(j >= 0 && j < 256) {
  380. if(temp1[j]) {
  381. print("yacc bug -- cant have 2 different Ts with same value\n");
  382. print(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name);
  383. nerrors++;
  384. }
  385. temp1[j] = i;
  386. if(j > c)
  387. c = j;
  388. }
  389. }
  390. warray("yytok2", temp1, c+1);
  391. /* table 3 has everything else */
  392. Bprint(ftable, "int32_t yytok3[] =\n{\n");
  393. c = 0;
  394. TLOOP(i) {
  395. j = tokset[i].value;
  396. if(j >= 0 && j < 256)
  397. continue;
  398. if(j >= PRIVATE && j < 256+PRIVATE)
  399. continue;
  400. Bprint(ftable, "%4d,%4d,", j, i);
  401. c++;
  402. if(c%5 == 0)
  403. Bprint(ftable, "\n");
  404. }
  405. Bprint(ftable, "%4d\n};\n", 0);
  406. /* copy parser text */
  407. while((c=Bgetrune(finput)) != Beof) {
  408. if(c == '$') {
  409. if((c = Bgetrune(finput)) != 'A')
  410. Bputrune(ftable, '$');
  411. else { /* copy actions */
  412. faction = Bopen(actname, OREAD);
  413. if(faction == 0)
  414. error("cannot reopen action tempfile");
  415. while((c=Bgetrune(faction)) != Beof)
  416. Bputrune(ftable, c);
  417. Bterm(faction);
  418. ZAPFILE(actname);
  419. c = Bgetrune(finput);
  420. }
  421. }
  422. Bputrune(ftable, c);
  423. }
  424. Bterm(ftable);
  425. }
  426. /*
  427. * copies string q into p, returning next free char ptr
  428. */
  429. char*
  430. chcopy(char* p, char* q)
  431. {
  432. int c;
  433. while((c = *q) != 0){
  434. if(c == '"')
  435. *p++ = '\\';
  436. *p++ = c;
  437. q++;
  438. }
  439. *p = 0;
  440. return p;
  441. }
  442. /*
  443. * creates output string for item pointed to by pp
  444. */
  445. char*
  446. writem(int *pp)
  447. {
  448. int i,*p;
  449. static char sarr[ISIZE];
  450. char* q;
  451. for(p=pp; *p>0; p++)
  452. ;
  453. p = prdptr[-*p];
  454. q = chcopy(sarr, nontrst[*p-NTBASE].name);
  455. q = chcopy(q, ": ");
  456. for(;;) {
  457. *q = ' ';
  458. p++;
  459. if(p == pp)
  460. *q = '.';
  461. q++;
  462. *q = '\0';
  463. i = *p;
  464. if(i <= 0)
  465. break;
  466. q = chcopy(q, symnam(i));
  467. if(q > &sarr[ISIZE-30])
  468. error("item too big");
  469. }
  470. /* an item calling for a reduction */
  471. i = *pp;
  472. if(i < 0 ) {
  473. q = chcopy(q, " (");
  474. sprint(q, "%d)", -i);
  475. }
  476. return sarr;
  477. }
  478. /*
  479. * return a pointer to the name of symbol i
  480. */
  481. char*
  482. symnam(int i)
  483. {
  484. char* cp;
  485. cp = (i >= NTBASE)? nontrst[i-NTBASE].name: tokset[i].name;
  486. if(*cp == ' ')
  487. cp++;
  488. return cp;
  489. }
  490. /*
  491. * output the summary on y.output
  492. */
  493. void
  494. summary(void)
  495. {
  496. if(foutput != 0) {
  497. Bprint(foutput, "\n%d/%d terminals, %d/%d nonterminals\n",
  498. ntokens, NTERMS, nnonter, NNONTERM);
  499. Bprint(foutput, "%d/%d grammar rules, %d/%d states\n",
  500. nprod, NPROD, nstate, NSTATES);
  501. Bprint(foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n",
  502. zzsrconf, zzrrconf);
  503. Bprint(foutput, "%d/%d working sets used\n",
  504. (int)(zzcwp-wsets), WSETSIZE);
  505. Bprint(foutput, "memory: states,etc. %d/%d, parser %d/%d\n",
  506. (int)(zzmemsz-mem0), MEMSIZE, (int)(memp-amem), ACTSIZE);
  507. Bprint(foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE);
  508. Bprint(foutput, "%d extra closures\n", zzclose - 2*nstate);
  509. Bprint(foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp);
  510. Bprint(foutput, "%d goto entries\n", zzgoent);
  511. Bprint(foutput, "%d entries saved by goto default\n", zzgobest);
  512. }
  513. if(zzsrconf != 0 || zzrrconf != 0) {
  514. print("\nconflicts: ");
  515. if(zzsrconf)
  516. print("%d shift/reduce", zzsrconf);
  517. if(zzsrconf && zzrrconf)
  518. print(", ");
  519. if(zzrrconf)
  520. print("%d reduce/reduce", zzrrconf);
  521. print("\n");
  522. }
  523. if(ftemp != 0) {
  524. Bterm(ftemp);
  525. ftemp = 0;
  526. }
  527. if(fdefine != 0) {
  528. Bterm(fdefine);
  529. fdefine = 0;
  530. }
  531. }
  532. /*
  533. * write out error comment -- NEEDS WORK
  534. */
  535. void
  536. error(char *s, ...)
  537. {
  538. nerrors++;
  539. fprint(2, "\n fatal error:");
  540. fprint(2, s, (&s)[1]);
  541. fprint(2, ", %s:%d\n", infile, lineno);
  542. if(!fatfl)
  543. return;
  544. summary();
  545. cleantmp();
  546. exits("error");
  547. }
  548. /*
  549. * set elements 0 through n-1 to c
  550. */
  551. void
  552. aryfil(int *v, int n, int c)
  553. {
  554. int i;
  555. for(i=0; i<n; i++)
  556. v[i] = c;
  557. }
  558. /*
  559. * set a to the union of a and b
  560. * return 1 if b is not a subset of a, 0 otherwise
  561. */
  562. int
  563. setunion(int *a, int *b)
  564. {
  565. int i, x, sub;
  566. sub = 0;
  567. SETLOOP(i) {
  568. x = *a;
  569. *a |= *b;
  570. if(*a != x)
  571. sub = 1;
  572. a++;
  573. b++;
  574. }
  575. return sub;
  576. }
  577. void
  578. prlook(Lkset* p)
  579. {
  580. int j, *pp;
  581. pp = p->lset;
  582. if(pp == 0)
  583. Bprint(foutput, "\tNULL");
  584. else {
  585. Bprint(foutput, " { ");
  586. TLOOP(j)
  587. if(BIT(pp,j))
  588. Bprint(foutput, "%s ", symnam(j));
  589. Bprint(foutput, "}");
  590. }
  591. }
  592. /*
  593. * compute an array with the beginnings of productions yielding given nonterminals
  594. * The array pres points to these lists
  595. * the array pyield has the lists: the total size is only NPROD+1
  596. */
  597. void
  598. cpres(void)
  599. {
  600. int c, j, i, **pmem;
  601. static int *pyield[NPROD];
  602. pmem = pyield;
  603. NTLOOP(i) {
  604. c = i+NTBASE;
  605. pres[i] = pmem;
  606. fatfl = 0; /* make undefined symbols nonfatal */
  607. PLOOP(0, j)
  608. if(*prdptr[j] == c)
  609. *pmem++ = prdptr[j]+1;
  610. if(pres[i] == pmem)
  611. error("nonterminal %s not defined!", nontrst[i].name);
  612. }
  613. pres[i] = pmem;
  614. fatfl = 1;
  615. if(nerrors) {
  616. summary();
  617. cleantmp();
  618. exits("error");
  619. }
  620. if(pmem != &pyield[nprod])
  621. error("internal Yacc error: pyield %d", pmem-&pyield[nprod]);
  622. }
  623. /*
  624. * compute an array with the first of nonterminals
  625. */
  626. void
  627. cpfir(void)
  628. {
  629. int *p, **s, i, **t, ch, changes;
  630. zzcwp = &wsets[nnonter];
  631. NTLOOP(i) {
  632. aryfil(wsets[i].ws.lset, tbitset, 0);
  633. t = pres[i+1];
  634. /* initially fill the sets */
  635. for(s=pres[i]; s<t; ++s)
  636. for(p = *s; (ch = *p) > 0; ++p) {
  637. if(ch < NTBASE) {
  638. SETBIT(wsets[i].ws.lset, ch);
  639. break;
  640. }
  641. if(!pempty[ch-NTBASE])
  642. break;
  643. }
  644. }
  645. /* now, reflect transitivity */
  646. changes = 1;
  647. while(changes) {
  648. changes = 0;
  649. NTLOOP(i) {
  650. t = pres[i+1];
  651. for(s = pres[i]; s < t; ++s)
  652. for(p = *s; (ch = (*p-NTBASE)) >= 0; ++p) {
  653. changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset);
  654. if(!pempty[ch])
  655. break;
  656. }
  657. }
  658. }
  659. NTLOOP(i)
  660. pfirst[i] = flset(&wsets[i].ws);
  661. if(!indebug)
  662. return;
  663. if(foutput != 0)
  664. NTLOOP(i) {
  665. Bprint(foutput, "\n%s: ", nontrst[i].name);
  666. prlook(pfirst[i]);
  667. Bprint(foutput, " %d\n", pempty[i]);
  668. }
  669. }
  670. /*
  671. * sorts last state,and sees if it equals earlier ones. returns state number
  672. */
  673. int
  674. state(int c)
  675. {
  676. Item *p1, *p2, *k, *l, *q1, *q2;
  677. int size1, size2, i;
  678. p1 = pstate[nstate];
  679. p2 = pstate[nstate+1];
  680. if(p1 == p2)
  681. return 0; /* null state */
  682. /* sort the items */
  683. for(k = p2-1; k > p1; k--) /* make k the biggest */
  684. for(l = k-1; l >= p1; --l)
  685. if(l->pitem > k->pitem) {
  686. int *s;
  687. Lkset *ss;
  688. s = k->pitem;
  689. k->pitem = l->pitem;
  690. l->pitem = s;
  691. ss = k->look;
  692. k->look = l->look;
  693. l->look = ss;
  694. }
  695. size1 = p2 - p1; /* size of state */
  696. for(i = (c>=NTBASE)? ntstates[c-NTBASE]: tstates[c]; i != 0; i = mstates[i]) {
  697. /* get ith state */
  698. q1 = pstate[i];
  699. q2 = pstate[i+1];
  700. size2 = q2 - q1;
  701. if(size1 != size2)
  702. continue;
  703. k = p1;
  704. for(l = q1; l < q2; l++) {
  705. if(l->pitem != k->pitem)
  706. break;
  707. k++;
  708. }
  709. if(l != q2)
  710. continue;
  711. /* found it */
  712. pstate[nstate+1] = pstate[nstate]; /* delete last state */
  713. /* fix up lookaheads */
  714. if(nolook)
  715. return i;
  716. for(l = q1, k = p1; l < q2; ++l, ++k ) {
  717. int s;
  718. SETLOOP(s)
  719. clset.lset[s] = l->look->lset[s];
  720. if(setunion(clset.lset, k->look->lset)) {
  721. tystate[i] = MUSTDO;
  722. /* register the new set */
  723. l->look = flset( &clset );
  724. }
  725. }
  726. return i;
  727. }
  728. /* state is new */
  729. if(nolook)
  730. error("yacc state/nolook error");
  731. pstate[nstate+2] = p2;
  732. if(nstate+1 >= NSTATES)
  733. error("too many states");
  734. if(c >= NTBASE) {
  735. mstates[nstate] = ntstates[c-NTBASE];
  736. ntstates[c-NTBASE] = nstate;
  737. } else {
  738. mstates[nstate] = tstates[c];
  739. tstates[c] = nstate;
  740. }
  741. tystate[nstate] = MUSTDO;
  742. return nstate++;
  743. }
  744. void
  745. putitem(int *ptr, Lkset *lptr)
  746. {
  747. Item *j;
  748. if(pidebug && foutput != 0)
  749. Bprint(foutput, "putitem(%s), state %d\n", writem(ptr), nstate);
  750. j = pstate[nstate+1];
  751. j->pitem = ptr;
  752. if(!nolook)
  753. j->look = flset(lptr);
  754. pstate[nstate+1] = ++j;
  755. if((int*)j > zzmemsz) {
  756. zzmemsz = (int*)j;
  757. if(zzmemsz >= &mem0[MEMSIZE])
  758. error("out of state space");
  759. }
  760. }
  761. /*
  762. * mark nonterminals which derive the empty string
  763. * also, look for nonterminals which don't derive any token strings
  764. */
  765. void
  766. cempty(void)
  767. {
  768. int i, *p;
  769. /* first, use the array pempty to detect productions that can never be reduced */
  770. /* set pempty to WHONOWS */
  771. aryfil(pempty, nnonter+1, WHOKNOWS);
  772. /* now, look at productions, marking nonterminals which derive something */
  773. more:
  774. PLOOP(0, i) {
  775. if(pempty[*prdptr[i] - NTBASE])
  776. continue;
  777. for(p = prdptr[i]+1; *p >= 0; ++p)
  778. if(*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS)
  779. break;
  780. /* production can be derived */
  781. if(*p < 0) {
  782. pempty[*prdptr[i]-NTBASE] = OK;
  783. goto more;
  784. }
  785. }
  786. /* now, look at the nonterminals, to see if they are all OK */
  787. NTLOOP(i) {
  788. /* the added production rises or falls as the start symbol ... */
  789. if(i == 0)
  790. continue;
  791. if(pempty[i] != OK) {
  792. fatfl = 0;
  793. error("nonterminal %s never derives any token string", nontrst[i].name);
  794. }
  795. }
  796. if(nerrors) {
  797. summary();
  798. cleantmp();
  799. exits("error");
  800. }
  801. /* now, compute the pempty array, to see which nonterminals derive the empty string */
  802. /* set pempty to WHOKNOWS */
  803. aryfil( pempty, nnonter+1, WHOKNOWS);
  804. /* loop as int32_t as we keep finding empty nonterminals */
  805. again:
  806. PLOOP(1, i) {
  807. /* not known to be empty */
  808. if(pempty[*prdptr[i]-NTBASE] == WHOKNOWS) {
  809. for(p = prdptr[i]+1; *p >= NTBASE && pempty[*p-NTBASE] == EMPTY ; ++p)
  810. ;
  811. /* we have a nontrivially empty nonterminal */
  812. if(*p < 0) {
  813. pempty[*prdptr[i]-NTBASE] = EMPTY;
  814. /* got one ... try for another */
  815. goto again;
  816. }
  817. }
  818. }
  819. }
  820. /*
  821. * generate the states
  822. */
  823. void
  824. stagen(void)
  825. {
  826. int c, i, j, more;
  827. Wset *p, *q;
  828. /* initialize */
  829. nstate = 0;
  830. /* THIS IS FUNNY from the standpoint of portability
  831. * it represents the magic moment when the mem0 array, which has
  832. * been holding the productions, starts to hold item pointers, of a
  833. * different type...
  834. * someday, alloc should be used to allocate all this stuff... for now, we
  835. * accept that if pointers don't fit in integers, there is a problem...
  836. */
  837. pstate[0] = pstate[1] = (Item*)mem;
  838. aryfil(clset.lset, tbitset, 0);
  839. putitem(prdptr[0]+1, &clset);
  840. tystate[0] = MUSTDO;
  841. nstate = 1;
  842. pstate[2] = pstate[1];
  843. aryfil(amem, ACTSIZE, 0);
  844. /* now, the main state generation loop */
  845. for(more=1; more;) {
  846. more = 0;
  847. SLOOP(i) {
  848. if(tystate[i] != MUSTDO)
  849. continue;
  850. tystate[i] = DONE;
  851. aryfil(temp1, nnonter+1, 0);
  852. /* take state i, close it, and do gotos */
  853. closure(i);
  854. /* generate goto's */
  855. WSLOOP(wsets, p) {
  856. if(p->flag)
  857. continue;
  858. p->flag = 1;
  859. c = *(p->pitem);
  860. if(c <= 1) {
  861. if(pstate[i+1]-pstate[i] <= p-wsets)
  862. tystate[i] = MUSTLOOKAHEAD;
  863. continue;
  864. }
  865. /* do a goto on c */
  866. WSLOOP(p, q)
  867. /* this item contributes to the goto */
  868. if(c == *(q->pitem)) {
  869. putitem(q->pitem+1, &q->ws);
  870. q->flag = 1;
  871. }
  872. if(c < NTBASE)
  873. state(c); /* register new state */
  874. else
  875. temp1[c-NTBASE] = state(c);
  876. }
  877. if(gsdebug && foutput != 0) {
  878. Bprint(foutput, "%d: ", i);
  879. NTLOOP(j)
  880. if(temp1[j])
  881. Bprint(foutput, "%s %d, ",
  882. nontrst[j].name, temp1[j]);
  883. Bprint(foutput, "\n");
  884. }
  885. indgo[i] = apack(&temp1[1], nnonter-1) - 1;
  886. /* do some more */
  887. more = 1;
  888. }
  889. }
  890. }
  891. /*
  892. * generate the closure of state i
  893. */
  894. void
  895. closure(int i)
  896. {
  897. Wset *u, *v;
  898. Item *p, *q;
  899. int c, ch, work, k, *pi, **s, **t;
  900. zzclose++;
  901. /* first, copy kernel of state i to wsets */
  902. cwp = wsets;
  903. ITMLOOP(i, p, q) {
  904. cwp->pitem = p->pitem;
  905. cwp->flag = 1; /* this item must get closed */
  906. SETLOOP(k)
  907. cwp->ws.lset[k] = p->look->lset[k];
  908. WSBUMP(cwp);
  909. }
  910. /* now, go through the loop, closing each item */
  911. work = 1;
  912. while(work) {
  913. work = 0;
  914. WSLOOP(wsets, u) {
  915. if(u->flag == 0)
  916. continue;
  917. /* dot is before c */
  918. c = *(u->pitem);
  919. if(c < NTBASE) {
  920. u->flag = 0;
  921. /* only interesting case is where . is before nonterminal */
  922. continue;
  923. }
  924. /* compute the lookahead */
  925. aryfil(clset.lset, tbitset, 0);
  926. /* find items involving c */
  927. WSLOOP(u, v)
  928. if(v->flag == 1 && *(pi=v->pitem) == c) {
  929. v->flag = 0;
  930. if(nolook)
  931. continue;
  932. while((ch = *++pi) > 0) {
  933. /* terminal symbol */
  934. if(ch < NTBASE) {
  935. SETBIT(clset.lset, ch);
  936. break;
  937. }
  938. /* nonterminal symbol */
  939. setunion(clset.lset, pfirst[ch-NTBASE]->lset);
  940. if(!pempty[ch-NTBASE])
  941. break;
  942. }
  943. if(ch <= 0)
  944. setunion(clset.lset, v->ws.lset);
  945. }
  946. /*
  947. * now loop over productions derived from c
  948. * c is now nonterminal number
  949. */
  950. c -= NTBASE;
  951. t = pres[c+1];
  952. for(s = pres[c]; s < t; ++s) {
  953. /*
  954. * put these items into the closure
  955. * is the item there
  956. */
  957. WSLOOP(wsets, v)
  958. /* yes, it is there */
  959. if(v->pitem == *s) {
  960. if(nolook)
  961. goto nexts;
  962. if(setunion(v->ws.lset, clset.lset))
  963. v->flag = work = 1;
  964. goto nexts;
  965. }
  966. /* not there; make a new entry */
  967. if(cwp-wsets+1 >= WSETSIZE)
  968. error( "working set overflow");
  969. cwp->pitem = *s;
  970. cwp->flag = 1;
  971. if(!nolook) {
  972. work = 1;
  973. SETLOOP(k) cwp->ws.lset[k] = clset.lset[k];
  974. }
  975. WSBUMP(cwp);
  976. nexts:;
  977. }
  978. }
  979. }
  980. /* have computed closure; flags are reset; return */
  981. if(cwp > zzcwp)
  982. zzcwp = cwp;
  983. if(cldebug && foutput != 0) {
  984. Bprint(foutput, "\nState %d, nolook = %d\n", i, nolook);
  985. WSLOOP(wsets, u) {
  986. if(u->flag)
  987. Bprint(foutput, "flag set!\n");
  988. u->flag = 0;
  989. Bprint(foutput, "\t%s", writem(u->pitem));
  990. prlook(&u->ws);
  991. Bprint(foutput, "\n");
  992. }
  993. }
  994. }
  995. /*
  996. * decide if the lookahead set pointed to by p is known
  997. * return pointer to a perminent location for the set
  998. */
  999. Lkset*
  1000. flset(Lkset *p)
  1001. {
  1002. Lkset *q;
  1003. int *u, *v, *w, j;
  1004. for(q = &lkst[nlset]; q-- > lkst;) {
  1005. u = p->lset;
  1006. v = q->lset;
  1007. w = &v[tbitset];
  1008. while(v < w)
  1009. if(*u++ != *v++)
  1010. goto more;
  1011. /* we have matched */
  1012. return q;
  1013. more:;
  1014. }
  1015. /* add a new one */
  1016. q = &lkst[nlset++];
  1017. if(nlset >= LSETSIZE)
  1018. error("too many lookahead sets");
  1019. SETLOOP(j)
  1020. q->lset[j] = p->lset[j];
  1021. return q;
  1022. }
  1023. void
  1024. cleantmp(void)
  1025. {
  1026. ZAPFILE(actname);
  1027. ZAPFILE(tempname);
  1028. }
  1029. void
  1030. intr(void)
  1031. {
  1032. cleantmp();
  1033. exits("interrupted");
  1034. }
  1035. void
  1036. usage(void)
  1037. {
  1038. fprint(2, "usage: yacc [-Dn] [-vdS] [-o outputfile] [-s stem] grammar\n");
  1039. exits("usage");
  1040. }
  1041. void
  1042. setup(int argc, char *argv[])
  1043. {
  1044. int32_t c, t;
  1045. int i, j, lev, ty, ytab, *p;
  1046. int vflag, dflag, stem;
  1047. char actnm[8], *stemc, *s, dirbuf[128];
  1048. ytab = 0;
  1049. vflag = 0;
  1050. dflag = 0;
  1051. stem = 0;
  1052. stemc = "y";
  1053. foutput = 0;
  1054. fdefine = 0;
  1055. fdebug = 0;
  1056. ARGBEGIN{
  1057. case 'v':
  1058. case 'V':
  1059. vflag++;
  1060. break;
  1061. case 'D':
  1062. yydebug = EARGF(usage());
  1063. break;
  1064. case 'd':
  1065. dflag++;
  1066. break;
  1067. case 'o':
  1068. ytab++;
  1069. ytabc = EARGF(usage());
  1070. break;
  1071. case 's':
  1072. stem++;
  1073. stemc = ARGF();
  1074. break;
  1075. case 'S':
  1076. parser = PARSERS;
  1077. break;
  1078. default:
  1079. error("illegal option: %c", ARGC());
  1080. }ARGEND
  1081. openup(stemc, dflag, vflag, ytab, ytabc);
  1082. ftemp = Bopen(tempname = mktemp(ttempname), OWRITE);
  1083. faction = Bopen(actname = mktemp(tactname), OWRITE);
  1084. if(ftemp == 0 || faction == 0)
  1085. error("cannot open temp file");
  1086. if(argc < 1)
  1087. error("no input file");
  1088. infile = argv[0];
  1089. if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
  1090. i = strlen(infile)+1+strlen(dirbuf)+1+10;
  1091. s = malloc(i);
  1092. if(s != nil){
  1093. snprint(s, i, "%s/%s", dirbuf, infile);
  1094. cleanname(s);
  1095. infile = s;
  1096. }
  1097. }
  1098. finput = Bopen(infile, OREAD);
  1099. if(finput == 0)
  1100. error("cannot open '%s'", argv[0]);
  1101. cnamp = cnames;
  1102. defin(0, "$end");
  1103. extval = PRIVATE; /* tokens start in unicode 'private use' */
  1104. defin(0, "error");
  1105. defin(1, "$accept");
  1106. defin(0, "$unk");
  1107. mem = mem0;
  1108. i = 0;
  1109. for(t = gettok(); t != MARK && t != ENDFILE;)
  1110. switch(t) {
  1111. case ';':
  1112. t = gettok();
  1113. break;
  1114. case START:
  1115. if(gettok() != IDENTIFIER)
  1116. error("bad %%start construction");
  1117. start = chfind(1, tokname);
  1118. t = gettok();
  1119. continue;
  1120. case TYPEDEF:
  1121. if(gettok() != TYPENAME)
  1122. error("bad syntax in %%type");
  1123. ty = numbval;
  1124. for(;;) {
  1125. t = gettok();
  1126. switch(t) {
  1127. case IDENTIFIER:
  1128. if((t=chfind(1, tokname)) < NTBASE) {
  1129. j = TYPE(toklev[t]);
  1130. if(j != 0 && j != ty)
  1131. error("type redeclaration of token %s",
  1132. tokset[t].name);
  1133. else
  1134. SETTYPE(toklev[t], ty);
  1135. } else {
  1136. j = nontrst[t-NTBASE].value;
  1137. if(j != 0 && j != ty)
  1138. error("type redeclaration of nonterminal %s",
  1139. nontrst[t-NTBASE].name );
  1140. else
  1141. nontrst[t-NTBASE].value = ty;
  1142. }
  1143. case ',':
  1144. continue;
  1145. case ';':
  1146. t = gettok();
  1147. default:
  1148. break;
  1149. }
  1150. break;
  1151. }
  1152. continue;
  1153. case UNION:
  1154. /* copy the union declaration to the output */
  1155. cpyunion();
  1156. t = gettok();
  1157. continue;
  1158. case LEFT:
  1159. case BINARY:
  1160. case RIGHT:
  1161. i++;
  1162. case TERM:
  1163. /* nonzero means new prec. and assoc. */
  1164. lev = t-TERM;
  1165. ty = 0;
  1166. /* get identifiers so defined */
  1167. t = gettok();
  1168. /* there is a type defined */
  1169. if(t == TYPENAME) {
  1170. ty = numbval;
  1171. t = gettok();
  1172. }
  1173. for(;;) {
  1174. switch(t) {
  1175. case ',':
  1176. t = gettok();
  1177. continue;
  1178. case ';':
  1179. break;
  1180. case IDENTIFIER:
  1181. j = chfind(0, tokname);
  1182. if(j >= NTBASE)
  1183. error("%s defined earlier as nonterminal", tokname);
  1184. if(lev) {
  1185. if(ASSOC(toklev[j]))
  1186. error("redeclaration of precedence of %s", tokname);
  1187. SETASC(toklev[j], lev);
  1188. SETPLEV(toklev[j], i);
  1189. }
  1190. if(ty) {
  1191. if(TYPE(toklev[j]))
  1192. error("redeclaration of type of %s", tokname);
  1193. SETTYPE(toklev[j],ty);
  1194. }
  1195. t = gettok();
  1196. if(t == NUMBER) {
  1197. tokset[j].value = numbval;
  1198. if(j < ndefout && j > 3)
  1199. error("please define type number of %s earlier",
  1200. tokset[j].name);
  1201. t = gettok();
  1202. }
  1203. continue;
  1204. }
  1205. break;
  1206. }
  1207. continue;
  1208. case LCURLY:
  1209. defout(0);
  1210. cpycode();
  1211. t = gettok();
  1212. continue;
  1213. default:
  1214. error("syntax error");
  1215. }
  1216. if(t == ENDFILE)
  1217. error("unexpected EOF before %%");
  1218. /* t is MARK */
  1219. Bprint(ftable, "extern int yyerrflag;\n");
  1220. Bprint(ftable, "#ifndef YYMAXDEPTH\n");
  1221. Bprint(ftable, "#define YYMAXDEPTH 150\n");
  1222. Bprint(ftable, "#endif\n" );
  1223. if(!ntypes) {
  1224. Bprint(ftable, "#ifndef YYSTYPE\n");
  1225. Bprint(ftable, "#define YYSTYPE int\n");
  1226. Bprint(ftable, "#endif\n");
  1227. }
  1228. Bprint(ftable, "YYSTYPE yylval;\n");
  1229. Bprint(ftable, "YYSTYPE yyval;\n");
  1230. prdptr[0] = mem;
  1231. /* added production */
  1232. *mem++ = NTBASE;
  1233. /* if start is 0, we will overwrite with the lhs of the first rule */
  1234. *mem++ = start;
  1235. *mem++ = 1;
  1236. *mem++ = 0;
  1237. prdptr[1] = mem;
  1238. while((t=gettok()) == LCURLY)
  1239. cpycode();
  1240. if(t != IDENTCOLON)
  1241. error("bad syntax on first rule");
  1242. if(!start)
  1243. prdptr[0][1] = chfind(1, tokname);
  1244. /* read rules */
  1245. while(t != MARK && t != ENDFILE) {
  1246. /* process a rule */
  1247. rlines[nprod] = lineno;
  1248. if(t == '|')
  1249. *mem++ = *prdptr[nprod-1];
  1250. else
  1251. if(t == IDENTCOLON) {
  1252. *mem = chfind(1, tokname);
  1253. if(*mem < NTBASE)
  1254. error("token illegal on LHS of grammar rule");
  1255. mem++;
  1256. } else
  1257. error("illegal rule: missing semicolon or | ?");
  1258. /* read rule body */
  1259. t = gettok();
  1260. more_rule:
  1261. while(t == IDENTIFIER) {
  1262. *mem = chfind(1, tokname);
  1263. if(*mem < NTBASE)
  1264. levprd[nprod] = toklev[*mem];
  1265. mem++;
  1266. t = gettok();
  1267. }
  1268. if(t == PREC) {
  1269. if(gettok() != IDENTIFIER)
  1270. error("illegal %%prec syntax");
  1271. j = chfind(2, tokname);
  1272. if(j >= NTBASE)
  1273. error("nonterminal %s illegal after %%prec",
  1274. nontrst[j-NTBASE].name);
  1275. levprd[nprod] = toklev[j];
  1276. t = gettok();
  1277. }
  1278. if(t == '=') {
  1279. levprd[nprod] |= ACTFLAG;
  1280. Bprint(faction, "\ncase %d:", nprod);
  1281. cpyact(mem-prdptr[nprod]-1);
  1282. Bprint(faction, " break;");
  1283. if((t=gettok()) == IDENTIFIER) {
  1284. /* action within rule... */
  1285. sprint(actnm, "$$%d", nprod);
  1286. /* make it a nonterminal */
  1287. j = chfind(1, actnm);
  1288. /*
  1289. * the current rule will become rule number nprod+1
  1290. * move the contents down, and make room for the null
  1291. */
  1292. for(p = mem; p >= prdptr[nprod]; --p)
  1293. p[2] = *p;
  1294. mem += 2;
  1295. /* enter null production for action */
  1296. p = prdptr[nprod];
  1297. *p++ = j;
  1298. *p++ = -nprod;
  1299. /* update the production information */
  1300. levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
  1301. levprd[nprod] = ACTFLAG;
  1302. if(++nprod >= NPROD)
  1303. error("more than %d rules", NPROD);
  1304. prdptr[nprod] = p;
  1305. /* make the action appear in the original rule */
  1306. *mem++ = j;
  1307. /* get some more of the rule */
  1308. goto more_rule;
  1309. }
  1310. }
  1311. while(t == ';')
  1312. t = gettok();
  1313. *mem++ = -nprod;
  1314. /* check that default action is reasonable */
  1315. if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
  1316. /* no explicit action, LHS has value */
  1317. int tempty;
  1318. tempty = prdptr[nprod][1];
  1319. if(tempty < 0)
  1320. error("must return a value, since LHS has a type");
  1321. else
  1322. if(tempty >= NTBASE)
  1323. tempty = nontrst[tempty-NTBASE].value;
  1324. else
  1325. tempty = TYPE(toklev[tempty]);
  1326. if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
  1327. error("default action causes potential type clash");
  1328. }
  1329. nprod++;
  1330. if(nprod >= NPROD)
  1331. error("more than %d rules", NPROD);
  1332. prdptr[nprod] = mem;
  1333. levprd[nprod] = 0;
  1334. }
  1335. /* end of all rules */
  1336. defout(1);
  1337. finact();
  1338. if(t == MARK) {
  1339. Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
  1340. while((c=Bgetrune(finput)) != Beof)
  1341. Bputrune(ftable, c);
  1342. }
  1343. Bterm(finput);
  1344. }
  1345. /*
  1346. * finish action routine
  1347. */
  1348. void
  1349. finact(void)
  1350. {
  1351. Bterm(faction);
  1352. Bprint(ftable, "#define YYEOFCODE %d\n", 1);
  1353. Bprint(ftable, "#define YYERRCODE %d\n", 2);
  1354. }
  1355. /*
  1356. * define s to be a terminal if t=0
  1357. * or a nonterminal if t=1
  1358. */
  1359. int
  1360. defin(int nt, char *s)
  1361. {
  1362. int val;
  1363. Rune rune;
  1364. val = 0;
  1365. if(nt) {
  1366. nnonter++;
  1367. if(nnonter >= NNONTERM)
  1368. error("too many nonterminals, limit %d",NNONTERM);
  1369. nontrst[nnonter].name = cstash(s);
  1370. return NTBASE + nnonter;
  1371. }
  1372. /* must be a token */
  1373. ntokens++;
  1374. if(ntokens >= NTERMS)
  1375. error("too many terminals, limit %d", NTERMS);
  1376. tokset[ntokens].name = cstash(s);
  1377. /* establish value for token */
  1378. /* single character literal */
  1379. if(s[0] == ' ') {
  1380. val = chartorune(&rune, &s[1]);
  1381. if(s[val+1] == 0) {
  1382. val = rune;
  1383. goto out;
  1384. }
  1385. }
  1386. /* escape sequence */
  1387. if(s[0] == ' ' && s[1] == '\\') {
  1388. if(s[3] == 0) {
  1389. /* single character escape sequence */
  1390. switch(s[2]) {
  1391. case 'n': val = '\n'; break;
  1392. case 'r': val = '\r'; break;
  1393. case 'b': val = '\b'; break;
  1394. case 't': val = '\t'; break;
  1395. case 'f': val = '\f'; break;
  1396. case '\'': val = '\''; break;
  1397. case '"': val = '"'; break;
  1398. case '\\': val = '\\'; break;
  1399. default: error("invalid escape");
  1400. }
  1401. goto out;
  1402. }
  1403. /* \nnn sequence */
  1404. if(s[2] >= '0' && s[2] <= '7') {
  1405. if(s[3] < '0' ||
  1406. s[3] > '7' ||
  1407. s[4] < '0' ||
  1408. s[4] > '7' ||
  1409. s[5] != 0)
  1410. error("illegal \\nnn construction");
  1411. val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
  1412. if(val == 0)
  1413. error("'\\000' is illegal");
  1414. goto out;
  1415. }
  1416. error("unknown escape");
  1417. }
  1418. val = extval++;
  1419. out:
  1420. tokset[ntokens].value = val;
  1421. toklev[ntokens] = 0;
  1422. return ntokens;
  1423. }
  1424. /*
  1425. * write out the defines (at the end of the declaration section)
  1426. */
  1427. void
  1428. defout(int last)
  1429. {
  1430. int i, c;
  1431. char sar[NAMESIZE+10];
  1432. for(i=ndefout; i<=ntokens; i++) {
  1433. /* non-literals */
  1434. c = tokset[i].name[0];
  1435. if(c != ' ' && c != '$') {
  1436. Bprint(ftable, "#define %s %d\n",
  1437. tokset[i].name, tokset[i].value);
  1438. if(fdefine)
  1439. Bprint(fdefine, "#define\t%s\t%d\n",
  1440. tokset[i].name, tokset[i].value);
  1441. }
  1442. }
  1443. ndefout = ntokens+1;
  1444. if(last && fdebug) {
  1445. Bprint(fdebug, "char* yytoknames[] =\n{\n");
  1446. TLOOP(i) {
  1447. if(tokset[i].name) {
  1448. chcopy(sar, tokset[i].name);
  1449. Bprint(fdebug, "\t\"%s\",\n", sar);
  1450. continue;
  1451. }
  1452. Bprint(fdebug, "\t0,\n");
  1453. }
  1454. Bprint(fdebug, "};\n");
  1455. }
  1456. }
  1457. char*
  1458. cstash(char *s)
  1459. {
  1460. char *temp;
  1461. temp = cnamp;
  1462. do {
  1463. if(cnamp >= &cnames[cnamsz])
  1464. error("too many characters in id's and literals");
  1465. else
  1466. *cnamp++ = *s;
  1467. } while(*s++);
  1468. return temp;
  1469. }
  1470. int32_t
  1471. gettok(void)
  1472. {
  1473. int32_t c;
  1474. Rune rune;
  1475. int i, base, match, reserve;
  1476. static int peekline;
  1477. begin:
  1478. reserve = 0;
  1479. lineno += peekline;
  1480. peekline = 0;
  1481. c = Bgetrune(finput);
  1482. while(c == ' ' || c == '\n' || c == '\t' || c == '\f') {
  1483. if(c == '\n')
  1484. lineno++;
  1485. c = Bgetrune(finput);
  1486. }
  1487. /* skip comment */
  1488. if(c == '/') {
  1489. lineno += skipcom();
  1490. goto begin;
  1491. }
  1492. switch(c) {
  1493. case Beof:
  1494. return ENDFILE;
  1495. case '{':
  1496. Bungetrune(finput);
  1497. return '=';
  1498. case '<':
  1499. /* get, and look up, a type name (union member name) */
  1500. i = 0;
  1501. while((c=Bgetrune(finput)) != '>' && c >= 0 && c != '\n') {
  1502. rune = c;
  1503. c = runetochar(&tokname[i], &rune);
  1504. if(i < NAMESIZE)
  1505. i += c;
  1506. }
  1507. if(c != '>')
  1508. error("unterminated < ... > clause");
  1509. tokname[i] = 0;
  1510. for(i=1; i<=ntypes; i++)
  1511. if(!strcmp(typeset[i], tokname)) {
  1512. numbval = i;
  1513. return TYPENAME;
  1514. }
  1515. ntypes++;
  1516. numbval = ntypes;
  1517. typeset[numbval] = cstash(tokname);
  1518. return TYPENAME;
  1519. case '"':
  1520. case '\'':
  1521. match = c;
  1522. tokname[0] = ' ';
  1523. i = 1;
  1524. for(;;) {
  1525. c = Bgetrune(finput);
  1526. if(c == '\n' || c <= 0)
  1527. error("illegal or missing ' or \"" );
  1528. if(c == '\\') {
  1529. tokname[i] = '\\';
  1530. if(i < NAMESIZE)
  1531. i++;
  1532. c = Bgetrune(finput);
  1533. } else
  1534. if(c == match)
  1535. break;
  1536. rune = c;
  1537. c = runetochar(&tokname[i], &rune);
  1538. if(i < NAMESIZE)
  1539. i += c;
  1540. }
  1541. break;
  1542. case '%':
  1543. case '\\':
  1544. switch(c = Bgetrune(finput)) {
  1545. case '0': return TERM;
  1546. case '<': return LEFT;
  1547. case '2': return BINARY;
  1548. case '>': return RIGHT;
  1549. case '%':
  1550. case '\\': return MARK;
  1551. case '=': return PREC;
  1552. case '{': return LCURLY;
  1553. default: reserve = 1;
  1554. }
  1555. default:
  1556. /* number */
  1557. if(isdigit(c)) {
  1558. numbval = c-'0';
  1559. base = (c=='0')? 8: 10;
  1560. for(c = Bgetrune(finput); isdigit(c); c = Bgetrune(finput))
  1561. numbval = numbval*base + (c-'0');
  1562. Bungetrune(finput);
  1563. return NUMBER;
  1564. }
  1565. if(islower(c) || isupper(c) || c=='_' || c=='.' || c=='$') {
  1566. i = 0;
  1567. while(islower(c) || isupper(c) || isdigit(c) ||
  1568. c == '-' || c=='_' || c=='.' || c=='$') {
  1569. if(reserve && isupper(c))
  1570. c += 'a'-'A';
  1571. rune = c;
  1572. c = runetochar(&tokname[i], &rune);
  1573. if(i < NAMESIZE)
  1574. i += c;
  1575. c = Bgetrune(finput);
  1576. }
  1577. } else
  1578. return c;
  1579. Bungetrune(finput);
  1580. }
  1581. tokname[i] = 0;
  1582. /* find a reserved word */
  1583. if(reserve) {
  1584. for(c=0; resrv[c].name; c++)
  1585. if(strcmp(tokname, resrv[c].name) == 0)
  1586. return resrv[c].value;
  1587. error("invalid escape, or illegal reserved word: %s", tokname);
  1588. }
  1589. /* look ahead to distinguish IDENTIFIER from IDENTCOLON */
  1590. c = Bgetrune(finput);
  1591. while(c == ' ' || c == '\t'|| c == '\n' || c == '\f' || c == '/') {
  1592. if(c == '\n')
  1593. peekline++;
  1594. /* look for comments */
  1595. if(c == '/')
  1596. peekline += skipcom();
  1597. c = Bgetrune(finput);
  1598. }
  1599. if(c == ':')
  1600. return IDENTCOLON;
  1601. Bungetrune(finput);
  1602. return IDENTIFIER;
  1603. }
  1604. /*
  1605. * determine the type of a symbol
  1606. */
  1607. int
  1608. fdtype(int t)
  1609. {
  1610. int v;
  1611. if(t >= NTBASE)
  1612. v = nontrst[t-NTBASE].value;
  1613. else
  1614. v = TYPE(toklev[t]);
  1615. if(v <= 0)
  1616. error("must specify type for %s", (t>=NTBASE)?
  1617. nontrst[t-NTBASE].name: tokset[t].name);
  1618. return v;
  1619. }
  1620. int
  1621. chfind(int t, char *s)
  1622. {
  1623. int i;
  1624. if(s[0] == ' ')
  1625. t = 0;
  1626. TLOOP(i)
  1627. if(!strcmp(s, tokset[i].name))
  1628. return i;
  1629. NTLOOP(i)
  1630. if(!strcmp(s, nontrst[i].name))
  1631. return NTBASE+i;
  1632. /* cannot find name */
  1633. if(t > 1)
  1634. error("%s should have been defined earlier", s);
  1635. return defin(t, s);
  1636. }
  1637. /*
  1638. * copy the union declaration to the output, and the define file if present
  1639. */
  1640. void
  1641. cpyunion(void)
  1642. {
  1643. int32_t c;
  1644. int level;
  1645. Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
  1646. Bprint(ftable, "typedef union ");
  1647. if(fdefine != 0)
  1648. Bprint(fdefine, "\ntypedef union ");
  1649. level = 0;
  1650. for(;;) {
  1651. if((c=Bgetrune(finput)) == Beof)
  1652. error("EOF encountered while processing %%union");
  1653. Bputrune(ftable, c);
  1654. if(fdefine != 0)
  1655. Bputrune(fdefine, c);
  1656. switch(c) {
  1657. case '\n':
  1658. lineno++;
  1659. break;
  1660. case '{':
  1661. level++;
  1662. break;
  1663. case '}':
  1664. level--;
  1665. /* we are finished copying */
  1666. if(level == 0) {
  1667. Bprint(ftable, " YYSTYPE;\n");
  1668. if(fdefine != 0)
  1669. Bprint(fdefine, "\tYYSTYPE;\nextern\tYYSTYPE\tyylval;\n");
  1670. return;
  1671. }
  1672. }
  1673. }
  1674. }
  1675. /*
  1676. * copies code between \{ and \}
  1677. */
  1678. void
  1679. cpycode(void)
  1680. {
  1681. int32_t c;
  1682. c = Bgetrune(finput);
  1683. if(c == '\n') {
  1684. c = Bgetrune(finput);
  1685. lineno++;
  1686. }
  1687. Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
  1688. while(c != Beof) {
  1689. if(c == '\\') {
  1690. if((c=Bgetrune(finput)) == '}')
  1691. return;
  1692. Bputc(ftable, '\\');
  1693. }
  1694. if(c == '%') {
  1695. if((c=Bgetrune(finput)) == '}')
  1696. return;
  1697. Bputc(ftable, '%');
  1698. }
  1699. Bputrune(ftable, c);
  1700. if(c == '\n')
  1701. lineno++;
  1702. c = Bgetrune(finput);
  1703. }
  1704. error("eof before %%}");
  1705. }
  1706. /*
  1707. * skip over comments
  1708. * skipcom is called after reading a '/'
  1709. */
  1710. int
  1711. skipcom(void)
  1712. {
  1713. int32_t c;
  1714. int i;
  1715. /* i is the number of lines skipped */
  1716. i = 0;
  1717. c = Bgetrune(finput);
  1718. if(c == '/'){ /* C++ //: skip to end of line */
  1719. while((c = Bgetrune(finput)) != Beof)
  1720. if(c == '\n')
  1721. return 1;
  1722. }else if(c == '*'){ /* normal C comment */
  1723. while((c = Bgetrune(finput)) != Beof) {
  1724. while(c == '*')
  1725. if((c = Bgetrune(finput)) == '/')
  1726. return i;
  1727. if(c == '\n')
  1728. i++;
  1729. }
  1730. }else
  1731. error("illegal comment");
  1732. error("EOF inside comment");
  1733. return 0;
  1734. }
  1735. /*
  1736. * copy C action to the next ; or closing }
  1737. */
  1738. void
  1739. cpyact(int offset)
  1740. {
  1741. int32_t c;
  1742. int brac, match, j, s, fnd, tok;
  1743. Bprint(faction, "\n#line\t%d\t\"%s\"\n", lineno, infile);
  1744. brac = 0;
  1745. loop:
  1746. c = Bgetrune(finput);
  1747. swt:
  1748. switch(c) {
  1749. case ';':
  1750. if(brac == 0) {
  1751. Bputrune(faction, c);
  1752. return;
  1753. }
  1754. goto lcopy;
  1755. case '{':
  1756. brac++;
  1757. goto lcopy;
  1758. case '$':
  1759. s = 1;
  1760. tok = -1;
  1761. c = Bgetrune(finput);
  1762. /* type description */
  1763. if(c == '<') {
  1764. Bungetrune(finput);
  1765. if(gettok() != TYPENAME)
  1766. error("bad syntax on $<ident> clause");
  1767. tok = numbval;
  1768. c = Bgetrune(finput);
  1769. }
  1770. if(c == '$') {
  1771. Bprint(faction, "yyval");
  1772. /* put out the proper tag... */
  1773. if(ntypes) {
  1774. if(tok < 0)
  1775. tok = fdtype(*prdptr[nprod]);
  1776. Bprint(faction, ".%s", typeset[tok]);
  1777. }
  1778. goto loop;
  1779. }
  1780. if(c == '-') {
  1781. s = -s;
  1782. c = Bgetrune(finput);
  1783. }
  1784. if(isdigit(c)) {
  1785. j = 0;
  1786. while(isdigit(c)) {
  1787. j = j*10 + (c-'0');
  1788. c = Bgetrune(finput);
  1789. }
  1790. Bungetrune(finput);
  1791. j = j*s - offset;
  1792. if(j > 0)
  1793. error("Illegal use of $%d", j+offset);
  1794. dollar:
  1795. Bprint(faction, "yypt[-%d].yyv", -j);
  1796. /* put out the proper tag */
  1797. if(ntypes) {
  1798. if(j+offset <= 0 && tok < 0)
  1799. error("must specify type of $%d", j+offset);
  1800. if(tok < 0)
  1801. tok = fdtype(prdptr[nprod][j+offset]);
  1802. Bprint(faction, ".%s", typeset[tok]);
  1803. }
  1804. goto loop;
  1805. }
  1806. if(isupper(c) || islower(c) || c == '_' || c == '.') {
  1807. int tok; /* tok used oustide for type info */
  1808. /* look for $name */
  1809. Bungetrune(finput);
  1810. if(gettok() != IDENTIFIER)
  1811. error("$ must be followed by an identifier");
  1812. tok = chfind(2, tokname);
  1813. if((c = Bgetrune(finput)) != '#') {
  1814. Bungetrune(finput);
  1815. fnd = -1;
  1816. } else
  1817. if(gettok() != NUMBER) {
  1818. error("# must be followed by number");
  1819. fnd = -1;
  1820. } else
  1821. fnd = numbval;
  1822. for(j=1; j<=offset; ++j)
  1823. if(tok == prdptr[nprod][j]) {
  1824. if(--fnd <= 0) {
  1825. j -= offset;
  1826. goto dollar;
  1827. }
  1828. }
  1829. error("$name or $name#number not found");
  1830. }
  1831. Bputc(faction, '$');
  1832. if(s < 0 )
  1833. Bputc(faction, '-');
  1834. goto swt;
  1835. case '}':
  1836. brac--;
  1837. if(brac)
  1838. goto lcopy;
  1839. Bputrune(faction, c);
  1840. return;
  1841. case '/':
  1842. /* look for comments */
  1843. Bputrune(faction, c);
  1844. c = Bgetrune(finput);
  1845. if(c != '*')
  1846. goto swt;
  1847. /* it really is a comment; copy it */
  1848. Bputrune(faction, c);
  1849. c = Bgetrune(finput);
  1850. while(c >= 0) {
  1851. while(c == '*') {
  1852. Bputrune(faction, c);
  1853. if((c=Bgetrune(finput)) == '/')
  1854. goto lcopy;
  1855. }
  1856. Bputrune(faction, c);
  1857. if(c == '\n')
  1858. lineno++;
  1859. c = Bgetrune(finput);
  1860. }
  1861. error("EOF inside comment");
  1862. case '\'':
  1863. /* character constant */
  1864. match = '\'';
  1865. goto string;
  1866. case '"':
  1867. /* character string */
  1868. match = '"';
  1869. string:
  1870. Bputrune(faction, c);
  1871. while((c = Bgetrune(finput)) != 0){
  1872. if(c == '\\'){
  1873. Bputrune(faction, c);
  1874. c = Bgetrune(finput);
  1875. if(c == '\n')
  1876. lineno++;
  1877. }else{
  1878. if(c == match)
  1879. goto lcopy;
  1880. if(c == '\n')
  1881. error("newline in string or char. const.");
  1882. }
  1883. Bputrune(faction, c);
  1884. }
  1885. error("EOF in string or character constant");
  1886. case Beof:
  1887. error("action does not terminate");
  1888. case '\n':
  1889. lineno++;
  1890. goto lcopy;
  1891. }
  1892. lcopy:
  1893. Bputrune(faction, c);
  1894. goto loop;
  1895. }
  1896. void
  1897. openup(char *stem, int dflag, int vflag, int ytab, char *ytabc)
  1898. {
  1899. char buf[256];
  1900. if(vflag) {
  1901. snprint(buf, sizeof buf, "%s.%s", stem, FILEU);
  1902. foutput = Bopen(buf, OWRITE);
  1903. if(foutput == 0)
  1904. error("cannot open %s", buf);
  1905. }
  1906. if(yydebug) {
  1907. snprint(buf, sizeof buf, "%s.%s", stem, FILEDEBUG);
  1908. if((fdebug = Bopen(buf, OWRITE)) == 0)
  1909. error("can't open %s", buf);
  1910. }
  1911. if(dflag) {
  1912. snprint(buf, sizeof buf, "%s.%s", stem, FILED);
  1913. fdefine = Bopen(buf, OWRITE);
  1914. if(fdefine == 0)
  1915. error("can't create %s", buf);
  1916. }
  1917. if(ytab == 0)
  1918. snprint(buf, sizeof buf, "%s.%s", stem, OFILE);
  1919. else
  1920. strecpy(buf, buf+sizeof buf, ytabc);
  1921. ftable = Bopen(buf, OWRITE);
  1922. if(ftable == 0)
  1923. error("cannot open table file %s", buf);
  1924. }
  1925. /*
  1926. * print the output for the states
  1927. */
  1928. void
  1929. output(void)
  1930. {
  1931. int i, k, c;
  1932. Wset *u, *v;
  1933. Bprint(ftable, "short yyexca[] =\n{");
  1934. if(fdebug)
  1935. Bprint(fdebug, "char* yystates[] =\n{\n");
  1936. /* output the stuff for state i */
  1937. SLOOP(i) {
  1938. nolook = tystate[i]!=MUSTLOOKAHEAD;
  1939. closure(i);
  1940. /* output actions */
  1941. nolook = 1;
  1942. aryfil(temp1, ntokens+nnonter+1, 0);
  1943. WSLOOP(wsets, u) {
  1944. c = *(u->pitem);
  1945. if(c > 1 && c < NTBASE && temp1[c] == 0) {
  1946. WSLOOP(u, v)
  1947. if(c == *(v->pitem))
  1948. putitem(v->pitem+1, (Lkset*)0);
  1949. temp1[c] = state(c);
  1950. } else
  1951. if(c > NTBASE && temp1[(c -= NTBASE) + ntokens] == 0)
  1952. temp1[c+ntokens] = amem[indgo[i]+c];
  1953. }
  1954. if(i == 1)
  1955. temp1[1] = ACCEPTCODE;
  1956. /* now, we have the shifts; look at the reductions */
  1957. lastred = 0;
  1958. WSLOOP(wsets, u) {
  1959. c = *u->pitem;
  1960. /* reduction */
  1961. if(c <= 0) {
  1962. lastred = -c;
  1963. TLOOP(k)
  1964. if(BIT(u->ws.lset, k)) {
  1965. if(temp1[k] == 0)
  1966. temp1[k] = c;
  1967. else
  1968. if(temp1[k] < 0) { /* reduce/reduce conflict */
  1969. if(foutput)
  1970. Bprint(foutput,
  1971. "\n%d: reduce/reduce conflict"
  1972. " (red'ns %d and %d ) on %s",
  1973. i, -temp1[k], lastred,
  1974. symnam(k));
  1975. if(-temp1[k] > lastred)
  1976. temp1[k] = -lastred;
  1977. zzrrconf++;
  1978. } else
  1979. /* potential shift/reduce conflict */
  1980. precftn( lastred, k, i );
  1981. }
  1982. }
  1983. }
  1984. wract(i);
  1985. }
  1986. if(fdebug)
  1987. Bprint(fdebug, "};\n");
  1988. Bprint(ftable, "};\n");
  1989. Bprint(ftable, "#define YYNPROD %d\n", nprod);
  1990. Bprint(ftable, "#define YYPRIVATE %d\n", PRIVATE);
  1991. if(yydebug)
  1992. Bprint(ftable, "#define yydebug %s\n", yydebug);
  1993. }
  1994. /*
  1995. * pack state i from temp1 into amem
  1996. */
  1997. int
  1998. apack(int *p, int n)
  1999. {
  2000. int *pp, *qq, *rr, off, *q, *r;
  2001. /* we don't need to worry about checking because
  2002. * we will only look at entries known to be there...
  2003. * eliminate leading and trailing 0's
  2004. */
  2005. q = p+n;
  2006. for(pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
  2007. ;
  2008. /* no actions */
  2009. if(pp > q)
  2010. return 0;
  2011. p = pp;
  2012. /* now, find a place for the elements from p to q, inclusive */
  2013. r = &amem[ACTSIZE-1];
  2014. for(rr = amem; rr <= r; rr++, off++) {
  2015. for(qq = rr, pp = p; pp <= q; pp++, qq++)
  2016. if(*pp != 0)
  2017. if(*pp != *qq && *qq != 0)
  2018. goto nextk;
  2019. /* we have found an acceptable k */
  2020. if(pkdebug && foutput != 0)
  2021. Bprint(foutput, "off = %d, k = %d\n", off, (int)(rr-amem));
  2022. for(qq = rr, pp = p; pp <= q; pp++, qq++)
  2023. if(*pp) {
  2024. if(qq > r)
  2025. error("action table overflow");
  2026. if(qq > memp)
  2027. memp = qq;
  2028. *qq = *pp;
  2029. }
  2030. if(pkdebug && foutput != 0)
  2031. for(pp = amem; pp <= memp; pp += 10) {
  2032. Bprint(foutput, "\t");
  2033. for(qq = pp; qq <= pp+9; qq++)
  2034. Bprint(foutput, "%d ", *qq);
  2035. Bprint(foutput, "\n");
  2036. }
  2037. return(off);
  2038. nextk:;
  2039. }
  2040. error("no space in action table");
  2041. return 0;
  2042. }
  2043. /*
  2044. * output the gotos for the nontermninals
  2045. */
  2046. void
  2047. go2out(void)
  2048. {
  2049. int i, j, k, best, count, cbest, times;
  2050. /* mark begining of gotos */
  2051. Bprint(ftemp, "$\n");
  2052. for(i = 1; i <= nnonter; i++) {
  2053. go2gen(i);
  2054. /* find the best one to make default */
  2055. best = -1;
  2056. times = 0;
  2057. /* is j the most frequent */
  2058. for(j = 0; j <= nstate; j++) {
  2059. if(tystate[j] == 0)
  2060. continue;
  2061. if(tystate[j] == best)
  2062. continue;
  2063. /* is tystate[j] the most frequent */
  2064. count = 0;
  2065. cbest = tystate[j];
  2066. for(k = j; k <= nstate; k++)
  2067. if(tystate[k] == cbest)
  2068. count++;
  2069. if(count > times) {
  2070. best = cbest;
  2071. times = count;
  2072. }
  2073. }
  2074. /* best is now the default entry */
  2075. zzgobest += times-1;
  2076. for(j = 0; j <= nstate; j++)
  2077. if(tystate[j] != 0 && tystate[j] != best) {
  2078. Bprint(ftemp, "%d,%d,", j, tystate[j]);
  2079. zzgoent++;
  2080. }
  2081. /* now, the default */
  2082. if(best == -1)
  2083. best = 0;
  2084. zzgoent++;
  2085. Bprint(ftemp, "%d\n", best);
  2086. }
  2087. }
  2088. /*
  2089. * output the gotos for nonterminal c
  2090. */
  2091. void
  2092. go2gen(int c)
  2093. {
  2094. int i, work, cc;
  2095. Item *p, *q;
  2096. /* first, find nonterminals with gotos on c */
  2097. aryfil(temp1, nnonter+1, 0);
  2098. temp1[c] = 1;
  2099. work = 1;
  2100. while(work) {
  2101. work = 0;
  2102. PLOOP(0, i)
  2103. /* cc is a nonterminal */
  2104. if((cc=prdptr[i][1]-NTBASE) >= 0)
  2105. /* cc has a goto on c */
  2106. if(temp1[cc] != 0) {
  2107. /* thus, the left side of production i does too */
  2108. cc = *prdptr[i]-NTBASE;
  2109. if(temp1[cc] == 0) {
  2110. work = 1;
  2111. temp1[cc] = 1;
  2112. }
  2113. }
  2114. }
  2115. /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
  2116. if(g2debug && foutput != 0) {
  2117. Bprint(foutput, "%s: gotos on ", nontrst[c].name);
  2118. NTLOOP(i)
  2119. if(temp1[i])
  2120. Bprint(foutput, "%s ", nontrst[i].name);
  2121. Bprint(foutput, "\n");
  2122. }
  2123. /* now, go through and put gotos into tystate */
  2124. aryfil(tystate, nstate, 0);
  2125. SLOOP(i)
  2126. ITMLOOP(i, p, q)
  2127. if((cc = *p->pitem) >= NTBASE)
  2128. /* goto on c is possible */
  2129. if(temp1[cc-NTBASE]) {
  2130. tystate[i] = amem[indgo[i]+c];
  2131. break;
  2132. }
  2133. }
  2134. /*
  2135. * decide a shift/reduce conflict by precedence.
  2136. * r is a rule number, t a token number
  2137. * the conflict is in state s
  2138. * temp1[t] is changed to reflect the action
  2139. */
  2140. void
  2141. precftn(int r, int t, int s)
  2142. {
  2143. int lp, lt, action;
  2144. lp = levprd[r];
  2145. lt = toklev[t];
  2146. if(PLEVEL(lt) == 0 || PLEVEL(lp) == 0) {
  2147. /* conflict */
  2148. if(foutput != 0)
  2149. Bprint(foutput,
  2150. "\n%d: shift/reduce conflict (shift %d(%d), red'n %d(%d)) on %s",
  2151. s, temp1[t], PLEVEL(lt), r, PLEVEL(lp), symnam(t));
  2152. zzsrconf++;
  2153. return;
  2154. }
  2155. if(PLEVEL(lt) == PLEVEL(lp))
  2156. action = ASSOC(lt);
  2157. else
  2158. if(PLEVEL(lt) > PLEVEL(lp))
  2159. action = RASC; /* shift */
  2160. else
  2161. action = LASC; /* reduce */
  2162. switch(action) {
  2163. case BASC: /* error action */
  2164. temp1[t] = ERRCODE;
  2165. break;
  2166. case LASC: /* reduce */
  2167. temp1[t] = -r;
  2168. break;
  2169. }
  2170. }
  2171. /*
  2172. * output state i
  2173. * temp1 has the actions, lastred the default
  2174. */
  2175. void
  2176. wract(int i)
  2177. {
  2178. int p, p0, p1, ntimes, tred, count, j, flag;
  2179. /* find the best choice for lastred */
  2180. lastred = 0;
  2181. ntimes = 0;
  2182. TLOOP(j) {
  2183. if(temp1[j] >= 0)
  2184. continue;
  2185. if(temp1[j]+lastred == 0)
  2186. continue;
  2187. /* count the number of appearances of temp1[j] */
  2188. count = 0;
  2189. tred = -temp1[j];
  2190. levprd[tred] |= REDFLAG;
  2191. TLOOP(p)
  2192. if(temp1[p]+tred == 0)
  2193. count++;
  2194. if(count > ntimes) {
  2195. lastred = tred;
  2196. ntimes = count;
  2197. }
  2198. }
  2199. /*
  2200. * for error recovery, arrange that, if there is a shift on the
  2201. * error recovery token, `error', that the default be the error action
  2202. */
  2203. if(temp1[2] > 0)
  2204. lastred = 0;
  2205. /* clear out entries in temp1 which equal lastred */
  2206. TLOOP(p)
  2207. if(temp1[p]+lastred == 0)
  2208. temp1[p] = 0;
  2209. wrstate(i);
  2210. defact[i] = lastred;
  2211. flag = 0;
  2212. TLOOP(p0)
  2213. if((p1=temp1[p0]) != 0) {
  2214. if(p1 < 0) {
  2215. p1 = -p1;
  2216. goto exc;
  2217. }
  2218. if(p1 == ACCEPTCODE) {
  2219. p1 = -1;
  2220. goto exc;
  2221. }
  2222. if(p1 == ERRCODE) {
  2223. p1 = 0;
  2224. exc:
  2225. if(flag++ == 0)
  2226. Bprint(ftable, "-1, %d,\n", i);
  2227. Bprint(ftable, "\t%d, %d,\n", p0, p1);
  2228. zzexcp++;
  2229. continue;
  2230. }
  2231. Bprint(ftemp, "%d,%d,", p0, p1);
  2232. zzacent++;
  2233. }
  2234. if(flag) {
  2235. defact[i] = -2;
  2236. Bprint(ftable, "\t-2, %d,\n", lastred);
  2237. }
  2238. Bprint(ftemp, "\n");
  2239. }
  2240. /*
  2241. * writes state i
  2242. */
  2243. void
  2244. wrstate(int i)
  2245. {
  2246. int j0, j1;
  2247. Item *pp, *qq;
  2248. Wset *u;
  2249. if(fdebug) {
  2250. if(lastred) {
  2251. Bprint(fdebug, " 0, /*%d*/\n", i);
  2252. } else {
  2253. Bprint(fdebug, " \"");
  2254. ITMLOOP(i, pp, qq)
  2255. Bprint(fdebug, "%s\\n", writem(pp->pitem));
  2256. if(tystate[i] == MUSTLOOKAHEAD)
  2257. WSLOOP(wsets + (pstate[i+1] - pstate[i]), u)
  2258. if(*u->pitem < 0)
  2259. Bprint(fdebug, "%s\\n", writem(u->pitem));
  2260. Bprint(fdebug, "\", /*%d*/\n", i);
  2261. }
  2262. }
  2263. if(foutput == 0)
  2264. return;
  2265. Bprint(foutput, "\nstate %d\n", i);
  2266. ITMLOOP(i, pp, qq)
  2267. Bprint(foutput, "\t%s\n", writem(pp->pitem));
  2268. if(tystate[i] == MUSTLOOKAHEAD)
  2269. /* print out empty productions in closure */
  2270. WSLOOP(wsets+(pstate[i+1]-pstate[i]), u)
  2271. if(*u->pitem < 0)
  2272. Bprint(foutput, "\t%s\n", writem(u->pitem));
  2273. /* check for state equal to another */
  2274. TLOOP(j0)
  2275. if((j1=temp1[j0]) != 0) {
  2276. Bprint(foutput, "\n\t%s ", symnam(j0));
  2277. /* shift, error, or accept */
  2278. if(j1 > 0) {
  2279. if(j1 == ACCEPTCODE)
  2280. Bprint(foutput, "accept");
  2281. else
  2282. if(j1 == ERRCODE)
  2283. Bprint(foutput, "error");
  2284. else
  2285. Bprint(foutput, "shift %d", j1);
  2286. } else
  2287. Bprint(foutput, "reduce %d (src line %d)", -j1, rlines[-j1]);
  2288. }
  2289. /* output the final production */
  2290. if(lastred)
  2291. Bprint(foutput, "\n\t. reduce %d (src line %d)\n\n",
  2292. lastred, rlines[lastred]);
  2293. else
  2294. Bprint(foutput, "\n\t. error\n\n");
  2295. /* now, output nonterminal actions */
  2296. j1 = ntokens;
  2297. for(j0 = 1; j0 <= nnonter; j0++) {
  2298. j1++;
  2299. if(temp1[j1])
  2300. Bprint(foutput, "\t%s goto %d\n", symnam(j0+NTBASE), temp1[j1]);
  2301. }
  2302. }
  2303. void
  2304. warray(char *s, int *v, int n)
  2305. {
  2306. int i;
  2307. Bprint(ftable, "short %s[] =\n{", s);
  2308. for(i=0;;) {
  2309. if(i%10 == 0)
  2310. Bprint(ftable, "\n");
  2311. Bprint(ftable, "%4d", v[i]);
  2312. i++;
  2313. if(i >= n) {
  2314. Bprint(ftable, "\n};\n");
  2315. break;
  2316. }
  2317. Bprint(ftable, ",");
  2318. }
  2319. }
  2320. /*
  2321. * in order to free up the mem and amem arrays for the optimizer,
  2322. * and still be able to output yyr1, etc., after the sizes of
  2323. * the action array is known, we hide the nonterminals
  2324. * derived by productions in levprd.
  2325. */
  2326. void
  2327. hideprod(void)
  2328. {
  2329. int i, j;
  2330. j = 0;
  2331. levprd[0] = 0;
  2332. PLOOP(1, i) {
  2333. if(!(levprd[i] & REDFLAG)) {
  2334. j++;
  2335. if(foutput != 0)
  2336. Bprint(foutput, "Rule not reduced: %s\n", writem(prdptr[i]));
  2337. }
  2338. levprd[i] = *prdptr[i] - NTBASE;
  2339. }
  2340. if(j)
  2341. print("%d rules never reduced\n", j);
  2342. }
  2343. void
  2344. callopt(void)
  2345. {
  2346. int i, *p, j, k, *q;
  2347. /* read the arrays from tempfile and set parameters */
  2348. finput = Bopen(tempname, OREAD);
  2349. if(finput == 0)
  2350. error("optimizer cannot open tempfile");
  2351. pgo[0] = 0;
  2352. temp1[0] = 0;
  2353. nstate = 0;
  2354. nnonter = 0;
  2355. for(;;) {
  2356. switch(gtnm()) {
  2357. case '\n':
  2358. nstate++;
  2359. pmem--;
  2360. temp1[nstate] = pmem - mem0;
  2361. case ',':
  2362. continue;
  2363. case '$':
  2364. break;
  2365. default:
  2366. error("bad tempfile");
  2367. }
  2368. break;
  2369. }
  2370. pmem--;
  2371. temp1[nstate] = yypgo[0] = pmem - mem0;
  2372. for(;;) {
  2373. switch(gtnm()) {
  2374. case '\n':
  2375. nnonter++;
  2376. yypgo[nnonter] = pmem-mem0;
  2377. case ',':
  2378. continue;
  2379. case -1:
  2380. break;
  2381. default:
  2382. error("bad tempfile");
  2383. }
  2384. break;
  2385. }
  2386. pmem--;
  2387. yypgo[nnonter--] = pmem - mem0;
  2388. for(i = 0; i < nstate; i++) {
  2389. k = 32000;
  2390. j = 0;
  2391. q = mem0 + temp1[i+1];
  2392. for(p = mem0 + temp1[i]; p < q ; p += 2) {
  2393. if(*p > j)
  2394. j = *p;
  2395. if(*p < k)
  2396. k = *p;
  2397. }
  2398. /* nontrivial situation */
  2399. if(k <= j) {
  2400. /* j is now the range */
  2401. /* j -= k; *//* call scj */
  2402. if(k > maxoff)
  2403. maxoff = k;
  2404. }
  2405. tystate[i] = (temp1[i+1]-temp1[i]) + 2*j;
  2406. if(j > maxspr)
  2407. maxspr = j;
  2408. }
  2409. /* initialize ggreed table */
  2410. for(i = 1; i <= nnonter; i++) {
  2411. ggreed[i] = 1;
  2412. j = 0;
  2413. /* minimum entry index is always 0 */
  2414. q = mem0 + yypgo[i+1] - 1;
  2415. for(p = mem0+yypgo[i]; p < q ; p += 2) {
  2416. ggreed[i] += 2;
  2417. if(*p > j)
  2418. j = *p;
  2419. }
  2420. ggreed[i] = ggreed[i] + 2*j;
  2421. if(j > maxoff)
  2422. maxoff = j;
  2423. }
  2424. /* now, prepare to put the shift actions into the amem array */
  2425. for(i = 0; i < ACTSIZE; i++)
  2426. amem[i] = 0;
  2427. maxa = amem;
  2428. for(i = 0; i < nstate; i++) {
  2429. if(tystate[i] == 0 && adb > 1)
  2430. Bprint(ftable, "State %d: null\n", i);
  2431. indgo[i] = YYFLAG1;
  2432. }
  2433. while((i = nxti()) != NOMORE)
  2434. if(i >= 0)
  2435. stin(i);
  2436. else
  2437. gin(-i);
  2438. /* print amem array */
  2439. if(adb > 2 )
  2440. for(p = amem; p <= maxa; p += 10) {
  2441. Bprint(ftable, "%4d ", (int)(p-amem));
  2442. for(i = 0; i < 10; ++i)
  2443. Bprint(ftable, "%4d ", p[i]);
  2444. Bprint(ftable, "\n");
  2445. }
  2446. /* write out the output appropriate to the language */
  2447. aoutput();
  2448. osummary();
  2449. ZAPFILE(tempname);
  2450. }
  2451. void
  2452. gin(int i)
  2453. {
  2454. int *p, *r, *s, *q1, *q2;
  2455. /* enter gotos on nonterminal i into array amem */
  2456. ggreed[i] = 0;
  2457. q2 = mem0+ yypgo[i+1] - 1;
  2458. q1 = mem0 + yypgo[i];
  2459. /* now, find amem place for it */
  2460. for(p = amem; p < &amem[ACTSIZE]; p++) {
  2461. if(*p)
  2462. continue;
  2463. for(r = q1; r < q2; r += 2) {
  2464. s = p + *r + 1;
  2465. if(*s)
  2466. goto nextgp;
  2467. if(s > maxa)
  2468. if((maxa = s) > &amem[ACTSIZE])
  2469. error("a array overflow");
  2470. }
  2471. /* we have found amem spot */
  2472. *p = *q2;
  2473. if(p > maxa)
  2474. if((maxa = p) > &amem[ACTSIZE])
  2475. error("a array overflow");
  2476. for(r = q1; r < q2; r += 2) {
  2477. s = p + *r + 1;
  2478. *s = r[1];
  2479. }
  2480. pgo[i] = p-amem;
  2481. if(adb > 1)
  2482. Bprint(ftable, "Nonterminal %d, entry at %d\n", i, pgo[i]);
  2483. return;
  2484. nextgp:;
  2485. }
  2486. error("cannot place goto %d\n", i);
  2487. }
  2488. void
  2489. stin(int i)
  2490. {
  2491. int *r, *s, n, flag, j, *q1, *q2;
  2492. tystate[i] = 0;
  2493. /* enter state i into the amem array */
  2494. q2 = mem0+temp1[i+1];
  2495. q1 = mem0+temp1[i];
  2496. /* find an acceptable place */
  2497. for(n = -maxoff; n < ACTSIZE; n++) {
  2498. flag = 0;
  2499. for(r = q1; r < q2; r += 2) {
  2500. if((s = *r + n + amem) < amem)
  2501. goto nextn;
  2502. if(*s == 0)
  2503. flag++;
  2504. else
  2505. if(*s != r[1])
  2506. goto nextn;
  2507. }
  2508. /* check that the position equals another only if the states are identical */
  2509. for(j=0; j<nstate; j++) {
  2510. if(indgo[j] == n) {
  2511. /* we have some disagreement */
  2512. if(flag)
  2513. goto nextn;
  2514. if(temp1[j+1]+temp1[i] == temp1[j]+temp1[i+1]) {
  2515. /* states are equal */
  2516. indgo[i] = n;
  2517. if(adb > 1)
  2518. Bprint(ftable,
  2519. "State %d: entry at %d equals state %d\n",
  2520. i, n, j);
  2521. return;
  2522. }
  2523. /* we have some disagreement */
  2524. goto nextn;
  2525. }
  2526. }
  2527. for(r = q1; r < q2; r += 2) {
  2528. if((s = *r+n+amem) >= &amem[ACTSIZE])
  2529. error("out of space in optimizer a array");
  2530. if(s > maxa)
  2531. maxa = s;
  2532. if(*s != 0 && *s != r[1])
  2533. error("clobber of a array, pos'n %d, by %d", s-amem, r[1]);
  2534. *s = r[1];
  2535. }
  2536. indgo[i] = n;
  2537. if(adb > 1)
  2538. Bprint(ftable, "State %d: entry at %d\n", i, indgo[i]);
  2539. return;
  2540. nextn:;
  2541. }
  2542. error("Error; failure to place state %d\n", i);
  2543. }
  2544. /*
  2545. * finds the next i
  2546. */
  2547. int
  2548. nxti(void)
  2549. {
  2550. int i, max, maxi;
  2551. max = 0;
  2552. maxi = 0;
  2553. for(i = 1; i <= nnonter; i++)
  2554. if(ggreed[i] >= max) {
  2555. max = ggreed[i];
  2556. maxi = -i;
  2557. }
  2558. for(i = 0; i < nstate; ++i)
  2559. if(tystate[i] >= max) {
  2560. max = tystate[i];
  2561. maxi = i;
  2562. }
  2563. if(nxdb)
  2564. Bprint(ftable, "nxti = %d, max = %d\n", maxi, max);
  2565. if(max == 0)
  2566. return NOMORE;
  2567. return maxi;
  2568. }
  2569. /*
  2570. * write summary
  2571. */
  2572. void
  2573. osummary(void)
  2574. {
  2575. int i, *p;
  2576. if(foutput == 0)
  2577. return;
  2578. i = 0;
  2579. for(p = maxa; p >= amem; p--)
  2580. if(*p == 0)
  2581. i++;
  2582. Bprint(foutput, "Optimizer space used: input %d/%d, output %d/%d\n",
  2583. (int)(pmem-mem0+1), MEMSIZE, (int)(maxa-amem+1), ACTSIZE);
  2584. Bprint(foutput, "%d table entries, %d zero\n", (int)(maxa-amem+1), i);
  2585. Bprint(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff);
  2586. }
  2587. /*
  2588. * this version is for C
  2589. * write out the optimized parser
  2590. */
  2591. void
  2592. aoutput(void)
  2593. {
  2594. Bprint(ftable, "#define\tYYLAST\t%d\n", (int)(maxa-amem+1));
  2595. arout("yyact", amem, (maxa-amem)+1);
  2596. arout("yypact", indgo, nstate);
  2597. arout("yypgo", pgo, nnonter+1);
  2598. }
  2599. void
  2600. arout(char *s, int *v, int n)
  2601. {
  2602. int i;
  2603. Bprint(ftable, "short %s[] =\n{", s);
  2604. for(i = 0; i < n;) {
  2605. if(i%10 == 0)
  2606. Bprint(ftable, "\n");
  2607. Bprint(ftable, "%4d", v[i]);
  2608. i++;
  2609. if(i == n)
  2610. Bprint(ftable, "\n};\n");
  2611. else
  2612. Bprint(ftable, ",");
  2613. }
  2614. }
  2615. /*
  2616. * read and convert an integer from the standard input
  2617. * return the terminating character
  2618. * blanks, tabs, and newlines are ignored
  2619. */
  2620. int
  2621. gtnm(void)
  2622. {
  2623. int sign, val, c;
  2624. sign = 0;
  2625. val = 0;
  2626. while((c=Bgetrune(finput)) != Beof) {
  2627. if(isdigit(c)) {
  2628. val = val*10 + c-'0';
  2629. continue;
  2630. }
  2631. if(c == '-') {
  2632. sign = 1;
  2633. continue;
  2634. }
  2635. break;
  2636. }
  2637. if(sign)
  2638. val = -val;
  2639. *pmem++ = val;
  2640. if(pmem >= &mem0[MEMSIZE])
  2641. error("out of space");
  2642. return c;
  2643. }