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