You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3591 lines
69 KiB

  1. /*
  2. Derived from Inferno's utils/iyacc/yacc.c
  3. http://code.google.com/p/inferno-os/source/browse/utils/iyacc/yacc.c
  4. This copyright NOTICE applies to all files in this directory and
  5. subdirectories, unless another copyright notice appears in a given
  6. file or subdirectory. If you take substantial code from this software to use in
  7. other programs, you must somehow include with it an appropriate
  8. copyright notice that includes the copyright notice and the other
  9. notices below. It is fine (and often tidier) to do that in a separate
  10. file such as NOTICE, LICENCE or COPYING.
  11. Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
  12. Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
  13. Portions Copyright © 1997-1999 Vita Nuova Limited
  14. Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
  15. Portions Copyright © 2004,2006 Bruce Ellis
  16. Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
  17. Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
  18. Portions Copyright © 2009 The Go Authors. All rights reserved.
  19. Permission is hereby granted, free of charge, to any person obtaining a copy
  20. of this software and associated documentation files (the "Software"), to deal
  21. in the Software without restriction, including without limitation the rights
  22. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  23. copies of the Software, and to permit persons to whom the Software is
  24. furnished to do so, subject to the following conditions:
  25. The above copyright notice and this permission notice shall be included in
  26. all copies or substantial portions of the Software.
  27. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  33. THE SOFTWARE.
  34. */
  35. package main
  36. // yacc
  37. // major difference is lack of stem ("y" variable)
  38. //
  39. import (
  40. "bufio"
  41. "bytes"
  42. "flag"
  43. "fmt"
  44. "go/format"
  45. "io/ioutil"
  46. "os"
  47. "strconv"
  48. "strings"
  49. "unicode"
  50. )
  51. // the following are adjustable
  52. // according to memory size
  53. const (
  54. ACTSIZE = 120000
  55. NSTATES = 8000
  56. TEMPSIZE = 8000
  57. SYMINC = 50 // increase for non-term or term
  58. RULEINC = 50 // increase for max rule length prodptr[i]
  59. PRODINC = 100 // increase for productions prodptr
  60. WSETINC = 50 // increase for working sets wsets
  61. STATEINC = 200 // increase for states statemem
  62. PRIVATE = 0xE000 // unicode private use
  63. // relationships which must hold:
  64. // TEMPSIZE >= NTERMS + NNONTERM + 1;
  65. // TEMPSIZE >= NSTATES;
  66. //
  67. NTBASE = 010000
  68. ERRCODE = 8190
  69. ACCEPTCODE = 8191
  70. YYLEXUNK = 3
  71. TOKSTART = 4 //index of first defined token
  72. )
  73. // no, left, right, binary assoc.
  74. const (
  75. NOASC = iota
  76. LASC
  77. RASC
  78. BASC
  79. )
  80. // flags for state generation
  81. const (
  82. DONE = iota
  83. MUSTDO
  84. MUSTLOOKAHEAD
  85. )
  86. // flags for a rule having an action, and being reduced
  87. const (
  88. ACTFLAG = 1 << (iota + 2)
  89. REDFLAG
  90. )
  91. // output parser flags
  92. const yyFlag = -1000
  93. // parse tokens
  94. const (
  95. IDENTIFIER = PRIVATE + iota
  96. MARK
  97. TERM
  98. LEFT
  99. RIGHT
  100. BINARY
  101. PREC
  102. LCURLY
  103. IDENTCOLON
  104. NUMBER
  105. START
  106. TYPEDEF
  107. TYPENAME
  108. UNION
  109. ERROR
  110. )
  111. const ENDFILE = 0
  112. const EMPTY = 1
  113. const WHOKNOWS = 0
  114. const OK = 1
  115. const NOMORE = -1000
  116. // macros for getting associativity and precedence levels
  117. func ASSOC(i int) int { return i & 3 }
  118. func PLEVEL(i int) int { return (i >> 4) & 077 }
  119. func TYPE(i int) int { return (i >> 10) & 077 }
  120. // macros for setting associativity and precedence levels
  121. func SETASC(i, j int) int { return i | j }
  122. func SETPLEV(i, j int) int { return i | (j << 4) }
  123. func SETTYPE(i, j int) int { return i | (j << 10) }
  124. // I/O descriptors
  125. var finput *bufio.Reader // input file
  126. var stderr *bufio.Writer
  127. var ftable *bufio.Writer // y.go file
  128. var fcode = &bytes.Buffer{} // saved code
  129. var foutput *bufio.Writer // y.output file
  130. var fmtImported bool // output file has recorded an import of "fmt"
  131. var oflag string // -o [y.go] - y.go file
  132. var vflag string // -v [y.output] - y.output file
  133. var lflag bool // -l - disable line directives
  134. var prefix string // name prefix for identifiers, default yy
  135. func init() {
  136. flag.StringVar(&oflag, "o", "y.go", "parser output")
  137. flag.StringVar(&prefix, "p", "yy", "name prefix to use in generated code")
  138. flag.StringVar(&vflag, "v", "y.output", "create parsing tables")
  139. flag.BoolVar(&lflag, "l", false, "disable line directives")
  140. }
  141. var initialstacksize = 16
  142. // communication variables between various I/O routines
  143. var infile string // input file name
  144. var numbval int // value of an input number
  145. var tokname string // input token name, slop for runes and 0
  146. var tokflag = false
  147. // structure declarations
  148. type Lkset []int
  149. type Pitem struct {
  150. prod []int
  151. off int // offset within the production
  152. first int // first term or non-term in item
  153. prodno int // production number for sorting
  154. }
  155. type Item struct {
  156. pitem Pitem
  157. look Lkset
  158. }
  159. type Symb struct {
  160. name string
  161. noconst bool
  162. value int
  163. }
  164. type Wset struct {
  165. pitem Pitem
  166. flag int
  167. ws Lkset
  168. }
  169. // storage of types
  170. var ntypes int // number of types defined
  171. var typeset = make(map[int]string) // pointers to type tags
  172. // token information
  173. var ntokens = 0 // number of tokens
  174. var tokset []Symb
  175. var toklev []int // vector with the precedence of the terminals
  176. // nonterminal information
  177. var nnonter = -1 // the number of nonterminals
  178. var nontrst []Symb
  179. var start int // start symbol
  180. // state information
  181. var nstate = 0 // number of states
  182. var pstate = make([]int, NSTATES+2) // index into statemem to the descriptions of the states
  183. var statemem []Item
  184. var tystate = make([]int, NSTATES) // contains type information about the states
  185. var tstates []int // states generated by terminal gotos
  186. var ntstates []int // states generated by nonterminal gotos
  187. var mstates = make([]int, NSTATES) // chain of overflows of term/nonterm generation lists
  188. var lastred int // number of last reduction of a state
  189. var defact = make([]int, NSTATES) // default actions of states
  190. // lookahead set information
  191. var nolook = 0 // flag to turn off lookahead computations
  192. var tbitset = 0 // size of lookahead sets
  193. var clset Lkset // temporary storage for lookahead computations
  194. // working set information
  195. var wsets []Wset
  196. var cwp int
  197. // storage for action table
  198. var amem []int // action table storage
  199. var memp int // next free action table position
  200. var indgo = make([]int, NSTATES) // index to the stored goto table
  201. // temporary vector, indexable by states, terms, or ntokens
  202. var temp1 = make([]int, TEMPSIZE) // temporary storage, indexed by terms + ntokens or states
  203. var lineno = 1 // current input line number
  204. var fatfl = 1 // if on, error is fatal
  205. var nerrors = 0 // number of errors
  206. // assigned token type values
  207. var extval = 0
  208. // grammar rule information
  209. var nprod = 1 // number of productions
  210. var prdptr [][]int // pointers to descriptions of productions
  211. var levprd []int // precedence levels for the productions
  212. var rlines []int // line number for this rule
  213. // statistics collection variables
  214. var zzgoent = 0
  215. var zzgobest = 0
  216. var zzacent = 0
  217. var zzexcp = 0
  218. var zzclose = 0
  219. var zzrrconf = 0
  220. var zzsrconf = 0
  221. var zzstate = 0
  222. // optimizer arrays
  223. var yypgo [][]int
  224. var optst [][]int
  225. var ggreed []int
  226. var pgo []int
  227. var maxspr int // maximum spread of any entry
  228. var maxoff int // maximum offset into a array
  229. var maxa int
  230. // storage for information about the nonterminals
  231. var pres [][][]int // vector of pointers to productions yielding each nonterminal
  232. var pfirst []Lkset
  233. var pempty []int // vector of nonterminals nontrivially deriving e
  234. // random stuff picked out from between functions
  235. var indebug = 0 // debugging flag for cpfir
  236. var pidebug = 0 // debugging flag for putitem
  237. var gsdebug = 0 // debugging flag for stagen
  238. var cldebug = 0 // debugging flag for closure
  239. var pkdebug = 0 // debugging flag for apack
  240. var g2debug = 0 // debugging for go2gen
  241. var adb = 0 // debugging for callopt
  242. type Resrv struct {
  243. name string
  244. value int
  245. }
  246. var resrv = []Resrv{
  247. {"binary", BINARY},
  248. {"left", LEFT},
  249. {"nonassoc", BINARY},
  250. {"prec", PREC},
  251. {"right", RIGHT},
  252. {"start", START},
  253. {"term", TERM},
  254. {"token", TERM},
  255. {"type", TYPEDEF},
  256. {"union", UNION},
  257. {"struct", UNION},
  258. {"error", ERROR},
  259. }
  260. type Error struct {
  261. lineno int
  262. tokens []string
  263. msg string
  264. }
  265. var errors []Error
  266. type Row struct {
  267. actions []int
  268. defaultAction int
  269. }
  270. var stateTable []Row
  271. var zznewstate = 0
  272. const EOF = -1
  273. func main() {
  274. setup() // initialize and read productions
  275. tbitset = (ntokens + 32) / 32
  276. cpres() // make table of which productions yield a given nonterminal
  277. cempty() // make a table of which nonterminals can match the empty string
  278. cpfir() // make a table of firsts of nonterminals
  279. stagen() // generate the states
  280. yypgo = make([][]int, nnonter+1)
  281. optst = make([][]int, nstate)
  282. output() // write the states and the tables
  283. go2out()
  284. hideprod()
  285. summary()
  286. callopt()
  287. others()
  288. exit(0)
  289. }
  290. func setup() {
  291. var j, ty int
  292. stderr = bufio.NewWriter(os.Stderr)
  293. foutput = nil
  294. flag.Parse()
  295. if flag.NArg() != 1 {
  296. usage()
  297. }
  298. if initialstacksize < 1 {
  299. // never set so cannot happen
  300. fmt.Fprintf(stderr, "yacc: stack size too small\n")
  301. usage()
  302. }
  303. yaccpar = strings.Replace(yaccpartext, "$$", prefix, -1)
  304. openup()
  305. defin(0, "$end")
  306. extval = PRIVATE // tokens start in unicode 'private use'
  307. defin(0, "error")
  308. defin(1, "$accept")
  309. defin(0, "$unk")
  310. i := 0
  311. t := gettok()
  312. outer:
  313. for {
  314. switch t {
  315. default:
  316. errorf("syntax error tok=%v", t-PRIVATE)
  317. case MARK, ENDFILE:
  318. break outer
  319. case ';':
  320. // Do nothing.
  321. case START:
  322. t = gettok()
  323. if t != IDENTIFIER {
  324. errorf("bad %%start construction")
  325. }
  326. start = chfind(1, tokname)
  327. case ERROR:
  328. lno := lineno
  329. var tokens []string
  330. for {
  331. t := gettok()
  332. if t == ':' {
  333. break
  334. }
  335. if t != IDENTIFIER && t != IDENTCOLON {
  336. errorf("bad syntax in %%error")
  337. }
  338. tokens = append(tokens, tokname)
  339. if t == IDENTCOLON {
  340. break
  341. }
  342. }
  343. if gettok() != IDENTIFIER {
  344. errorf("bad syntax in %%error")
  345. }
  346. errors = append(errors, Error{lno, tokens, tokname})
  347. case TYPEDEF:
  348. t = gettok()
  349. if t != TYPENAME {
  350. errorf("bad syntax in %%type")
  351. }
  352. ty = numbval
  353. for {
  354. t = gettok()
  355. switch t {
  356. case IDENTIFIER:
  357. t = chfind(1, tokname)
  358. if t < NTBASE {
  359. j = TYPE(toklev[t])
  360. if j != 0 && j != ty {
  361. errorf("type redeclaration of token %s",
  362. tokset[t].name)
  363. } else {
  364. toklev[t] = SETTYPE(toklev[t], ty)
  365. }
  366. } else {
  367. j = nontrst[t-NTBASE].value
  368. if j != 0 && j != ty {
  369. errorf("type redeclaration of nonterminal %v",
  370. nontrst[t-NTBASE].name)
  371. } else {
  372. nontrst[t-NTBASE].value = ty
  373. }
  374. }
  375. continue
  376. case ',':
  377. continue
  378. }
  379. break
  380. }
  381. continue
  382. case UNION:
  383. cpyunion()
  384. case LEFT, BINARY, RIGHT, TERM:
  385. // nonzero means new prec. and assoc.
  386. lev := t - TERM
  387. if lev != 0 {
  388. i++
  389. }
  390. ty = 0
  391. // get identifiers so defined
  392. t = gettok()
  393. // there is a type defined
  394. if t == TYPENAME {
  395. ty = numbval
  396. t = gettok()
  397. }
  398. for {
  399. switch t {
  400. case ',':
  401. t = gettok()
  402. continue
  403. case ';':
  404. // Do nothing.
  405. case IDENTIFIER:
  406. j = chfind(0, tokname)
  407. if j >= NTBASE {
  408. errorf("%v defined earlier as nonterminal", tokname)
  409. }
  410. if lev != 0 {
  411. if ASSOC(toklev[j]) != 0 {
  412. errorf("redeclaration of precedence of %v", tokname)
  413. }
  414. toklev[j] = SETASC(toklev[j], lev)
  415. toklev[j] = SETPLEV(toklev[j], i)
  416. }
  417. if ty != 0 {
  418. if TYPE(toklev[j]) != 0 {
  419. errorf("redeclaration of type of %v", tokname)
  420. }
  421. toklev[j] = SETTYPE(toklev[j], ty)
  422. }
  423. t = gettok()
  424. if t == NUMBER {
  425. tokset[j].value = numbval
  426. t = gettok()
  427. }
  428. continue
  429. }
  430. break
  431. }
  432. continue
  433. case LCURLY:
  434. cpycode()
  435. }
  436. t = gettok()
  437. }
  438. if t == ENDFILE {
  439. errorf("unexpected EOF before %%")
  440. }
  441. fmt.Fprintf(fcode, "switch %snt {\n", prefix)
  442. moreprod()
  443. prdptr[0] = []int{NTBASE, start, 1, 0}
  444. nprod = 1
  445. curprod := make([]int, RULEINC)
  446. t = gettok()
  447. if t != IDENTCOLON {
  448. errorf("bad syntax on first rule")
  449. }
  450. if start == 0 {
  451. prdptr[0][1] = chfind(1, tokname)
  452. }
  453. // read rules
  454. // put into prdptr array in the format
  455. // target
  456. // followed by id's of terminals and non-terminals
  457. // followed by -nprod
  458. for t != MARK && t != ENDFILE {
  459. mem := 0
  460. // process a rule
  461. rlines[nprod] = lineno
  462. ruleline := lineno
  463. if t == '|' {
  464. curprod[mem] = prdptr[nprod-1][0]
  465. mem++
  466. } else if t == IDENTCOLON {
  467. curprod[mem] = chfind(1, tokname)
  468. if curprod[mem] < NTBASE {
  469. lerrorf(ruleline, "token illegal on LHS of grammar rule")
  470. }
  471. mem++
  472. } else {
  473. lerrorf(ruleline, "illegal rule: missing semicolon or | ?")
  474. }
  475. // read rule body
  476. t = gettok()
  477. for {
  478. for t == IDENTIFIER {
  479. curprod[mem] = chfind(1, tokname)
  480. if curprod[mem] < NTBASE {
  481. levprd[nprod] = toklev[curprod[mem]]
  482. }
  483. mem++
  484. if mem >= len(curprod) {
  485. ncurprod := make([]int, mem+RULEINC)
  486. copy(ncurprod, curprod)
  487. curprod = ncurprod
  488. }
  489. t = gettok()
  490. }
  491. if t == PREC {
  492. if gettok() != IDENTIFIER {
  493. lerrorf(ruleline, "illegal %%prec syntax")
  494. }
  495. j = chfind(2, tokname)
  496. if j >= NTBASE {
  497. lerrorf(ruleline, "nonterminal "+nontrst[j-NTBASE].name+" illegal after %%prec")
  498. }
  499. levprd[nprod] = toklev[j]
  500. t = gettok()
  501. }
  502. if t != '=' {
  503. break
  504. }
  505. levprd[nprod] |= ACTFLAG
  506. fmt.Fprintf(fcode, "\n\tcase %v:", nprod)
  507. fmt.Fprintf(fcode, "\n\t\t%sDollar = %sS[%spt-%v:%spt+1]", prefix, prefix, prefix, mem-1, prefix)
  508. cpyact(curprod, mem)
  509. // action within rule...
  510. t = gettok()
  511. if t == IDENTIFIER {
  512. // make it a nonterminal
  513. j = chfind(1, fmt.Sprintf("$$%v", nprod))
  514. //
  515. // the current rule will become rule number nprod+1
  516. // enter null production for action
  517. //
  518. prdptr[nprod] = make([]int, 2)
  519. prdptr[nprod][0] = j
  520. prdptr[nprod][1] = -nprod
  521. // update the production information
  522. nprod++
  523. moreprod()
  524. levprd[nprod] = levprd[nprod-1] & ^ACTFLAG
  525. levprd[nprod-1] = ACTFLAG
  526. rlines[nprod] = lineno
  527. // make the action appear in the original rule
  528. curprod[mem] = j
  529. mem++
  530. if mem >= len(curprod) {
  531. ncurprod := make([]int, mem+RULEINC)
  532. copy(ncurprod, curprod)
  533. curprod = ncurprod
  534. }
  535. }
  536. }
  537. for t == ';' {
  538. t = gettok()
  539. }
  540. curprod[mem] = -nprod
  541. mem++
  542. // check that default action is reasonable
  543. if ntypes != 0 && (levprd[nprod]&ACTFLAG) == 0 &&
  544. nontrst[curprod[0]-NTBASE].value != 0 {
  545. // no explicit action, LHS has value
  546. tempty := curprod[1]
  547. if tempty < 0 {
  548. lerrorf(ruleline, "must return a value, since LHS has a type")
  549. }
  550. if tempty >= NTBASE {
  551. tempty = nontrst[tempty-NTBASE].value
  552. } else {
  553. tempty = TYPE(toklev[tempty])
  554. }
  555. if tempty != nontrst[curprod[0]-NTBASE].value {
  556. lerrorf(ruleline, "default action causes potential type clash")
  557. }
  558. }
  559. moreprod()
  560. prdptr[nprod] = make([]int, mem)
  561. copy(prdptr[nprod], curprod)
  562. nprod++
  563. moreprod()
  564. levprd[nprod] = 0
  565. }
  566. if TEMPSIZE < ntokens+nnonter+1 {
  567. errorf("too many tokens (%d) or non-terminals (%d)", ntokens, nnonter)
  568. }
  569. //
  570. // end of all rules
  571. // dump out the prefix code
  572. //
  573. fmt.Fprintf(fcode, "\n\t}")
  574. // put out non-literal terminals
  575. for i := TOKSTART; i <= ntokens; i++ {
  576. // non-literals
  577. if !tokset[i].noconst {
  578. fmt.Fprintf(ftable, "const %v = %v\n", tokset[i].name, tokset[i].value)
  579. }
  580. }
  581. // put out names of tokens
  582. ftable.WriteRune('\n')
  583. fmt.Fprintf(ftable, "var %sToknames = [...]string{\n", prefix)
  584. for i := 1; i <= ntokens; i++ {
  585. fmt.Fprintf(ftable, "\t%q,\n", tokset[i].name)
  586. }
  587. fmt.Fprintf(ftable, "}\n")
  588. // put out names of states.
  589. // commented out to avoid a huge table just for debugging.
  590. // re-enable to have the names in the binary.
  591. fmt.Fprintf(ftable, "var %sStatenames = [...]string{", prefix)
  592. // for i:=TOKSTART; i<=ntokens; i++ {
  593. // fmt.Fprintf(ftable, "\t%q,\n", tokset[i].name);
  594. // }
  595. fmt.Fprintf(ftable, "}\n")
  596. ftable.WriteRune('\n')
  597. fmt.Fprintf(ftable, "const %sEofCode = 1\n", prefix)
  598. fmt.Fprintf(ftable, "const %sErrCode = 2\n", prefix)
  599. fmt.Fprintf(ftable, "const %sInitialStackSize = %v\n", prefix, initialstacksize)
  600. //
  601. // copy any postfix code
  602. //
  603. if t == MARK {
  604. if !lflag {
  605. fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno)
  606. }
  607. for {
  608. c := getrune(finput)
  609. if c == EOF {
  610. break
  611. }
  612. ftable.WriteRune(c)
  613. }
  614. }
  615. }
  616. //
  617. // allocate enough room to hold another production
  618. //
  619. func moreprod() {
  620. n := len(prdptr)
  621. if nprod >= n {
  622. nn := n + PRODINC
  623. aprod := make([][]int, nn)
  624. alevprd := make([]int, nn)
  625. arlines := make([]int, nn)
  626. copy(aprod, prdptr)
  627. copy(alevprd, levprd)
  628. copy(arlines, rlines)
  629. prdptr = aprod
  630. levprd = alevprd
  631. rlines = arlines
  632. }
  633. }
  634. //
  635. // define s to be a terminal if nt==0
  636. // or a nonterminal if nt==1
  637. //
  638. func defin(nt int, s string) int {
  639. val := 0
  640. if nt != 0 {
  641. nnonter++
  642. if nnonter >= len(nontrst) {
  643. anontrst := make([]Symb, nnonter+SYMINC)
  644. copy(anontrst, nontrst)
  645. nontrst = anontrst
  646. }
  647. nontrst[nnonter] = Symb{name: s}
  648. return NTBASE + nnonter
  649. }
  650. // must be a token
  651. ntokens++
  652. if ntokens >= len(tokset) {
  653. nn := ntokens + SYMINC
  654. atokset := make([]Symb, nn)
  655. atoklev := make([]int, nn)
  656. copy(atoklev, toklev)
  657. copy(atokset, tokset)
  658. tokset = atokset
  659. toklev = atoklev
  660. }
  661. tokset[ntokens].name = s
  662. toklev[ntokens] = 0
  663. // establish value for token
  664. // single character literal
  665. if s[0] == '\'' || s[0] == '"' {
  666. q, err := strconv.Unquote(s)
  667. if err != nil {
  668. errorf("invalid token: %s", err)
  669. }
  670. rq := []rune(q)
  671. if len(rq) != 1 {
  672. errorf("character token too long: %s", s)
  673. }
  674. val = int(rq[0])
  675. if val == 0 {
  676. errorf("token value 0 is illegal")
  677. }
  678. tokset[ntokens].noconst = true
  679. } else {
  680. val = extval
  681. extval++
  682. if s[0] == '$' {
  683. tokset[ntokens].noconst = true
  684. }
  685. }
  686. tokset[ntokens].value = val
  687. return ntokens
  688. }
  689. var peekline = 0
  690. func gettok() int {
  691. var i int
  692. var match, c rune
  693. tokname = ""
  694. for {
  695. lineno += peekline
  696. peekline = 0
  697. c = getrune(finput)
  698. for c == ' ' || c == '\n' || c == '\t' || c == '\v' || c == '\r' {
  699. if c == '\n' {
  700. lineno++
  701. }
  702. c = getrune(finput)
  703. }
  704. // skip comment -- fix
  705. if c != '/' {
  706. break
  707. }
  708. lineno += skipcom()
  709. }
  710. switch c {
  711. case EOF:
  712. if tokflag {
  713. fmt.Printf(">>> ENDFILE %v\n", lineno)
  714. }
  715. return ENDFILE
  716. case '{':
  717. ungetrune(finput, c)
  718. if tokflag {
  719. fmt.Printf(">>> ={ %v\n", lineno)
  720. }
  721. return '='
  722. case '<':
  723. // get, and look up, a type name (union member name)
  724. c = getrune(finput)
  725. for c != '>' && c != EOF && c != '\n' {
  726. tokname += string(c)
  727. c = getrune(finput)
  728. }
  729. if c != '>' {
  730. errorf("unterminated < ... > clause")
  731. }
  732. for i = 1; i <= ntypes; i++ {
  733. if typeset[i] == tokname {
  734. numbval = i
  735. if tokflag {
  736. fmt.Printf(">>> TYPENAME old <%v> %v\n", tokname, lineno)
  737. }
  738. return TYPENAME
  739. }
  740. }
  741. ntypes++
  742. numbval = ntypes
  743. typeset[numbval] = tokname
  744. if tokflag {
  745. fmt.Printf(">>> TYPENAME new <%v> %v\n", tokname, lineno)
  746. }
  747. return TYPENAME
  748. case '"', '\'':
  749. match = c
  750. tokname = string(c)
  751. for {
  752. c = getrune(finput)
  753. if c == '\n' || c == EOF {
  754. errorf("illegal or missing ' or \"")
  755. }
  756. if c == '\\' {
  757. tokname += string('\\')
  758. c = getrune(finput)
  759. } else if c == match {
  760. if tokflag {
  761. fmt.Printf(">>> IDENTIFIER \"%v\" %v\n", tokname, lineno)
  762. }
  763. tokname += string(c)
  764. return IDENTIFIER
  765. }
  766. tokname += string(c)
  767. }
  768. case '%':
  769. c = getrune(finput)
  770. switch c {
  771. case '%':
  772. if tokflag {
  773. fmt.Printf(">>> MARK %%%% %v\n", lineno)
  774. }
  775. return MARK
  776. case '=':
  777. if tokflag {
  778. fmt.Printf(">>> PREC %%= %v\n", lineno)
  779. }
  780. return PREC
  781. case '{':
  782. if tokflag {
  783. fmt.Printf(">>> LCURLY %%{ %v\n", lineno)
  784. }
  785. return LCURLY
  786. }
  787. getword(c)
  788. // find a reserved word
  789. for i := range resrv {
  790. if tokname == resrv[i].name {
  791. if tokflag {
  792. fmt.Printf(">>> %%%v %v %v\n", tokname,
  793. resrv[i].value-PRIVATE, lineno)
  794. }
  795. return resrv[i].value
  796. }
  797. }
  798. errorf("invalid escape, or illegal reserved word: %v", tokname)
  799. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  800. numbval = int(c - '0')
  801. for {
  802. c = getrune(finput)
  803. if !isdigit(c) {
  804. break
  805. }
  806. numbval = numbval*10 + int(c-'0')
  807. }
  808. ungetrune(finput, c)
  809. if tokflag {
  810. fmt.Printf(">>> NUMBER %v %v\n", numbval, lineno)
  811. }
  812. return NUMBER
  813. default:
  814. if isword(c) || c == '.' || c == '$' {
  815. getword(c)
  816. break
  817. }
  818. if tokflag {
  819. fmt.Printf(">>> OPERATOR %v %v\n", string(c), lineno)
  820. }
  821. return int(c)
  822. }
  823. // look ahead to distinguish IDENTIFIER from IDENTCOLON
  824. c = getrune(finput)
  825. for c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\r' || c == '/' {
  826. if c == '\n' {
  827. peekline++
  828. }
  829. // look for comments
  830. if c == '/' {
  831. peekline += skipcom()
  832. }
  833. c = getrune(finput)
  834. }
  835. if c == ':' {
  836. if tokflag {
  837. fmt.Printf(">>> IDENTCOLON %v: %v\n", tokname, lineno)
  838. }
  839. return IDENTCOLON
  840. }
  841. ungetrune(finput, c)
  842. if tokflag {
  843. fmt.Printf(">>> IDENTIFIER %v %v\n", tokname, lineno)
  844. }
  845. return IDENTIFIER
  846. }
  847. func getword(c rune) {
  848. tokname = ""
  849. for isword(c) || isdigit(c) || c == '.' || c == '$' {
  850. tokname += string(c)
  851. c = getrune(finput)
  852. }
  853. ungetrune(finput, c)
  854. }
  855. //
  856. // determine the type of a symbol
  857. //
  858. func fdtype(t int) int {
  859. var v int
  860. var s string
  861. if t >= NTBASE {
  862. v = nontrst[t-NTBASE].value
  863. s = nontrst[t-NTBASE].name
  864. } else {
  865. v = TYPE(toklev[t])
  866. s = tokset[t].name
  867. }
  868. if v <= 0 {
  869. errorf("must specify type for %v", s)
  870. }
  871. return v
  872. }
  873. func chfind(t int, s string) int {
  874. if s[0] == '"' || s[0] == '\'' {
  875. t = 0
  876. }
  877. for i := 0; i <= ntokens; i++ {
  878. if s == tokset[i].name {
  879. return i
  880. }
  881. }
  882. for i := 0; i <= nnonter; i++ {
  883. if s == nontrst[i].name {
  884. return NTBASE + i
  885. }
  886. }
  887. // cannot find name
  888. if t > 1 {
  889. errorf("%v should have been defined earlier", s)
  890. }
  891. return defin(t, s)
  892. }
  893. //
  894. // copy the union declaration to the output, and the define file if present
  895. //
  896. func cpyunion() {
  897. if !lflag {
  898. fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno)
  899. }
  900. fmt.Fprintf(ftable, "type %sSymType struct", prefix)
  901. level := 0
  902. out:
  903. for {
  904. c := getrune(finput)
  905. if c == EOF {
  906. errorf("EOF encountered while processing %%union")
  907. }
  908. ftable.WriteRune(c)
  909. switch c {
  910. case '\n':
  911. lineno++
  912. case '{':
  913. if level == 0 {
  914. fmt.Fprintf(ftable, "\n\tyys int")
  915. }
  916. level++
  917. case '}':
  918. level--
  919. if level == 0 {
  920. break out
  921. }
  922. }
  923. }
  924. fmt.Fprintf(ftable, "\n\n")
  925. }
  926. //
  927. // saves code between %{ and %}
  928. // adds an import for __fmt__ the first time
  929. //
  930. func cpycode() {
  931. lno := lineno
  932. c := getrune(finput)
  933. if c == '\n' {
  934. c = getrune(finput)
  935. lineno++
  936. }
  937. if !lflag {
  938. fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno)
  939. }
  940. // accumulate until %}
  941. code := make([]rune, 0, 1024)
  942. for c != EOF {
  943. if c == '%' {
  944. c = getrune(finput)
  945. if c == '}' {
  946. emitcode(code, lno+1)
  947. return
  948. }
  949. code = append(code, '%')
  950. }
  951. code = append(code, c)
  952. if c == '\n' {
  953. lineno++
  954. }
  955. c = getrune(finput)
  956. }
  957. lineno = lno
  958. errorf("eof before %%}")
  959. }
  960. //
  961. // emits code saved up from between %{ and %}
  962. // called by cpycode
  963. // adds an import for __yyfmt__ after the package clause
  964. //
  965. func emitcode(code []rune, lineno int) {
  966. for i, line := range lines(code) {
  967. writecode(line)
  968. if !fmtImported && isPackageClause(line) {
  969. fmt.Fprintln(ftable, `import __yyfmt__ "fmt"`)
  970. if !lflag {
  971. fmt.Fprintf(ftable, "//line %v:%v\n\t\t", infile, lineno+i)
  972. }
  973. fmtImported = true
  974. }
  975. }
  976. }
  977. //
  978. // does this line look like a package clause? not perfect: might be confused by early comments.
  979. //
  980. func isPackageClause(line []rune) bool {
  981. line = skipspace(line)
  982. // must be big enough.
  983. if len(line) < len("package X\n") {
  984. return false
  985. }
  986. // must start with "package"
  987. for i, r := range []rune("package") {
  988. if line[i] != r {
  989. return false
  990. }
  991. }
  992. line = skipspace(line[len("package"):])
  993. // must have another identifier.
  994. if len(line) == 0 || (!unicode.IsLetter(line[0]) && line[0] != '_') {
  995. return false
  996. }
  997. for len(line) > 0 {
  998. if !unicode.IsLetter(line[0]) && !unicode.IsDigit(line[0]) && line[0] != '_' {
  999. break
  1000. }
  1001. line = line[1:]
  1002. }
  1003. line = skipspace(line)
  1004. // eol, newline, or comment must follow
  1005. if len(line) == 0 {
  1006. return true
  1007. }
  1008. if line[0] == '\r' || line[0] == '\n' {
  1009. return true
  1010. }
  1011. if len(line) >= 2 {
  1012. return line[0] == '/' && (line[1] == '/' || line[1] == '*')
  1013. }
  1014. return false
  1015. }
  1016. //
  1017. // skip initial spaces
  1018. //
  1019. func skipspace(line []rune) []rune {
  1020. for len(line) > 0 {
  1021. if line[0] != ' ' && line[0] != '\t' {
  1022. break
  1023. }
  1024. line = line[1:]
  1025. }
  1026. return line
  1027. }
  1028. //
  1029. // break code into lines
  1030. //
  1031. func lines(code []rune) [][]rune {
  1032. l := make([][]rune, 0, 100)
  1033. for len(code) > 0 {
  1034. // one line per loop
  1035. var i int
  1036. for i = range code {
  1037. if code[i] == '\n' {
  1038. break
  1039. }
  1040. }
  1041. l = append(l, code[:i+1])
  1042. code = code[i+1:]
  1043. }
  1044. return l
  1045. }
  1046. //
  1047. // writes code to ftable
  1048. //
  1049. func writecode(code []rune) {
  1050. for _, r := range code {
  1051. ftable.WriteRune(r)
  1052. }
  1053. }
  1054. //
  1055. // skip over comments
  1056. // skipcom is called after reading a '/'
  1057. //
  1058. func skipcom() int {
  1059. c := getrune(finput)
  1060. if c == '/' {
  1061. for c != EOF {
  1062. if c == '\n' {
  1063. return 1
  1064. }
  1065. c = getrune(finput)
  1066. }
  1067. errorf("EOF inside comment")
  1068. return 0
  1069. }
  1070. if c != '*' {
  1071. errorf("illegal comment")
  1072. }
  1073. nl := 0 // lines skipped
  1074. c = getrune(finput)
  1075. l1:
  1076. switch c {
  1077. case '*':
  1078. c = getrune(finput)
  1079. if c == '/' {
  1080. break
  1081. }
  1082. goto l1
  1083. case '\n':
  1084. nl++
  1085. fallthrough
  1086. default:
  1087. c = getrune(finput)
  1088. goto l1
  1089. }
  1090. return nl
  1091. }
  1092. //
  1093. // copy action to the next ; or closing }
  1094. //
  1095. func cpyact(curprod []int, max int) {
  1096. if !lflag {
  1097. fmt.Fprintf(fcode, "\n\t\t//line %v:%v", infile, lineno)
  1098. }
  1099. fmt.Fprint(fcode, "\n\t\t")
  1100. lno := lineno
  1101. brac := 0
  1102. loop:
  1103. for {
  1104. c := getrune(finput)
  1105. swt:
  1106. switch c {
  1107. case ';':
  1108. if brac == 0 {
  1109. fcode.WriteRune(c)
  1110. return
  1111. }
  1112. case '{':
  1113. brac++
  1114. case '$':
  1115. s := 1
  1116. tok := -1
  1117. c = getrune(finput)
  1118. // type description
  1119. if c == '<' {
  1120. ungetrune(finput, c)
  1121. if gettok() != TYPENAME {
  1122. errorf("bad syntax on $<ident> clause")
  1123. }
  1124. tok = numbval
  1125. c = getrune(finput)
  1126. }
  1127. if c == '$' {
  1128. fmt.Fprintf(fcode, "%sVAL", prefix)
  1129. // put out the proper tag...
  1130. if ntypes != 0 {
  1131. if tok < 0 {
  1132. tok = fdtype(curprod[0])
  1133. }
  1134. fmt.Fprintf(fcode, ".%v", typeset[tok])
  1135. }
  1136. continue loop
  1137. }
  1138. if c == '-' {
  1139. s = -s
  1140. c = getrune(finput)
  1141. }
  1142. j := 0
  1143. if isdigit(c) {
  1144. for isdigit(c) {
  1145. j = j*10 + int(c-'0')
  1146. c = getrune(finput)
  1147. }
  1148. ungetrune(finput, c)
  1149. j = j * s
  1150. if j >= max {
  1151. errorf("Illegal use of $%v", j)
  1152. }
  1153. } else if isword(c) || c == '.' {
  1154. // look for $name
  1155. ungetrune(finput, c)
  1156. if gettok() != IDENTIFIER {
  1157. errorf("$ must be followed by an identifier")
  1158. }
  1159. tokn := chfind(2, tokname)
  1160. fnd := -1
  1161. c = getrune(finput)
  1162. if c != '@' {
  1163. ungetrune(finput, c)
  1164. } else if gettok() != NUMBER {
  1165. errorf("@ must be followed by number")
  1166. } else {
  1167. fnd = numbval
  1168. }
  1169. for j = 1; j < max; j++ {
  1170. if tokn == curprod[j] {
  1171. fnd--
  1172. if fnd <= 0 {
  1173. break
  1174. }
  1175. }
  1176. }
  1177. if j >= max {
  1178. errorf("$name or $name@number not found")
  1179. }
  1180. } else {
  1181. fcode.WriteRune('$')
  1182. if s < 0 {
  1183. fcode.WriteRune('-')
  1184. }
  1185. ungetrune(finput, c)
  1186. continue loop
  1187. }
  1188. fmt.Fprintf(fcode, "%sDollar[%v]", prefix, j)
  1189. // put out the proper tag
  1190. if ntypes != 0 {
  1191. if j <= 0 && tok < 0 {
  1192. errorf("must specify type of $%v", j)
  1193. }
  1194. if tok < 0 {
  1195. tok = fdtype(curprod[j])
  1196. }
  1197. fmt.Fprintf(fcode, ".%v", typeset[tok])
  1198. }
  1199. continue loop
  1200. case '}':
  1201. brac--
  1202. if brac != 0 {
  1203. break
  1204. }
  1205. fcode.WriteRune(c)
  1206. return
  1207. case '/':
  1208. nc := getrune(finput)
  1209. if nc != '/' && nc != '*' {
  1210. ungetrune(finput, nc)
  1211. break
  1212. }
  1213. // a comment
  1214. fcode.WriteRune(c)
  1215. fcode.WriteRune(nc)
  1216. c = getrune(finput)
  1217. for c != EOF {
  1218. switch {
  1219. case c == '\n':
  1220. lineno++
  1221. if nc == '/' { // end of // comment
  1222. break swt
  1223. }
  1224. case c == '*' && nc == '*': // end of /* comment?
  1225. nnc := getrune(finput)
  1226. if nnc == '/' {
  1227. fcode.WriteRune('*')
  1228. fcode.WriteRune('/')
  1229. c = getrune(finput)
  1230. break swt
  1231. }
  1232. ungetrune(finput, nnc)
  1233. }
  1234. fcode.WriteRune(c)
  1235. c = getrune(finput)
  1236. }
  1237. errorf("EOF inside comment")
  1238. case '\'', '"':
  1239. // character string or constant
  1240. match := c
  1241. fcode.WriteRune(c)
  1242. c = getrune(finput)
  1243. for c != EOF {
  1244. if c == '\\' {
  1245. fcode.WriteRune(c)
  1246. c = getrune(finput)
  1247. if c == '\n' {
  1248. lineno++
  1249. }
  1250. } else if c == match {
  1251. break swt
  1252. }
  1253. if c == '\n' {
  1254. errorf("newline in string or char const")
  1255. }
  1256. fcode.WriteRune(c)
  1257. c = getrune(finput)
  1258. }
  1259. errorf("EOF in string or character constant")
  1260. case EOF:
  1261. lineno = lno
  1262. errorf("action does not terminate")
  1263. case '\n':
  1264. fmt.Fprint(fcode, "\n\t")
  1265. lineno++
  1266. continue loop
  1267. }
  1268. fcode.WriteRune(c)
  1269. }
  1270. }
  1271. func openup() {
  1272. infile = flag.Arg(0)
  1273. finput = open(infile)
  1274. if finput == nil {
  1275. errorf("cannot open %v", infile)
  1276. }
  1277. foutput = nil
  1278. if vflag != "" {
  1279. foutput = create(vflag)
  1280. if foutput == nil {
  1281. errorf("can't create file %v", vflag)
  1282. }
  1283. }
  1284. ftable = nil
  1285. if oflag == "" {
  1286. oflag = "y.go"
  1287. }
  1288. ftable = create(oflag)
  1289. if ftable == nil {
  1290. errorf("can't create file %v", oflag)
  1291. }
  1292. }
  1293. //
  1294. // return a pointer to the name of symbol i
  1295. //
  1296. func symnam(i int) string {
  1297. var s string
  1298. if i >= NTBASE {
  1299. s = nontrst[i-NTBASE].name
  1300. } else {
  1301. s = tokset[i].name
  1302. }
  1303. return s
  1304. }
  1305. //
  1306. // set elements 0 through n-1 to c
  1307. //
  1308. func aryfil(v []int, n, c int) {
  1309. for i := 0; i < n; i++ {
  1310. v[i] = c
  1311. }
  1312. }
  1313. //
  1314. // compute an array with the beginnings of productions yielding given nonterminals
  1315. // The array pres points to these lists
  1316. // the array pyield has the lists: the total size is only NPROD+1
  1317. //
  1318. func cpres() {
  1319. pres = make([][][]int, nnonter+1)
  1320. curres := make([][]int, nprod)
  1321. if false {
  1322. for j := 0; j <= nnonter; j++ {
  1323. fmt.Printf("nnonter[%v] = %v\n", j, nontrst[j].name)
  1324. }
  1325. for j := 0; j < nprod; j++ {
  1326. fmt.Printf("prdptr[%v][0] = %v+NTBASE\n", j, prdptr[j][0]-NTBASE)
  1327. }
  1328. }
  1329. fatfl = 0 // make undefined symbols nonfatal
  1330. for i := 0; i <= nnonter; i++ {
  1331. n := 0
  1332. c := i + NTBASE
  1333. for j := 0; j < nprod; j++ {
  1334. if prdptr[j][0] == c {
  1335. curres[n] = prdptr[j][1:]
  1336. n++
  1337. }
  1338. }
  1339. if n == 0 {
  1340. errorf("nonterminal %v not defined", nontrst[i].name)
  1341. continue
  1342. }
  1343. pres[i] = make([][]int, n)
  1344. copy(pres[i], curres)
  1345. }
  1346. fatfl = 1
  1347. if nerrors != 0 {
  1348. summary()
  1349. exit(1)
  1350. }
  1351. }
  1352. //
  1353. // mark nonterminals which derive the empty string
  1354. // also, look for nonterminals which don't derive any token strings
  1355. //
  1356. func cempty() {
  1357. var i, p, np int
  1358. var prd []int
  1359. pempty = make([]int, nnonter+1)
  1360. // first, use the array pempty to detect productions that can never be reduced
  1361. // set pempty to WHONOWS
  1362. aryfil(pempty, nnonter+1, WHOKNOWS)
  1363. // now, look at productions, marking nonterminals which derive something
  1364. more:
  1365. for {
  1366. for i = 0; i < nprod; i++ {
  1367. prd = prdptr[i]
  1368. if pempty[prd[0]-NTBASE] != 0 {
  1369. continue
  1370. }
  1371. np = len(prd) - 1
  1372. for p = 1; p < np; p++ {
  1373. if prd[p] >= NTBASE && pempty[prd[p]-NTBASE] == WHOKNOWS {
  1374. break
  1375. }
  1376. }
  1377. // production can be derived
  1378. if p == np {
  1379. pempty[prd[0]-NTBASE] = OK
  1380. continue more
  1381. }
  1382. }
  1383. break
  1384. }
  1385. // now, look at the nonterminals, to see if they are all OK
  1386. for i = 0; i <= nnonter; i++ {
  1387. // the added production rises or falls as the start symbol ...
  1388. if i == 0 {
  1389. continue
  1390. }
  1391. if pempty[i] != OK {
  1392. fatfl = 0
  1393. errorf("nonterminal " + nontrst[i].name + " never derives any token string")
  1394. }
  1395. }
  1396. if nerrors != 0 {
  1397. summary()
  1398. exit(1)
  1399. }
  1400. // now, compute the pempty array, to see which nonterminals derive the empty string
  1401. // set pempty to WHOKNOWS
  1402. aryfil(pempty, nnonter+1, WHOKNOWS)
  1403. // loop as long as we keep finding empty nonterminals
  1404. again:
  1405. for {
  1406. next:
  1407. for i = 1; i < nprod; i++ {
  1408. // not known to be empty
  1409. prd = prdptr[i]
  1410. if pempty[prd[0]-NTBASE] != WHOKNOWS {
  1411. continue
  1412. }
  1413. np = len(prd) - 1
  1414. for p = 1; p < np; p++ {
  1415. if prd[p] < NTBASE || pempty[prd[p]-NTBASE] != EMPTY {
  1416. continue next
  1417. }
  1418. }
  1419. // we have a nontrivially empty nonterminal
  1420. pempty[prd[0]-NTBASE] = EMPTY
  1421. // got one ... try for another
  1422. continue again
  1423. }
  1424. return
  1425. }
  1426. }
  1427. //
  1428. // compute an array with the first of nonterminals
  1429. //
  1430. func cpfir() {
  1431. var s, n, p, np, ch, i int
  1432. var curres [][]int
  1433. var prd []int
  1434. wsets = make([]Wset, nnonter+WSETINC)
  1435. pfirst = make([]Lkset, nnonter+1)
  1436. for i = 0; i <= nnonter; i++ {
  1437. wsets[i].ws = mkset()
  1438. pfirst[i] = mkset()
  1439. curres = pres[i]
  1440. n = len(curres)
  1441. // initially fill the sets
  1442. for s = 0; s < n; s++ {
  1443. prd = curres[s]
  1444. np = len(prd) - 1
  1445. for p = 0; p < np; p++ {
  1446. ch = prd[p]
  1447. if ch < NTBASE {
  1448. setbit(pfirst[i], ch)
  1449. break
  1450. }
  1451. if pempty[ch-NTBASE] == 0 {
  1452. break
  1453. }
  1454. }
  1455. }
  1456. }
  1457. // now, reflect transitivity
  1458. changes := 1
  1459. for changes != 0 {
  1460. changes = 0
  1461. for i = 0; i <= nnonter; i++ {
  1462. curres = pres[i]
  1463. n = len(curres)
  1464. for s = 0; s < n; s++ {
  1465. prd = curres[s]
  1466. np = len(prd) - 1
  1467. for p = 0; p < np; p++ {
  1468. ch = prd[p] - NTBASE
  1469. if ch < 0 {
  1470. break
  1471. }
  1472. changes |= setunion(pfirst[i], pfirst[ch])
  1473. if pempty[ch] == 0 {
  1474. break
  1475. }
  1476. }
  1477. }
  1478. }
  1479. }
  1480. if indebug == 0 {
  1481. return
  1482. }
  1483. if foutput != nil {
  1484. for i = 0; i <= nnonter; i++ {
  1485. fmt.Fprintf(foutput, "\n%v: %v %v\n",
  1486. nontrst[i].name, pfirst[i], pempty[i])
  1487. }
  1488. }
  1489. }
  1490. //
  1491. // generate the states
  1492. //
  1493. func stagen() {
  1494. // initialize
  1495. nstate = 0
  1496. tstates = make([]int, ntokens+1) // states generated by terminal gotos
  1497. ntstates = make([]int, nnonter+1) // states generated by nonterminal gotos
  1498. amem = make([]int, ACTSIZE)
  1499. memp = 0
  1500. clset = mkset()
  1501. pstate[0] = 0
  1502. pstate[1] = 0
  1503. aryfil(clset, tbitset, 0)
  1504. putitem(Pitem{prdptr[0], 0, 0, 0}, clset)
  1505. tystate[0] = MUSTDO
  1506. nstate = 1
  1507. pstate[2] = pstate[1]
  1508. //
  1509. // now, the main state generation loop
  1510. // first pass generates all of the states
  1511. // later passes fix up lookahead
  1512. // could be sped up a lot by remembering
  1513. // results of the first pass rather than recomputing
  1514. //
  1515. first := 1
  1516. for more := 1; more != 0; first = 0 {
  1517. more = 0
  1518. for i := 0; i < nstate; i++ {
  1519. if tystate[i] != MUSTDO {
  1520. continue
  1521. }
  1522. tystate[i] = DONE
  1523. aryfil(temp1, nnonter+1, 0)
  1524. // take state i, close it, and do gotos
  1525. closure(i)
  1526. // generate goto's
  1527. for p := 0; p < cwp; p++ {
  1528. pi := wsets[p]
  1529. if pi.flag != 0 {
  1530. continue
  1531. }
  1532. wsets[p].flag = 1
  1533. c := pi.pitem.first
  1534. if c <= 1 {
  1535. if pstate[i+1]-pstate[i] <= p {
  1536. tystate[i] = MUSTLOOKAHEAD
  1537. }
  1538. continue
  1539. }
  1540. // do a goto on c
  1541. putitem(wsets[p].pitem, wsets[p].ws)
  1542. for q := p + 1; q < cwp; q++ {
  1543. // this item contributes to the goto
  1544. if c == wsets[q].pitem.first {
  1545. putitem(wsets[q].pitem, wsets[q].ws)
  1546. wsets[q].flag = 1
  1547. }
  1548. }
  1549. if c < NTBASE {
  1550. state(c) // register new state
  1551. } else {
  1552. temp1[c-NTBASE] = state(c)
  1553. }
  1554. }
  1555. if gsdebug != 0 && foutput != nil {
  1556. fmt.Fprintf(foutput, "%v: ", i)
  1557. for j := 0; j <= nnonter; j++ {
  1558. if temp1[j] != 0 {
  1559. fmt.Fprintf(foutput, "%v %v,", nontrst[j].name, temp1[j])
  1560. }
  1561. }
  1562. fmt.Fprintf(foutput, "\n")
  1563. }
  1564. if first != 0 {
  1565. indgo[i] = apack(temp1[1:], nnonter-1) - 1
  1566. }
  1567. more++
  1568. }
  1569. }
  1570. }
  1571. //
  1572. // generate the closure of state i
  1573. //
  1574. func closure(i int) {
  1575. zzclose++
  1576. // first, copy kernel of state i to wsets
  1577. cwp = 0
  1578. q := pstate[i+1]
  1579. for p := pstate[i]; p < q; p++ {
  1580. wsets[cwp].pitem = statemem[p].pitem
  1581. wsets[cwp].flag = 1 // this item must get closed
  1582. copy(wsets[cwp].ws, statemem[p].look)
  1583. cwp++
  1584. }
  1585. // now, go through the loop, closing each item
  1586. work := 1
  1587. for work != 0 {
  1588. work = 0
  1589. for u := 0; u < cwp; u++ {
  1590. if wsets[u].flag == 0 {
  1591. continue
  1592. }
  1593. // dot is before c
  1594. c := wsets[u].pitem.first
  1595. if c < NTBASE {
  1596. wsets[u].flag = 0
  1597. // only interesting case is where . is before nonterminal
  1598. continue
  1599. }
  1600. // compute the lookahead
  1601. aryfil(clset, tbitset, 0)
  1602. // find items involving c
  1603. for v := u; v < cwp; v++ {
  1604. if wsets[v].flag != 1 || wsets[v].pitem.first != c {
  1605. continue
  1606. }
  1607. pi := wsets[v].pitem.prod
  1608. ipi := wsets[v].pitem.off + 1
  1609. wsets[v].flag = 0
  1610. if nolook != 0 {
  1611. continue
  1612. }
  1613. ch := pi[ipi]
  1614. ipi++
  1615. for ch > 0 {
  1616. // terminal symbol
  1617. if ch < NTBASE {
  1618. setbit(clset, ch)
  1619. break
  1620. }
  1621. // nonterminal symbol
  1622. setunion(clset, pfirst[ch-NTBASE])
  1623. if pempty[ch-NTBASE] == 0 {
  1624. break
  1625. }
  1626. ch = pi[ipi]
  1627. ipi++
  1628. }
  1629. if ch <= 0 {
  1630. setunion(clset, wsets[v].ws)
  1631. }
  1632. }
  1633. //
  1634. // now loop over productions derived from c
  1635. //
  1636. curres := pres[c-NTBASE]
  1637. n := len(curres)
  1638. nexts:
  1639. // initially fill the sets
  1640. for s := 0; s < n; s++ {
  1641. prd := curres[s]
  1642. //
  1643. // put these items into the closure
  1644. // is the item there
  1645. //
  1646. for v := 0; v < cwp; v++ {
  1647. // yes, it is there
  1648. if wsets[v].pitem.off == 0 &&
  1649. aryeq(wsets[v].pitem.prod, prd) != 0 {
  1650. if nolook == 0 &&
  1651. setunion(wsets[v].ws, clset) != 0 {
  1652. wsets[v].flag = 1
  1653. work = 1
  1654. }
  1655. continue nexts
  1656. }
  1657. }
  1658. // not there; make a new entry
  1659. if cwp >= len(wsets) {
  1660. awsets := make([]Wset, cwp+WSETINC)
  1661. copy(awsets, wsets)
  1662. wsets = awsets
  1663. }
  1664. wsets[cwp].pitem = Pitem{prd, 0, prd[0], -prd[len(prd)-1]}
  1665. wsets[cwp].flag = 1
  1666. wsets[cwp].ws = mkset()
  1667. if nolook == 0 {
  1668. work = 1
  1669. copy(wsets[cwp].ws, clset)
  1670. }
  1671. cwp++
  1672. }
  1673. }
  1674. }
  1675. // have computed closure; flags are reset; return
  1676. if cldebug != 0 && foutput != nil {
  1677. fmt.Fprintf(foutput, "\nState %v, nolook = %v\n", i, nolook)
  1678. for u := 0; u < cwp; u++ {
  1679. if wsets[u].flag != 0 {
  1680. fmt.Fprintf(foutput, "flag set\n")
  1681. }
  1682. wsets[u].flag = 0
  1683. fmt.Fprintf(foutput, "\t%v", writem(wsets[u].pitem))
  1684. prlook(wsets[u].ws)
  1685. fmt.Fprintf(foutput, "\n")
  1686. }
  1687. }
  1688. }
  1689. //
  1690. // sorts last state,and sees if it equals earlier ones. returns state number
  1691. //
  1692. func state(c int) int {
  1693. zzstate++
  1694. p1 := pstate[nstate]
  1695. p2 := pstate[nstate+1]
  1696. if p1 == p2 {
  1697. return 0 // null state
  1698. }
  1699. // sort the items
  1700. var k, l int
  1701. for k = p1 + 1; k < p2; k++ { // make k the biggest
  1702. for l = k; l > p1; l-- {
  1703. if statemem[l].pitem.prodno < statemem[l-1].pitem.prodno ||
  1704. statemem[l].pitem.prodno == statemem[l-1].pitem.prodno &&
  1705. statemem[l].pitem.off < statemem[l-1].pitem.off {
  1706. s := statemem[l]
  1707. statemem[l] = statemem[l-1]
  1708. statemem[l-1] = s
  1709. } else {
  1710. break
  1711. }
  1712. }
  1713. }
  1714. size1 := p2 - p1 // size of state
  1715. var i int
  1716. if c >= NTBASE {
  1717. i = ntstates[c-NTBASE]
  1718. } else {
  1719. i = tstates[c]
  1720. }
  1721. look:
  1722. for ; i != 0; i = mstates[i] {
  1723. // get ith state
  1724. q1 := pstate[i]
  1725. q2 := pstate[i+1]
  1726. size2 := q2 - q1
  1727. if size1 != size2 {
  1728. continue
  1729. }
  1730. k = p1
  1731. for l = q1; l < q2; l++ {
  1732. if aryeq(statemem[l].pitem.prod, statemem[k].pitem.prod) == 0 ||
  1733. statemem[l].pitem.off != statemem[k].pitem.off {
  1734. continue look
  1735. }
  1736. k++
  1737. }
  1738. // found it
  1739. pstate[nstate+1] = pstate[nstate] // delete last state
  1740. // fix up lookaheads
  1741. if nolook != 0 {
  1742. return i
  1743. }
  1744. k = p1
  1745. for l = q1; l < q2; l++ {
  1746. if setunion(statemem[l].look, statemem[k].look) != 0 {
  1747. tystate[i] = MUSTDO
  1748. }
  1749. k++
  1750. }
  1751. return i
  1752. }
  1753. // state is new
  1754. zznewstate++
  1755. if nolook != 0 {
  1756. errorf("yacc state/nolook error")
  1757. }
  1758. pstate[nstate+2] = p2
  1759. if nstate+1 >= NSTATES {
  1760. errorf("too many states")
  1761. }
  1762. if c >= NTBASE {
  1763. mstates[nstate] = ntstates[c-NTBASE]
  1764. ntstates[c-NTBASE] = nstate
  1765. } else {
  1766. mstates[nstate] = tstates[c]
  1767. tstates[c] = nstate
  1768. }
  1769. tystate[nstate] = MUSTDO
  1770. nstate++
  1771. return nstate - 1
  1772. }
  1773. func putitem(p Pitem, set Lkset) {
  1774. p.off++
  1775. p.first = p.prod[p.off]
  1776. if pidebug != 0 && foutput != nil {
  1777. fmt.Fprintf(foutput, "putitem(%v), state %v\n", writem(p), nstate)
  1778. }
  1779. j := pstate[nstate+1]
  1780. if j >= len(statemem) {
  1781. asm := make([]Item, j+STATEINC)
  1782. copy(asm, statemem)
  1783. statemem = asm
  1784. }
  1785. statemem[j].pitem = p
  1786. if nolook == 0 {
  1787. s := mkset()
  1788. copy(s, set)
  1789. statemem[j].look = s
  1790. }
  1791. j++
  1792. pstate[nstate+1] = j
  1793. }
  1794. //
  1795. // creates output string for item pointed to by pp
  1796. //
  1797. func writem(pp Pitem) string {
  1798. var i int
  1799. p := pp.prod
  1800. q := chcopy(nontrst[prdptr[pp.prodno][0]-NTBASE].name) + ": "
  1801. npi := pp.off
  1802. pi := aryeq(p, prdptr[pp.prodno])
  1803. for {
  1804. c := ' '
  1805. if pi == npi {
  1806. c = '.'
  1807. }
  1808. q += string(c)
  1809. i = p[pi]
  1810. pi++
  1811. if i <= 0 {
  1812. break
  1813. }
  1814. q += chcopy(symnam(i))
  1815. }
  1816. // an item calling for a reduction
  1817. i = p[npi]
  1818. if i < 0 {
  1819. q += fmt.Sprintf(" (%v)", -i)
  1820. }
  1821. return q
  1822. }
  1823. //
  1824. // pack state i from temp1 into amem
  1825. //
  1826. func apack(p []int, n int) int {
  1827. //
  1828. // we don't need to worry about checking because
  1829. // we will only look at entries known to be there...
  1830. // eliminate leading and trailing 0's
  1831. //
  1832. off := 0
  1833. pp := 0
  1834. for ; pp <= n && p[pp] == 0; pp++ {
  1835. off--
  1836. }
  1837. // no actions
  1838. if pp > n {
  1839. return 0
  1840. }
  1841. for ; n > pp && p[n] == 0; n-- {
  1842. }
  1843. p = p[pp : n+1]
  1844. // now, find a place for the elements from p to q, inclusive
  1845. r := len(amem) - len(p)
  1846. nextk:
  1847. for rr := 0; rr <= r; rr++ {
  1848. qq := rr
  1849. for pp = 0; pp < len(p); pp++ {
  1850. if p[pp] != 0 {
  1851. if p[pp] != amem[qq] && amem[qq] != 0 {
  1852. continue nextk
  1853. }
  1854. }
  1855. qq++
  1856. }
  1857. // we have found an acceptable k
  1858. if pkdebug != 0 && foutput != nil {
  1859. fmt.Fprintf(foutput, "off = %v, k = %v\n", off+rr, rr)
  1860. }
  1861. qq = rr
  1862. for pp = 0; pp < len(p); pp++ {
  1863. if p[pp] != 0 {
  1864. if qq > memp {
  1865. memp = qq
  1866. }
  1867. amem[qq] = p[pp]
  1868. }
  1869. qq++
  1870. }
  1871. if pkdebug != 0 && foutput != nil {
  1872. for pp = 0; pp <= memp; pp += 10 {
  1873. fmt.Fprintf(foutput, "\n")
  1874. for qq = pp; qq <= pp+9; qq++ {
  1875. fmt.Fprintf(foutput, "%v ", amem[qq])
  1876. }
  1877. fmt.Fprintf(foutput, "\n")
  1878. }
  1879. }
  1880. return off + rr
  1881. }
  1882. errorf("no space in action table")
  1883. return 0
  1884. }
  1885. //
  1886. // print the output for the states
  1887. //
  1888. func output() {
  1889. var c, u, v int
  1890. if !lflag {
  1891. fmt.Fprintf(ftable, "\n//line yacctab:1")
  1892. }
  1893. fmt.Fprintf(ftable, "\nvar %sExca = [...]int{\n", prefix)
  1894. if len(errors) > 0 {
  1895. stateTable = make([]Row, nstate)
  1896. }
  1897. noset := mkset()
  1898. // output the stuff for state i
  1899. for i := 0; i < nstate; i++ {
  1900. nolook = 0
  1901. if tystate[i] != MUSTLOOKAHEAD {
  1902. nolook = 1
  1903. }
  1904. closure(i)
  1905. // output actions
  1906. nolook = 1
  1907. aryfil(temp1, ntokens+nnonter+1, 0)
  1908. for u = 0; u < cwp; u++ {
  1909. c = wsets[u].pitem.first
  1910. if c > 1 && c < NTBASE && temp1[c] == 0 {
  1911. for v = u; v < cwp; v++ {
  1912. if c == wsets[v].pitem.first {
  1913. putitem(wsets[v].pitem, noset)
  1914. }
  1915. }
  1916. temp1[c] = state(c)
  1917. } else if c > NTBASE {
  1918. c -= NTBASE
  1919. if temp1[c+ntokens] == 0 {
  1920. temp1[c+ntokens] = amem[indgo[i]+c]
  1921. }
  1922. }
  1923. }
  1924. if i == 1 {
  1925. temp1[1] = ACCEPTCODE
  1926. }
  1927. // now, we have the shifts; look at the reductions
  1928. lastred = 0
  1929. for u = 0; u < cwp; u++ {
  1930. c = wsets[u].pitem.first
  1931. // reduction
  1932. if c > 0 {
  1933. continue
  1934. }
  1935. lastred = -c
  1936. us := wsets[u].ws
  1937. for k := 0; k <= ntokens; k++ {
  1938. if bitset(us, k) == 0 {
  1939. continue
  1940. }
  1941. if temp1[k] == 0 {
  1942. temp1[k] = c
  1943. } else if temp1[k] < 0 { // reduce/reduce conflict
  1944. if foutput != nil {
  1945. fmt.Fprintf(foutput,
  1946. "\n %v: reduce/reduce conflict (red'ns "+
  1947. "%v and %v) on %v",
  1948. i, -temp1[k], lastred, symnam(k))
  1949. }
  1950. if -temp1[k] > lastred {
  1951. temp1[k] = -lastred
  1952. }
  1953. zzrrconf++
  1954. } else {
  1955. // potential shift/reduce conflict
  1956. precftn(lastred, k, i)
  1957. }
  1958. }
  1959. }
  1960. wract(i)
  1961. }
  1962. fmt.Fprintf(ftable, "}\n")
  1963. ftable.WriteRune('\n')
  1964. fmt.Fprintf(ftable, "const %sPrivate = %v\n", prefix, PRIVATE)
  1965. }
  1966. //
  1967. // decide a shift/reduce conflict by precedence.
  1968. // r is a rule number, t a token number
  1969. // the conflict is in state s
  1970. // temp1[t] is changed to reflect the action
  1971. //
  1972. func precftn(r, t, s int) {
  1973. action := NOASC
  1974. lp := levprd[r]
  1975. lt := toklev[t]
  1976. if PLEVEL(lt) == 0 || PLEVEL(lp) == 0 {
  1977. // conflict
  1978. if foutput != nil {
  1979. fmt.Fprintf(foutput,
  1980. "\n%v: shift/reduce conflict (shift %v(%v), red'n %v(%v)) on %v",
  1981. s, temp1[t], PLEVEL(lt), r, PLEVEL(lp), symnam(t))
  1982. }
  1983. zzsrconf++
  1984. return
  1985. }
  1986. if PLEVEL(lt) == PLEVEL(lp) {
  1987. action = ASSOC(lt)
  1988. } else if PLEVEL(lt) > PLEVEL(lp) {
  1989. action = RASC // shift
  1990. } else {
  1991. action = LASC
  1992. } // reduce
  1993. switch action {
  1994. case BASC: // error action
  1995. temp1[t] = ERRCODE
  1996. case LASC: // reduce
  1997. temp1[t] = -r
  1998. }
  1999. }
  2000. //
  2001. // output state i
  2002. // temp1 has the actions, lastred the default
  2003. //
  2004. func wract(i int) {
  2005. var p, p1 int
  2006. // find the best choice for lastred
  2007. lastred = 0
  2008. ntimes := 0
  2009. for j := 0; j <= ntokens; j++ {
  2010. if temp1[j] >= 0 {
  2011. continue
  2012. }
  2013. if temp1[j]+lastred == 0 {
  2014. continue
  2015. }
  2016. // count the number of appearances of temp1[j]
  2017. count := 0
  2018. tred := -temp1[j]
  2019. levprd[tred] |= REDFLAG
  2020. for p = 0; p <= ntokens; p++ {
  2021. if temp1[p]+tred == 0 {
  2022. count++
  2023. }
  2024. }
  2025. if count > ntimes {
  2026. lastred = tred
  2027. ntimes = count
  2028. }
  2029. }
  2030. //
  2031. // for error recovery, arrange that, if there is a shift on the
  2032. // error recovery token, `error', that the default be the error action
  2033. //
  2034. if temp1[2] > 0 {
  2035. lastred = 0
  2036. }
  2037. // clear out entries in temp1 which equal lastred
  2038. // count entries in optst table
  2039. n := 0
  2040. for p = 0; p <= ntokens; p++ {
  2041. p1 = temp1[p]
  2042. if p1+lastred == 0 {
  2043. temp1[p] = 0
  2044. p1 = 0
  2045. }
  2046. if p1 > 0 && p1 != ACCEPTCODE && p1 != ERRCODE {
  2047. n++
  2048. }
  2049. }
  2050. wrstate(i)
  2051. defact[i] = lastred
  2052. flag := 0
  2053. os := make([]int, n*2)
  2054. n = 0
  2055. for p = 0; p <= ntokens; p++ {
  2056. p1 = temp1[p]
  2057. if p1 != 0 {
  2058. if p1 < 0 {
  2059. p1 = -p1
  2060. } else if p1 == ACCEPTCODE {
  2061. p1 = -1
  2062. } else if p1 == ERRCODE {
  2063. p1 = 0
  2064. } else {
  2065. os[n] = p
  2066. n++
  2067. os[n] = p1
  2068. n++
  2069. zzacent++
  2070. continue
  2071. }
  2072. if flag == 0 {
  2073. fmt.Fprintf(ftable, "\t-1, %v,\n", i)
  2074. }
  2075. flag++
  2076. fmt.Fprintf(ftable, "\t%v, %v,\n", p, p1)
  2077. zzexcp++
  2078. }
  2079. }
  2080. if flag != 0 {
  2081. defact[i] = -2
  2082. fmt.Fprintf(ftable, "\t-2, %v,\n", lastred)
  2083. }
  2084. optst[i] = os
  2085. }
  2086. //
  2087. // writes state i
  2088. //
  2089. func wrstate(i int) {
  2090. var j0, j1, u int
  2091. var pp, qq int
  2092. if len(errors) > 0 {
  2093. actions := append([]int(nil), temp1...)
  2094. defaultAction := ERRCODE
  2095. if lastred != 0 {
  2096. defaultAction = -lastred
  2097. }
  2098. stateTable[i] = Row{actions, defaultAction}
  2099. }
  2100. if foutput == nil {
  2101. return
  2102. }
  2103. fmt.Fprintf(foutput, "\nstate %v\n", i)
  2104. qq = pstate[i+1]
  2105. for pp = pstate[i]; pp < qq; pp++ {
  2106. fmt.Fprintf(foutput, "\t%v\n", writem(statemem[pp].pitem))
  2107. }
  2108. if tystate[i] == MUSTLOOKAHEAD {
  2109. // print out empty productions in closure
  2110. for u = pstate[i+1] - pstate[i]; u < cwp; u++ {
  2111. if wsets[u].pitem.first < 0 {
  2112. fmt.Fprintf(foutput, "\t%v\n", writem(wsets[u].pitem))
  2113. }
  2114. }
  2115. }
  2116. // check for state equal to another
  2117. for j0 = 0; j0 <= ntokens; j0++ {
  2118. j1 = temp1[j0]
  2119. if j1 != 0 {
  2120. fmt.Fprintf(foutput, "\n\t%v ", symnam(j0))
  2121. // shift, error, or accept
  2122. if j1 > 0 {
  2123. if j1 == ACCEPTCODE {
  2124. fmt.Fprintf(foutput, "accept")
  2125. } else if j1 == ERRCODE {
  2126. fmt.Fprintf(foutput, "error")
  2127. } else {
  2128. fmt.Fprintf(foutput, "shift %v", j1)
  2129. }
  2130. } else {
  2131. fmt.Fprintf(foutput, "reduce %v (src line %v)", -j1, rlines[-j1])
  2132. }
  2133. }
  2134. }
  2135. // output the final production
  2136. if lastred != 0 {
  2137. fmt.Fprintf(foutput, "\n\t. reduce %v (src line %v)\n\n",
  2138. lastred, rlines[lastred])
  2139. } else {
  2140. fmt.Fprintf(foutput, "\n\t. error\n\n")
  2141. }
  2142. // now, output nonterminal actions
  2143. j1 = ntokens
  2144. for j0 = 1; j0 <= nnonter; j0++ {
  2145. j1++
  2146. if temp1[j1] != 0 {
  2147. fmt.Fprintf(foutput, "\t%v goto %v\n", symnam(j0+NTBASE), temp1[j1])
  2148. }
  2149. }
  2150. }
  2151. //
  2152. // output the gotos for the nontermninals
  2153. //
  2154. func go2out() {
  2155. for i := 1; i <= nnonter; i++ {
  2156. go2gen(i)
  2157. // find the best one to make default
  2158. best := -1
  2159. times := 0
  2160. // is j the most frequent
  2161. for j := 0; j < nstate; j++ {
  2162. if tystate[j] == 0 {
  2163. continue
  2164. }
  2165. if tystate[j] == best {
  2166. continue
  2167. }
  2168. // is tystate[j] the most frequent
  2169. count := 0
  2170. cbest := tystate[j]
  2171. for k := j; k < nstate; k++ {
  2172. if tystate[k] == cbest {
  2173. count++
  2174. }
  2175. }
  2176. if count > times {
  2177. best = cbest
  2178. times = count
  2179. }
  2180. }
  2181. // best is now the default entry
  2182. zzgobest += times - 1
  2183. n := 0
  2184. for j := 0; j < nstate; j++ {
  2185. if tystate[j] != 0 && tystate[j] != best {
  2186. n++
  2187. }
  2188. }
  2189. goent := make([]int, 2*n+1)
  2190. n = 0
  2191. for j := 0; j < nstate; j++ {
  2192. if tystate[j] != 0 && tystate[j] != best {
  2193. goent[n] = j
  2194. n++
  2195. goent[n] = tystate[j]
  2196. n++
  2197. zzgoent++
  2198. }
  2199. }
  2200. // now, the default
  2201. if best == -1 {
  2202. best = 0
  2203. }
  2204. zzgoent++
  2205. goent[n] = best
  2206. yypgo[i] = goent
  2207. }
  2208. }
  2209. //
  2210. // output the gotos for nonterminal c
  2211. //
  2212. func go2gen(c int) {
  2213. var i, cc, p, q int
  2214. // first, find nonterminals with gotos on c
  2215. aryfil(temp1, nnonter+1, 0)
  2216. temp1[c] = 1
  2217. work := 1
  2218. for work != 0 {
  2219. work = 0
  2220. for i = 0; i < nprod; i++ {
  2221. // cc is a nonterminal with a goto on c
  2222. cc = prdptr[i][1] - NTBASE
  2223. if cc >= 0 && temp1[cc] != 0 {
  2224. // thus, the left side of production i does too
  2225. cc = prdptr[i][0] - NTBASE
  2226. if temp1[cc] == 0 {
  2227. work = 1
  2228. temp1[cc] = 1
  2229. }
  2230. }
  2231. }
  2232. }
  2233. // now, we have temp1[c] = 1 if a goto on c in closure of cc
  2234. if g2debug != 0 && foutput != nil {
  2235. fmt.Fprintf(foutput, "%v: gotos on ", nontrst[c].name)
  2236. for i = 0; i <= nnonter; i++ {
  2237. if temp1[i] != 0 {
  2238. fmt.Fprintf(foutput, "%v ", nontrst[i].name)
  2239. }
  2240. }
  2241. fmt.Fprintf(foutput, "\n")
  2242. }
  2243. // now, go through and put gotos into tystate
  2244. aryfil(tystate, nstate, 0)
  2245. for i = 0; i < nstate; i++ {
  2246. q = pstate[i+1]
  2247. for p = pstate[i]; p < q; p++ {
  2248. cc = statemem[p].pitem.first
  2249. if cc >= NTBASE {
  2250. // goto on c is possible
  2251. if temp1[cc-NTBASE] != 0 {
  2252. tystate[i] = amem[indgo[i]+c]
  2253. break
  2254. }
  2255. }
  2256. }
  2257. }
  2258. }
  2259. //
  2260. // in order to free up the mem and amem arrays for the optimizer,
  2261. // and still be able to output yyr1, etc., after the sizes of
  2262. // the action array is known, we hide the nonterminals
  2263. // derived by productions in levprd.
  2264. //
  2265. func hideprod() {
  2266. nred := 0
  2267. levprd[0] = 0
  2268. for i := 1; i < nprod; i++ {
  2269. if (levprd[i] & REDFLAG) == 0 {
  2270. if foutput != nil {
  2271. fmt.Fprintf(foutput, "Rule not reduced: %v\n",
  2272. writem(Pitem{prdptr[i], 0, 0, i}))
  2273. }
  2274. fmt.Printf("rule %v never reduced\n", writem(Pitem{prdptr[i], 0, 0, i}))
  2275. nred++
  2276. }
  2277. levprd[i] = prdptr[i][0] - NTBASE
  2278. }
  2279. if nred != 0 {
  2280. fmt.Printf("%v rules never reduced\n", nred)
  2281. }
  2282. }
  2283. func callopt() {
  2284. var j, k, p, q, i int
  2285. var v []int
  2286. pgo = make([]int, nnonter+1)
  2287. pgo[0] = 0
  2288. maxoff = 0
  2289. maxspr = 0
  2290. for i = 0; i < nstate; i++ {
  2291. k = 32000
  2292. j = 0
  2293. v = optst[i]
  2294. q = len(v)
  2295. for p = 0; p < q; p += 2 {
  2296. if v[p] > j {
  2297. j = v[p]
  2298. }
  2299. if v[p] < k {
  2300. k = v[p]
  2301. }
  2302. }
  2303. // nontrivial situation
  2304. if k <= j {
  2305. // j is now the range
  2306. // j -= k; // call scj
  2307. if k > maxoff {
  2308. maxoff = k
  2309. }
  2310. }
  2311. tystate[i] = q + 2*j
  2312. if j > maxspr {
  2313. maxspr = j
  2314. }
  2315. }
  2316. // initialize ggreed table
  2317. ggreed = make([]int, nnonter+1)
  2318. for i = 1; i <= nnonter; i++ {
  2319. ggreed[i] = 1
  2320. j = 0
  2321. // minimum entry index is always 0
  2322. v = yypgo[i]
  2323. q = len(v) - 1
  2324. for p = 0; p < q; p += 2 {
  2325. ggreed[i] += 2
  2326. if v[p] > j {
  2327. j = v[p]
  2328. }
  2329. }
  2330. ggreed[i] = ggreed[i] + 2*j
  2331. if j > maxoff {
  2332. maxoff = j
  2333. }
  2334. }
  2335. // now, prepare to put the shift actions into the amem array
  2336. for i = 0; i < ACTSIZE; i++ {
  2337. amem[i] = 0
  2338. }
  2339. maxa = 0
  2340. for i = 0; i < nstate; i++ {
  2341. if tystate[i] == 0 && adb > 1 {
  2342. fmt.Fprintf(ftable, "State %v: null\n", i)
  2343. }
  2344. indgo[i] = yyFlag
  2345. }
  2346. i = nxti()
  2347. for i != NOMORE {
  2348. if i >= 0 {
  2349. stin(i)
  2350. } else {
  2351. gin(-i)
  2352. }
  2353. i = nxti()
  2354. }
  2355. // print amem array
  2356. if adb > 2 {
  2357. for p = 0; p <= maxa; p += 10 {
  2358. fmt.Fprintf(ftable, "%v ", p)
  2359. for i = 0; i < 10; i++ {
  2360. fmt.Fprintf(ftable, "%v ", amem[p+i])
  2361. }
  2362. ftable.WriteRune('\n')
  2363. }
  2364. }
  2365. aoutput()
  2366. osummary()
  2367. }
  2368. //
  2369. // finds the next i
  2370. //
  2371. func nxti() int {
  2372. max := 0
  2373. maxi := 0
  2374. for i := 1; i <= nnonter; i++ {
  2375. if ggreed[i] >= max {
  2376. max = ggreed[i]
  2377. maxi = -i
  2378. }
  2379. }
  2380. for i := 0; i < nstate; i++ {
  2381. if tystate[i] >= max {
  2382. max = tystate[i]
  2383. maxi = i
  2384. }
  2385. }
  2386. if max == 0 {
  2387. return NOMORE
  2388. }
  2389. return maxi
  2390. }
  2391. func gin(i int) {
  2392. var s int
  2393. // enter gotos on nonterminal i into array amem
  2394. ggreed[i] = 0
  2395. q := yypgo[i]
  2396. nq := len(q) - 1
  2397. // now, find amem place for it
  2398. nextgp:
  2399. for p := 0; p < ACTSIZE; p++ {
  2400. if amem[p] != 0 {
  2401. continue
  2402. }
  2403. for r := 0; r < nq; r += 2 {
  2404. s = p + q[r] + 1
  2405. if s > maxa {
  2406. maxa = s
  2407. if maxa >= ACTSIZE {
  2408. errorf("a array overflow")
  2409. }
  2410. }
  2411. if amem[s] != 0 {
  2412. continue nextgp
  2413. }
  2414. }
  2415. // we have found amem spot
  2416. amem[p] = q[nq]
  2417. if p > maxa {
  2418. maxa = p
  2419. }
  2420. for r := 0; r < nq; r += 2 {
  2421. s = p + q[r] + 1
  2422. amem[s] = q[r+1]
  2423. }
  2424. pgo[i] = p
  2425. if adb > 1 {
  2426. fmt.Fprintf(ftable, "Nonterminal %v, entry at %v\n", i, pgo[i])
  2427. }
  2428. return
  2429. }
  2430. errorf("cannot place goto %v\n", i)
  2431. }
  2432. func stin(i int) {
  2433. var s int
  2434. tystate[i] = 0
  2435. // enter state i into the amem array
  2436. q := optst[i]
  2437. nq := len(q)
  2438. nextn:
  2439. // find an acceptable place
  2440. for n := -maxoff; n < ACTSIZE; n++ {
  2441. flag := 0
  2442. for r := 0; r < nq; r += 2 {
  2443. s = q[r] + n
  2444. if s < 0 || s > ACTSIZE {
  2445. continue nextn
  2446. }
  2447. if amem[s] == 0 {
  2448. flag++
  2449. } else if amem[s] != q[r+1] {
  2450. continue nextn
  2451. }
  2452. }
  2453. // check the position equals another only if the states are identical
  2454. for j := 0; j < nstate; j++ {
  2455. if indgo[j] == n {
  2456. // we have some disagreement
  2457. if flag != 0 {
  2458. continue nextn
  2459. }
  2460. if nq == len(optst[j]) {
  2461. // states are equal
  2462. indgo[i] = n
  2463. if adb > 1 {
  2464. fmt.Fprintf(ftable, "State %v: entry at"+
  2465. "%v equals state %v\n",
  2466. i, n, j)
  2467. }
  2468. return
  2469. }
  2470. // we have some disagreement
  2471. continue nextn
  2472. }
  2473. }
  2474. for r := 0; r < nq; r += 2 {
  2475. s = q[r] + n
  2476. if s > maxa {
  2477. maxa = s
  2478. }
  2479. if amem[s] != 0 && amem[s] != q[r+1] {
  2480. errorf("clobber of a array, pos'n %v, by %v", s, q[r+1])
  2481. }
  2482. amem[s] = q[r+1]
  2483. }
  2484. indgo[i] = n
  2485. if adb > 1 {
  2486. fmt.Fprintf(ftable, "State %v: entry at %v\n", i, indgo[i])
  2487. }
  2488. return
  2489. }
  2490. errorf("Error; failure to place state %v", i)
  2491. }
  2492. //
  2493. // this version is for limbo
  2494. // write out the optimized parser
  2495. //
  2496. func aoutput() {
  2497. ftable.WriteRune('\n')
  2498. fmt.Fprintf(ftable, "const %sLast = %v\n\n", prefix, maxa+1)
  2499. arout("Act", amem, maxa+1)
  2500. arout("Pact", indgo, nstate)
  2501. arout("Pgo", pgo, nnonter+1)
  2502. }
  2503. //
  2504. // put out other arrays, copy the parsers
  2505. //
  2506. func others() {
  2507. var i, j int
  2508. arout("R1", levprd, nprod)
  2509. aryfil(temp1, nprod, 0)
  2510. //
  2511. //yyr2 is the number of rules for each production
  2512. //
  2513. for i = 1; i < nprod; i++ {
  2514. temp1[i] = len(prdptr[i]) - 2
  2515. }
  2516. arout("R2", temp1, nprod)
  2517. aryfil(temp1, nstate, -1000)
  2518. for i = 0; i <= ntokens; i++ {
  2519. for j := tstates[i]; j != 0; j = mstates[j] {
  2520. temp1[j] = i
  2521. }
  2522. }
  2523. for i = 0; i <= nnonter; i++ {
  2524. for j = ntstates[i]; j != 0; j = mstates[j] {
  2525. temp1[j] = -i
  2526. }
  2527. }
  2528. arout("Chk", temp1, nstate)
  2529. arout("Def", defact, nstate)
  2530. // put out token translation tables
  2531. // table 1 has 0-256
  2532. aryfil(temp1, 256, 0)
  2533. c := 0
  2534. for i = 1; i <= ntokens; i++ {
  2535. j = tokset[i].value
  2536. if j >= 0 && j < 256 {
  2537. if temp1[j] != 0 {
  2538. fmt.Print("yacc bug -- cannot have 2 different Ts with same value\n")
  2539. fmt.Printf(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name)
  2540. nerrors++
  2541. }
  2542. temp1[j] = i
  2543. if j > c {
  2544. c = j
  2545. }
  2546. }
  2547. }
  2548. for i = 0; i <= c; i++ {
  2549. if temp1[i] == 0 {
  2550. temp1[i] = YYLEXUNK
  2551. }
  2552. }
  2553. arout("Tok1", temp1, c+1)
  2554. // table 2 has PRIVATE-PRIVATE+256
  2555. aryfil(temp1, 256, 0)
  2556. c = 0
  2557. for i = 1; i <= ntokens; i++ {
  2558. j = tokset[i].value - PRIVATE
  2559. if j >= 0 && j < 256 {
  2560. if temp1[j] != 0 {
  2561. fmt.Print("yacc bug -- cannot have 2 different Ts with same value\n")
  2562. fmt.Printf(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name)
  2563. nerrors++
  2564. }
  2565. temp1[j] = i
  2566. if j > c {
  2567. c = j
  2568. }
  2569. }
  2570. }
  2571. arout("Tok2", temp1, c+1)
  2572. // table 3 has everything else
  2573. fmt.Fprintf(ftable, "var %sTok3 = [...]int{\n\t", prefix)
  2574. c = 0
  2575. for i = 1; i <= ntokens; i++ {
  2576. j = tokset[i].value
  2577. if j >= 0 && j < 256 {
  2578. continue
  2579. }
  2580. if j >= PRIVATE && j < 256+PRIVATE {
  2581. continue
  2582. }
  2583. if c%5 != 0 {
  2584. ftable.WriteRune(' ')
  2585. }
  2586. fmt.Fprintf(ftable, "%d, %d,", j, i)
  2587. c++
  2588. if c%5 == 0 {
  2589. fmt.Fprint(ftable, "\n\t")
  2590. }
  2591. }
  2592. if c%5 != 0 {
  2593. ftable.WriteRune(' ')
  2594. }
  2595. fmt.Fprintf(ftable, "%d,\n}\n", 0)
  2596. // Custom error messages.
  2597. fmt.Fprintf(ftable, "\n")
  2598. fmt.Fprintf(ftable, "var %sErrorMessages = [...]struct {\n", prefix)
  2599. fmt.Fprintf(ftable, "\tstate int\n")
  2600. fmt.Fprintf(ftable, "\ttoken int\n")
  2601. fmt.Fprintf(ftable, "\tmsg string\n")
  2602. fmt.Fprintf(ftable, "}{\n")
  2603. for _, error := range errors {
  2604. lineno = error.lineno
  2605. state, token := runMachine(error.tokens)
  2606. fmt.Fprintf(ftable, "\t{%v, %v, %s},\n", state, token, error.msg)
  2607. }
  2608. fmt.Fprintf(ftable, "}\n")
  2609. // copy parser text
  2610. ch := getrune(finput)
  2611. for ch != EOF {
  2612. ftable.WriteRune(ch)
  2613. ch = getrune(finput)
  2614. }
  2615. // copy yaccpar
  2616. if !lflag {
  2617. fmt.Fprintf(ftable, "\n//line yaccpar:1\n")
  2618. }
  2619. parts := strings.SplitN(yaccpar, prefix+"run()", 2)
  2620. fmt.Fprintf(ftable, "%v", parts[0])
  2621. ftable.Write(fcode.Bytes())
  2622. fmt.Fprintf(ftable, "%v", parts[1])
  2623. }
  2624. func runMachine(tokens []string) (state, token int) {
  2625. var stack []int
  2626. i := 0
  2627. token = -1
  2628. Loop:
  2629. if token < 0 {
  2630. token = chfind(2, tokens[i])
  2631. i++
  2632. }
  2633. row := stateTable[state]
  2634. c := token
  2635. if token >= NTBASE {
  2636. c = token - NTBASE + ntokens
  2637. }
  2638. action := row.actions[c]
  2639. if action == 0 {
  2640. action = row.defaultAction
  2641. }
  2642. switch {
  2643. case action == ACCEPTCODE:
  2644. errorf("tokens are accepted")
  2645. return
  2646. case action == ERRCODE:
  2647. if token >= NTBASE {
  2648. errorf("error at non-terminal token %s", symnam(token))
  2649. }
  2650. return
  2651. case action > 0:
  2652. // Shift to state action.
  2653. stack = append(stack, state)
  2654. state = action
  2655. token = -1
  2656. goto Loop
  2657. default:
  2658. // Reduce by production -action.
  2659. prod := prdptr[-action]
  2660. if rhsLen := len(prod) - 2; rhsLen > 0 {
  2661. n := len(stack) - rhsLen
  2662. state = stack[n]
  2663. stack = stack[:n]
  2664. }
  2665. if token >= 0 {
  2666. i--
  2667. }
  2668. token = prod[0]
  2669. goto Loop
  2670. }
  2671. }
  2672. func arout(s string, v []int, n int) {
  2673. s = prefix + s
  2674. fmt.Fprintf(ftable, "var %v = [...]int{\n", s)
  2675. for i := 0; i < n; i++ {
  2676. if i%10 == 0 {
  2677. fmt.Fprintf(ftable, "\n\t")
  2678. } else {
  2679. ftable.WriteRune(' ')
  2680. }
  2681. fmt.Fprintf(ftable, "%d,", v[i])
  2682. }
  2683. fmt.Fprintf(ftable, "\n}\n")
  2684. }
  2685. //
  2686. // output the summary on y.output
  2687. //
  2688. func summary() {
  2689. if foutput != nil {
  2690. fmt.Fprintf(foutput, "\n%v terminals, %v nonterminals\n", ntokens, nnonter+1)
  2691. fmt.Fprintf(foutput, "%v grammar rules, %v/%v states\n", nprod, nstate, NSTATES)
  2692. fmt.Fprintf(foutput, "%v shift/reduce, %v reduce/reduce conflicts reported\n", zzsrconf, zzrrconf)
  2693. fmt.Fprintf(foutput, "%v working sets used\n", len(wsets))
  2694. fmt.Fprintf(foutput, "memory: parser %v/%v\n", memp, ACTSIZE)
  2695. fmt.Fprintf(foutput, "%v extra closures\n", zzclose-2*nstate)
  2696. fmt.Fprintf(foutput, "%v shift entries, %v exceptions\n", zzacent, zzexcp)
  2697. fmt.Fprintf(foutput, "%v goto entries\n", zzgoent)
  2698. fmt.Fprintf(foutput, "%v entries saved by goto default\n", zzgobest)
  2699. }
  2700. if zzsrconf != 0 || zzrrconf != 0 {
  2701. fmt.Printf("\nconflicts: ")
  2702. if zzsrconf != 0 {
  2703. fmt.Printf("%v shift/reduce", zzsrconf)
  2704. }
  2705. if zzsrconf != 0 && zzrrconf != 0 {
  2706. fmt.Printf(", ")
  2707. }
  2708. if zzrrconf != 0 {
  2709. fmt.Printf("%v reduce/reduce", zzrrconf)
  2710. }
  2711. fmt.Printf("\n")
  2712. }
  2713. }
  2714. //
  2715. // write optimizer summary
  2716. //
  2717. func osummary() {
  2718. if foutput == nil {
  2719. return
  2720. }
  2721. i := 0
  2722. for p := maxa; p >= 0; p-- {
  2723. if amem[p] == 0 {
  2724. i++
  2725. }
  2726. }
  2727. fmt.Fprintf(foutput, "Optimizer space used: output %v/%v\n", maxa+1, ACTSIZE)
  2728. fmt.Fprintf(foutput, "%v table entries, %v zero\n", maxa+1, i)
  2729. fmt.Fprintf(foutput, "maximum spread: %v, maximum offset: %v\n", maxspr, maxoff)
  2730. }
  2731. //
  2732. // copies and protects "'s in q
  2733. //
  2734. func chcopy(q string) string {
  2735. s := ""
  2736. i := 0
  2737. j := 0
  2738. for i = 0; i < len(q); i++ {
  2739. if q[i] == '"' {
  2740. s += q[j:i] + "\\"
  2741. j = i
  2742. }
  2743. }
  2744. return s + q[j:i]
  2745. }
  2746. func usage() {
  2747. fmt.Fprintf(stderr, "usage: yacc [-o output] [-v parsetable] input\n")
  2748. exit(1)
  2749. }
  2750. func bitset(set Lkset, bit int) int { return set[bit>>5] & (1 << uint(bit&31)) }
  2751. func setbit(set Lkset, bit int) { set[bit>>5] |= (1 << uint(bit&31)) }
  2752. func mkset() Lkset { return make([]int, tbitset) }
  2753. //
  2754. // set a to the union of a and b
  2755. // return 1 if b is not a subset of a, 0 otherwise
  2756. //
  2757. func setunion(a, b []int) int {
  2758. sub := 0
  2759. for i := 0; i < tbitset; i++ {
  2760. x := a[i]
  2761. y := x | b[i]
  2762. a[i] = y
  2763. if y != x {
  2764. sub = 1
  2765. }
  2766. }
  2767. return sub
  2768. }
  2769. func prlook(p Lkset) {
  2770. if p == nil {
  2771. fmt.Fprintf(foutput, "\tNULL")
  2772. return
  2773. }
  2774. fmt.Fprintf(foutput, " { ")
  2775. for j := 0; j <= ntokens; j++ {
  2776. if bitset(p, j) != 0 {
  2777. fmt.Fprintf(foutput, "%v ", symnam(j))
  2778. }
  2779. }
  2780. fmt.Fprintf(foutput, "}")
  2781. }
  2782. //
  2783. // utility routines
  2784. //
  2785. var peekrune rune
  2786. func isdigit(c rune) bool { return c >= '0' && c <= '9' }
  2787. func isword(c rune) bool {
  2788. return c >= 0xa0 || c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
  2789. }
  2790. //
  2791. // return 1 if 2 arrays are equal
  2792. // return 0 if not equal
  2793. //
  2794. func aryeq(a []int, b []int) int {
  2795. n := len(a)
  2796. if len(b) != n {
  2797. return 0
  2798. }
  2799. for ll := 0; ll < n; ll++ {
  2800. if a[ll] != b[ll] {
  2801. return 0
  2802. }
  2803. }
  2804. return 1
  2805. }
  2806. func getrune(f *bufio.Reader) rune {
  2807. var r rune
  2808. if peekrune != 0 {
  2809. if peekrune == EOF {
  2810. return EOF
  2811. }
  2812. r = peekrune
  2813. peekrune = 0
  2814. return r
  2815. }
  2816. c, n, err := f.ReadRune()
  2817. if n == 0 {
  2818. return EOF
  2819. }
  2820. if err != nil {
  2821. errorf("read error: %v", err)
  2822. }
  2823. //fmt.Printf("rune = %v n=%v\n", string(c), n);
  2824. return c
  2825. }
  2826. func ungetrune(f *bufio.Reader, c rune) {
  2827. if f != finput {
  2828. panic("ungetc - not finput")
  2829. }
  2830. if peekrune != 0 {
  2831. panic("ungetc - 2nd unget")
  2832. }
  2833. peekrune = c
  2834. }
  2835. func open(s string) *bufio.Reader {
  2836. fi, err := os.Open(s)
  2837. if err != nil {
  2838. errorf("error opening %v: %v", s, err)
  2839. }
  2840. //fmt.Printf("open %v\n", s);
  2841. return bufio.NewReader(fi)
  2842. }
  2843. func create(s string) *bufio.Writer {
  2844. fo, err := os.Create(s)
  2845. if err != nil {
  2846. errorf("error creating %v: %v", s, err)
  2847. }
  2848. //fmt.Printf("create %v mode %v\n", s);
  2849. return bufio.NewWriter(fo)
  2850. }
  2851. //
  2852. // write out error comment
  2853. //
  2854. func lerrorf(lineno int, s string, v ...interface{}) {
  2855. nerrors++
  2856. fmt.Fprintf(stderr, s, v...)
  2857. fmt.Fprintf(stderr, ": %v:%v\n", infile, lineno)
  2858. if fatfl != 0 {
  2859. summary()
  2860. exit(1)
  2861. }
  2862. }
  2863. func errorf(s string, v ...interface{}) {
  2864. lerrorf(lineno, s, v...)
  2865. }
  2866. func exit(status int) {
  2867. if ftable != nil {
  2868. ftable.Flush()
  2869. ftable = nil
  2870. gofmt()
  2871. }
  2872. if foutput != nil {
  2873. foutput.Flush()
  2874. foutput = nil
  2875. }
  2876. if stderr != nil {
  2877. stderr.Flush()
  2878. stderr = nil
  2879. }
  2880. os.Exit(status)
  2881. }
  2882. func gofmt() {
  2883. src, err := ioutil.ReadFile(oflag)
  2884. if err != nil {
  2885. return
  2886. }
  2887. src, err = format.Source(src)
  2888. if err != nil {
  2889. return
  2890. }
  2891. ioutil.WriteFile(oflag, src, 0666)
  2892. }
  2893. var yaccpar string // will be processed version of yaccpartext: s/$$/prefix/g
  2894. var yaccpartext = `
  2895. /* parser for yacc output */
  2896. var (
  2897. $$Debug = 0
  2898. $$ErrorVerbose = false
  2899. )
  2900. type $$Lexer interface {
  2901. Lex(lval *$$SymType) int
  2902. Error(s string)
  2903. }
  2904. type $$Parser interface {
  2905. Parse($$Lexer) int
  2906. Lookahead() int
  2907. }
  2908. type $$ParserImpl struct {
  2909. lval $$SymType
  2910. stack [$$InitialStackSize]$$SymType
  2911. char int
  2912. }
  2913. func (p *$$ParserImpl) Lookahead() int {
  2914. return p.char
  2915. }
  2916. func $$NewParser() $$Parser {
  2917. return &$$ParserImpl{}
  2918. }
  2919. const $$Flag = -1000
  2920. func $$Tokname(c int) string {
  2921. if c >= 1 && c-1 < len($$Toknames) {
  2922. if $$Toknames[c-1] != "" {
  2923. return $$Toknames[c-1]
  2924. }
  2925. }
  2926. return __yyfmt__.Sprintf("tok-%v", c)
  2927. }
  2928. func $$Statname(s int) string {
  2929. if s >= 0 && s < len($$Statenames) {
  2930. if $$Statenames[s] != "" {
  2931. return $$Statenames[s]
  2932. }
  2933. }
  2934. return __yyfmt__.Sprintf("state-%v", s)
  2935. }
  2936. func $$ErrorMessage(state, lookAhead int) string {
  2937. const TOKSTART = 4
  2938. if !$$ErrorVerbose {
  2939. return "syntax error"
  2940. }
  2941. for _, e := range $$ErrorMessages {
  2942. if e.state == state && e.token == lookAhead {
  2943. return "syntax error: " + e.msg
  2944. }
  2945. }
  2946. res := "syntax error: unexpected " + $$Tokname(lookAhead)
  2947. // To match Bison, suggest at most four expected tokens.
  2948. expected := make([]int, 0, 4)
  2949. // Look for shiftable tokens.
  2950. base := $$Pact[state]
  2951. for tok := TOKSTART; tok-1 < len($$Toknames); tok++ {
  2952. if n := base + tok; n >= 0 && n < $$Last && $$Chk[$$Act[n]] == tok {
  2953. if len(expected) == cap(expected) {
  2954. return res
  2955. }
  2956. expected = append(expected, tok)
  2957. }
  2958. }
  2959. if $$Def[state] == -2 {
  2960. i := 0
  2961. for $$Exca[i] != -1 || $$Exca[i+1] != state {
  2962. i += 2
  2963. }
  2964. // Look for tokens that we accept or reduce.
  2965. for i += 2; $$Exca[i] >= 0; i += 2 {
  2966. tok := $$Exca[i]
  2967. if tok < TOKSTART || $$Exca[i+1] == 0 {
  2968. continue
  2969. }
  2970. if len(expected) == cap(expected) {
  2971. return res
  2972. }
  2973. expected = append(expected, tok)
  2974. }
  2975. // If the default action is to accept or reduce, give up.
  2976. if $$Exca[i+1] != 0 {
  2977. return res
  2978. }
  2979. }
  2980. for i, tok := range expected {
  2981. if i == 0 {
  2982. res += ", expecting "
  2983. } else {
  2984. res += " or "
  2985. }
  2986. res += $$Tokname(tok)
  2987. }
  2988. return res
  2989. }
  2990. func $$lex1(lex $$Lexer, lval *$$SymType) (char, token int) {
  2991. token = 0
  2992. char = lex.Lex(lval)
  2993. if char <= 0 {
  2994. token = $$Tok1[0]
  2995. goto out
  2996. }
  2997. if char < len($$Tok1) {
  2998. token = $$Tok1[char]
  2999. goto out
  3000. }
  3001. if char >= $$Private {
  3002. if char < $$Private+len($$Tok2) {
  3003. token = $$Tok2[char-$$Private]
  3004. goto out
  3005. }
  3006. }
  3007. for i := 0; i < len($$Tok3); i += 2 {
  3008. token = $$Tok3[i+0]
  3009. if token == char {
  3010. token = $$Tok3[i+1]
  3011. goto out
  3012. }
  3013. }
  3014. out:
  3015. if token == 0 {
  3016. token = $$Tok2[1] /* unknown char */
  3017. }
  3018. if $$Debug >= 3 {
  3019. __yyfmt__.Printf("lex %s(%d)\n", $$Tokname(token), uint(char))
  3020. }
  3021. return char, token
  3022. }
  3023. func $$Parse($$lex $$Lexer) int {
  3024. return $$NewParser().Parse($$lex)
  3025. }
  3026. func ($$rcvr *$$ParserImpl) Parse($$lex $$Lexer) int {
  3027. var $$n int
  3028. var $$VAL $$SymType
  3029. var $$Dollar []$$SymType
  3030. _ = $$Dollar // silence set and not used
  3031. $$S := $$rcvr.stack[:]
  3032. Nerrs := 0 /* number of errors */
  3033. Errflag := 0 /* error recovery flag */
  3034. $$state := 0
  3035. $$rcvr.char = -1
  3036. $$token := -1 // $$rcvr.char translated into internal numbering
  3037. defer func() {
  3038. // Make sure we report no lookahead when not parsing.
  3039. $$state = -1
  3040. $$rcvr.char = -1
  3041. $$token = -1
  3042. }()
  3043. $$p := -1
  3044. goto $$stack
  3045. ret0:
  3046. return 0
  3047. ret1:
  3048. return 1
  3049. $$stack:
  3050. /* put a state and value onto the stack */
  3051. if $$Debug >= 4 {
  3052. __yyfmt__.Printf("char %v in %v\n", $$Tokname($$token), $$Statname($$state))
  3053. }
  3054. $$p++
  3055. if $$p >= len($$S) {
  3056. nyys := make([]$$SymType, len($$S)*2)
  3057. copy(nyys, $$S)
  3058. $$S = nyys
  3059. }
  3060. $$S[$$p] = $$VAL
  3061. $$S[$$p].yys = $$state
  3062. $$newstate:
  3063. $$n = $$Pact[$$state]
  3064. if $$n <= $$Flag {
  3065. goto $$default /* simple state */
  3066. }
  3067. if $$rcvr.char < 0 {
  3068. $$rcvr.char, $$token = $$lex1($$lex, &$$rcvr.lval)
  3069. }
  3070. $$n += $$token
  3071. if $$n < 0 || $$n >= $$Last {
  3072. goto $$default
  3073. }
  3074. $$n = $$Act[$$n]
  3075. if $$Chk[$$n] == $$token { /* valid shift */
  3076. $$rcvr.char = -1
  3077. $$token = -1
  3078. $$VAL = $$rcvr.lval
  3079. $$state = $$n
  3080. if Errflag > 0 {
  3081. Errflag--
  3082. }
  3083. goto $$stack
  3084. }
  3085. $$default:
  3086. /* default state action */
  3087. $$n = $$Def[$$state]
  3088. if $$n == -2 {
  3089. if $$rcvr.char < 0 {
  3090. $$rcvr.char, $$token = $$lex1($$lex, &$$rcvr.lval)
  3091. }
  3092. /* look through exception table */
  3093. xi := 0
  3094. for {
  3095. if $$Exca[xi+0] == -1 && $$Exca[xi+1] == $$state {
  3096. break
  3097. }
  3098. xi += 2
  3099. }
  3100. for xi += 2; ; xi += 2 {
  3101. $$n = $$Exca[xi+0]
  3102. if $$n < 0 || $$n == $$token {
  3103. break
  3104. }
  3105. }
  3106. $$n = $$Exca[xi+1]
  3107. if $$n < 0 {
  3108. goto ret0
  3109. }
  3110. }
  3111. if $$n == 0 {
  3112. /* error ... attempt to resume parsing */
  3113. switch Errflag {
  3114. case 0: /* brand new error */
  3115. $$lex.Error($$ErrorMessage($$state, $$token))
  3116. Nerrs++
  3117. if $$Debug >= 1 {
  3118. __yyfmt__.Printf("%s", $$Statname($$state))
  3119. __yyfmt__.Printf(" saw %s\n", $$Tokname($$token))
  3120. }
  3121. fallthrough
  3122. case 1, 2: /* incompletely recovered error ... try again */
  3123. Errflag = 3
  3124. /* find a state where "error" is a legal shift action */
  3125. for $$p >= 0 {
  3126. $$n = $$Pact[$$S[$$p].yys] + $$ErrCode
  3127. if $$n >= 0 && $$n < $$Last {
  3128. $$state = $$Act[$$n] /* simulate a shift of "error" */
  3129. if $$Chk[$$state] == $$ErrCode {
  3130. goto $$stack
  3131. }
  3132. }
  3133. /* the current p has no shift on "error", pop stack */
  3134. if $$Debug >= 2 {
  3135. __yyfmt__.Printf("error recovery pops state %d\n", $$S[$$p].yys)
  3136. }
  3137. $$p--
  3138. }
  3139. /* there is no state on the stack with an error shift ... abort */
  3140. goto ret1
  3141. case 3: /* no shift yet; clobber input char */
  3142. if $$Debug >= 2 {
  3143. __yyfmt__.Printf("error recovery discards %s\n", $$Tokname($$token))
  3144. }
  3145. if $$token == $$EofCode {
  3146. goto ret1
  3147. }
  3148. $$rcvr.char = -1
  3149. $$token = -1
  3150. goto $$newstate /* try again in the same state */
  3151. }
  3152. }
  3153. /* reduction by production $$n */
  3154. if $$Debug >= 2 {
  3155. __yyfmt__.Printf("reduce %v in:\n\t%v\n", $$n, $$Statname($$state))
  3156. }
  3157. $$nt := $$n
  3158. $$pt := $$p
  3159. _ = $$pt // guard against "declared and not used"
  3160. $$p -= $$R2[$$n]
  3161. // $$p is now the index of $0. Perform the default action. Iff the
  3162. // reduced production is ε, $1 is possibly out of range.
  3163. if $$p+1 >= len($$S) {
  3164. nyys := make([]$$SymType, len($$S)*2)
  3165. copy(nyys, $$S)
  3166. $$S = nyys
  3167. }
  3168. $$VAL = $$S[$$p+1]
  3169. /* consult goto table to find next state */
  3170. $$n = $$R1[$$n]
  3171. $$g := $$Pgo[$$n]
  3172. $$j := $$g + $$S[$$p].yys + 1
  3173. if $$j >= $$Last {
  3174. $$state = $$Act[$$g]
  3175. } else {
  3176. $$state = $$Act[$$j]
  3177. if $$Chk[$$state] != -$$n {
  3178. $$state = $$Act[$$g]
  3179. }
  3180. }
  3181. // dummy call; replaced with literal code
  3182. $$run()
  3183. goto $$stack /* stack new state and value */
  3184. }
  3185. `