yacc.c 57 KB

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