Commit bb0e7bda authored by Rob Pike's avatar Rob Pike

goyacc: provide -p flag to set prefix for names.

This should allow multiple goyacc grammars to be
compiled into the same binary. There's a chance it
Fixes #1562.

R=rsc, r2
CC=golang-dev
https://golang.org/cl/4256044
parent 432b4f30
...@@ -11,7 +11,7 @@ GOFILES=\ ...@@ -11,7 +11,7 @@ GOFILES=\
include ../../Make.cmd include ../../Make.cmd
units: goyacc units.y units: goyacc units.y
./goyacc units.y ./goyacc -p units_ units.y
$(GC) y.go $(GC) y.go
$(LD) -o units y.$O $(LD) -o units y.$O
...@@ -17,7 +17,8 @@ Yacc adepts will have no trouble adapting to this form of the tool. ...@@ -17,7 +17,8 @@ Yacc adepts will have no trouble adapting to this form of the tool.
The file units.y in this directory is a yacc grammar for a version of The file units.y in this directory is a yacc grammar for a version of
the Unix tool units, also written in Go and largely transliterated the Unix tool units, also written in Go and largely transliterated
from the Plan 9 C version. from the Plan 9 C version. It needs the flag "-p units_" (see
below).
The generated parser is reentrant. Parse expects to be given an The generated parser is reentrant. Parse expects to be given an
argument that conforms to the following interface: argument that conforms to the following interface:
...@@ -31,8 +32,14 @@ Lex should return the token identifier, and place other token ...@@ -31,8 +32,14 @@ Lex should return the token identifier, and place other token
information in lval (which replaces the usual yylval). information in lval (which replaces the usual yylval).
Error is equivalent to yyerror in the original yacc. Error is equivalent to yyerror in the original yacc.
Code inside the parser may refer to the variable yylex Code inside the parser may refer to the variable yylex,
which holds the yyLexer passed to Parse. which holds the yyLexer passed to Parse.
The "-p prefix" flag to goyacc sets the prefix, by default yy, that
begins the names of symbols, including types, the parser, and the
lexer, generated and referenced by goyacc's generated code. Setting
it to distinct values allows multiple grammars to be used in a
single binary.
*/ */
package documentation package documentation
...@@ -153,9 +153,17 @@ var ftable *bufio.Writer // y.go file ...@@ -153,9 +153,17 @@ var ftable *bufio.Writer // y.go file
var fcode = &bytes.Buffer{} // saved code var fcode = &bytes.Buffer{} // saved code
var foutput *bufio.Writer // y.output file var foutput *bufio.Writer // y.output file
var oflag string // -o [y.go] - y.go file var oflag string // -o [y.go] - y.go file
var vflag string // -v [y.output] - y.output file var vflag string // -v [y.output] - y.output file
var lflag bool // -l - disable line directives var lflag bool // -l - disable line directives
var prefix string // name prefix for identifiers, default yy
func init() {
flag.StringVar(&oflag, "o", "y.go", "parser output")
flag.StringVar(&prefix, "p", "yy", "name prefix to use in generated code")
flag.StringVar(&vflag, "v", "y.output", "create parsing tables")
flag.BoolVar(&lflag, "l", false, "disable line directives")
}
var stacksize = 200 var stacksize = 200
...@@ -349,10 +357,6 @@ func setup() { ...@@ -349,10 +357,6 @@ func setup() {
stderr = bufio.NewWriter(os.NewFile(2, "stderr")) stderr = bufio.NewWriter(os.NewFile(2, "stderr"))
foutput = nil foutput = nil
flag.StringVar(&oflag, "o", "", "parser output")
flag.StringVar(&vflag, "v", "", "create parsing tables")
flag.BoolVar(&lflag, "l", false, "disable line directives")
flag.Parse() flag.Parse()
if flag.NArg() != 1 { if flag.NArg() != 1 {
usage() usage()
...@@ -362,6 +366,7 @@ func setup() { ...@@ -362,6 +366,7 @@ func setup() {
fmt.Fprintf(stderr, "yacc: stack size too small\n") fmt.Fprintf(stderr, "yacc: stack size too small\n")
usage() usage()
} }
yaccpar = strings.Replace(yaccpartext, "$$", prefix, -1)
openup() openup()
defin(0, "$end") defin(0, "$end")
...@@ -506,20 +511,20 @@ outer: ...@@ -506,20 +511,20 @@ outer:
} }
// put out names of token names // put out names of token names
fmt.Fprintf(ftable, "var\tyyToknames\t =[]string {\n") fmt.Fprintf(ftable, "var\t%sToknames\t =[]string {\n", prefix)
for i := TOKSTART; i <= ntokens; i++ { for i := TOKSTART; i <= ntokens; i++ {
fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name) fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name)
} }
fmt.Fprintf(ftable, "}\n") fmt.Fprintf(ftable, "}\n")
// put out names of state names // put out names of state names
fmt.Fprintf(ftable, "var\tyyStatenames\t =[]string {\n") fmt.Fprintf(ftable, "var\t%sStatenames\t =[]string {\n", prefix)
// for i:=TOKSTART; i<=ntokens; i++ { // for i:=TOKSTART; i<=ntokens; i++ {
// fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name); // fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name);
// } // }
fmt.Fprintf(ftable, "}\n") fmt.Fprintf(ftable, "}\n")
fmt.Fprintf(fcode, "switch yynt {\n") fmt.Fprintf(fcode, "switch %snt {\n", prefix)
moreprod() moreprod()
prdptr[0] = []int{NTBASE, start, 1, 0} prdptr[0] = []int{NTBASE, start, 1, 0}
...@@ -648,8 +653,8 @@ outer: ...@@ -648,8 +653,8 @@ outer:
error("default action causes potential type clash") error("default action causes potential type clash")
} }
fmt.Fprintf(fcode, "\ncase %v:", nprod) fmt.Fprintf(fcode, "\ncase %v:", nprod)
fmt.Fprintf(fcode, "\n\tYYVAL.%v = YYS[yypt-0].%v;", fmt.Fprintf(fcode, "\n\t%sVAL.%v = %sS[%spt-0].%v;",
typeset[tempty], typeset[tempty]) prefix, typeset[tempty], prefix, prefix, typeset[tempty])
} }
moreprod() moreprod()
prdptr[nprod] = make([]int, mem) prdptr[nprod] = make([]int, mem)
...@@ -666,9 +671,9 @@ outer: ...@@ -666,9 +671,9 @@ outer:
fmt.Fprintf(fcode, "\n\t}") fmt.Fprintf(fcode, "\n\t}")
fmt.Fprintf(ftable, "const yyEofCode = 1\n") fmt.Fprintf(ftable, "const %sEofCode = 1\n", prefix)
fmt.Fprintf(ftable, "const yyErrCode = 2\n") fmt.Fprintf(ftable, "const %sErrCode = 2\n", prefix)
fmt.Fprintf(ftable, "const yyMaxDepth = %v\n", stacksize) fmt.Fprintf(ftable, "const %sMaxDepth = %v\n", prefix, stacksize)
// //
// copy any postfix code // copy any postfix code
...@@ -1034,7 +1039,7 @@ func cpyunion() { ...@@ -1034,7 +1039,7 @@ func cpyunion() {
if !lflag { if !lflag {
fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno) fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno)
} }
fmt.Fprintf(ftable, "type\tyySymType\tstruct") fmt.Fprintf(ftable, "type\t%sSymType\tstruct", prefix)
level := 0 level := 0
...@@ -1197,7 +1202,7 @@ loop: ...@@ -1197,7 +1202,7 @@ loop:
c = getrune(finput) c = getrune(finput)
} }
if c == '$' { if c == '$' {
fmt.Fprintf(fcode, "YYVAL") fmt.Fprintf(fcode, "%sVAL", prefix)
// put out the proper tag... // put out the proper tag...
if ntypes != 0 { if ntypes != 0 {
...@@ -1258,7 +1263,7 @@ loop: ...@@ -1258,7 +1263,7 @@ loop:
ungetrune(finput, c) ungetrune(finput, c)
continue loop continue loop
} }
fmt.Fprintf(fcode, "YYS[yypt-%v]", max-j-1) fmt.Fprintf(fcode, "%sS[%spt-%v]", prefix, prefix, max-j-1)
// put out the proper tag // put out the proper tag
if ntypes != 0 { if ntypes != 0 {
...@@ -2067,7 +2072,7 @@ func output() { ...@@ -2067,7 +2072,7 @@ func output() {
var c, u, v int var c, u, v int
fmt.Fprintf(ftable, "\n//line yacctab:1\n") fmt.Fprintf(ftable, "\n//line yacctab:1\n")
fmt.Fprintf(ftable, "var\tyyExca = []int {\n") fmt.Fprintf(ftable, "var\t%sExca = []int {\n", prefix)
noset := mkset() noset := mkset()
...@@ -2140,10 +2145,10 @@ func output() { ...@@ -2140,10 +2145,10 @@ func output() {
} }
fmt.Fprintf(ftable, "}\n") fmt.Fprintf(ftable, "}\n")
fmt.Fprintf(ftable, "const\tyyNprod\t= %v\n", nprod) fmt.Fprintf(ftable, "const\t%sNprod\t= %v\n", prefix, nprod)
fmt.Fprintf(ftable, "const\tyyPrivate\t= %v\n", PRIVATE) fmt.Fprintf(ftable, "const\t%sPrivate\t= %v\n", prefix, PRIVATE)
fmt.Fprintf(ftable, "var\tyyTokenNames []string\n") fmt.Fprintf(ftable, "var\t%sTokenNames []string\n", prefix)
fmt.Fprintf(ftable, "var\tyyStates []string\n") fmt.Fprintf(ftable, "var\t%sStates []string\n", prefix)
} }
// //
...@@ -2718,10 +2723,10 @@ nextn: ...@@ -2718,10 +2723,10 @@ nextn:
// write out the optimized parser // write out the optimized parser
// //
func aoutput() { func aoutput() {
fmt.Fprintf(ftable, "const\tyyLast\t= %v\n", maxa+1) fmt.Fprintf(ftable, "const\t%sLast\t= %v\n", prefix, maxa+1)
arout("yyAct", amem, maxa+1) arout("Act", amem, maxa+1)
arout("yyPact", indgo, nstate) arout("Pact", indgo, nstate)
arout("yyPgo", pgo, nnonter+1) arout("Pgo", pgo, nnonter+1)
} }
// //
...@@ -2730,7 +2735,7 @@ func aoutput() { ...@@ -2730,7 +2735,7 @@ func aoutput() {
func others() { func others() {
var i, j int var i, j int
arout("yyR1", levprd, nprod) arout("R1", levprd, nprod)
aryfil(temp1, nprod, 0) aryfil(temp1, nprod, 0)
// //
...@@ -2739,7 +2744,7 @@ func others() { ...@@ -2739,7 +2744,7 @@ func others() {
for i = 1; i < nprod; i++ { for i = 1; i < nprod; i++ {
temp1[i] = len(prdptr[i]) - 2 temp1[i] = len(prdptr[i]) - 2
} }
arout("yyR2", temp1, nprod) arout("R2", temp1, nprod)
aryfil(temp1, nstate, -1000) aryfil(temp1, nstate, -1000)
for i = 0; i <= ntokens; i++ { for i = 0; i <= ntokens; i++ {
...@@ -2752,8 +2757,8 @@ func others() { ...@@ -2752,8 +2757,8 @@ func others() {
temp1[j] = -i temp1[j] = -i
} }
} }
arout("yyChk", temp1, nstate) arout("Chk", temp1, nstate)
arout("yyDef", defact, nstate) arout("Def", defact, nstate)
// put out token translation tables // put out token translation tables
// table 1 has 0-256 // table 1 has 0-256
...@@ -2778,7 +2783,7 @@ func others() { ...@@ -2778,7 +2783,7 @@ func others() {
temp1[i] = YYLEXUNK temp1[i] = YYLEXUNK
} }
} }
arout("yyTok1", temp1, c+1) arout("Tok1", temp1, c+1)
// table 2 has PRIVATE-PRIVATE+256 // table 2 has PRIVATE-PRIVATE+256
aryfil(temp1, 256, 0) aryfil(temp1, 256, 0)
...@@ -2797,10 +2802,10 @@ func others() { ...@@ -2797,10 +2802,10 @@ func others() {
} }
} }
} }
arout("yyTok2", temp1, c+1) arout("Tok2", temp1, c+1)
// table 3 has everything else // table 3 has everything else
fmt.Fprintf(ftable, "var\tyyTok3\t= []int {\n") fmt.Fprintf(ftable, "var\t%sTok3\t= []int {\n", prefix)
c = 0 c = 0
for i = 1; i <= ntokens; i++ { for i = 1; i <= ntokens; i++ {
j = tokset[i].value j = tokset[i].value
...@@ -2829,13 +2834,14 @@ func others() { ...@@ -2829,13 +2834,14 @@ func others() {
// copy yaccpar // copy yaccpar
fmt.Fprintf(ftable, "\n//line yaccpar:1\n") fmt.Fprintf(ftable, "\n//line yaccpar:1\n")
parts := strings.Split(yaccpar, "yyrun()", 2) parts := strings.Split(yaccpar, prefix+"run()", 2)
fmt.Fprintf(ftable, "%v", parts[0]) fmt.Fprintf(ftable, "%v", parts[0])
ftable.Write(fcode.Bytes()) ftable.Write(fcode.Bytes())
fmt.Fprintf(ftable, "%v", parts[1]) fmt.Fprintf(ftable, "%v", parts[1])
} }
func arout(s string, v []int, n int) { func arout(s string, v []int, n int) {
s = prefix + s
fmt.Fprintf(ftable, "var\t%v\t= []int {\n", s) fmt.Fprintf(ftable, "var\t%v\t= []int {\n", s)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
if i%10 == 0 { if i%10 == 0 {
...@@ -3076,86 +3082,84 @@ func exit(status int) { ...@@ -3076,86 +3082,84 @@ func exit(status int) {
os.Exit(status) os.Exit(status)
} }
var yaccpar = ` var yaccpar string // will be processed version of yaccpartext: s/$$/prefix/g
var yaccpartext = `
/* parser for yacc output */ /* parser for yacc output */
var yyDebug = 0 var $$Debug = 0
type yyLexer interface { type $$Lexer interface {
Lex(lval *yySymType) int Lex(lval *$$SymType) int
Error(s string) Error(s string)
} }
const yyFlag = -1000 const $$Flag = -1000
func yyTokname(yyc int) string { func $$Tokname(c int) string {
if yyc > 0 && yyc <= len(yyToknames) { if c > 0 && c <= len($$Toknames) {
if yyToknames[yyc-1] != "" { if $$Toknames[c-1] != "" {
return yyToknames[yyc-1] return $$Toknames[c-1]
} }
} }
return fmt.Sprintf("tok-%v", yyc) return fmt.Sprintf("tok-%v", c)
} }
func yyStatname(yys int) string { func $$Statname(s int) string {
if yys >= 0 && yys < len(yyStatenames) { if s >= 0 && s < len($$Statenames) {
if yyStatenames[yys] != "" { if $$Statenames[s] != "" {
return yyStatenames[yys] return $$Statenames[s]
} }
} }
return fmt.Sprintf("state-%v", yys) return fmt.Sprintf("state-%v", s)
} }
func yylex1(yylex yyLexer, lval *yySymType) int { func $$lex1(lex $$Lexer, lval *$$SymType) int {
var yychar int c := 0
var c int char := lex.Lex(lval)
if char <= 0 {
yychar = yylex.Lex(lval) c = $$Tok1[0]
if yychar <= 0 {
c = yyTok1[0]
goto out goto out
} }
if yychar < len(yyTok1) { if char < len($$Tok1) {
c = yyTok1[yychar] c = $$Tok1[char]
goto out goto out
} }
if yychar >= yyPrivate { if char >= $$Private {
if yychar < yyPrivate+len(yyTok2) { if char < $$Private+len($$Tok2) {
c = yyTok2[yychar-yyPrivate] c = $$Tok2[char-$$Private]
goto out goto out
} }
} }
for i := 0; i < len(yyTok3); i += 2 { for i := 0; i < len($$Tok3); i += 2 {
c = yyTok3[i+0] c = $$Tok3[i+0]
if c == yychar { if c == char {
c = yyTok3[i+1] c = $$Tok3[i+1]
goto out goto out
} }
} }
c = 0
out: out:
if c == 0 { if c == 0 {
c = yyTok2[1] /* unknown char */ c = $$Tok2[1] /* unknown char */
} }
if yyDebug >= 3 { if $$Debug >= 3 {
fmt.Printf("lex %U %s\n", uint(yychar), yyTokname(c)) fmt.Printf("lex %U %s\n", uint(char), $$Tokname(c))
} }
return c return c
} }
func yyParse(yylex yyLexer) int { func $$Parse($$lex $$Lexer) int {
var yyn int var $$n int
var yylval yySymType var $$lval $$SymType
var YYVAL yySymType var $$VAL $$SymType
YYS := make([]yySymType, yyMaxDepth) $$S := make([]$$SymType, $$MaxDepth)
Nerrs := 0 /* number of errors */ Nerrs := 0 /* number of errors */
Errflag := 0 /* error recovery flag */ Errflag := 0 /* error recovery flag */
yystate := 0 $$state := 0
yychar := -1 $$char := -1
yyp := -1 $$p := -1
goto yystack goto $$stack
ret0: ret0:
return 0 return 0
...@@ -3163,80 +3167,80 @@ ret0: ...@@ -3163,80 +3167,80 @@ ret0:
ret1: ret1:
return 1 return 1
yystack: $$stack:
/* put a state and value onto the stack */ /* put a state and value onto the stack */
if yyDebug >= 4 { if $$Debug >= 4 {
fmt.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate)) fmt.Printf("char %v in %v\n", $$Tokname($$char), $$Statname($$state))
} }
yyp++ $$p++
if yyp >= len(YYS) { if $$p >= len($$S) {
nyys := make([]yySymType, len(YYS)*2) nyys := make([]$$SymType, len($$S)*2)
copy(nyys, YYS) copy(nyys, $$S)
YYS = nyys $$S = nyys
} }
YYS[yyp] = YYVAL $$S[$$p] = $$VAL
YYS[yyp].yys = yystate $$S[$$p].yys = $$state
yynewstate: $$newstate:
yyn = yyPact[yystate] $$n = $$Pact[$$state]
if yyn <= yyFlag { if $$n <= $$Flag {
goto yydefault /* simple state */ goto $$default /* simple state */
} }
if yychar < 0 { if $$char < 0 {
yychar = yylex1(yylex, &yylval) $$char = $$lex1($$lex, &$$lval)
} }
yyn += yychar $$n += $$char
if yyn < 0 || yyn >= yyLast { if $$n < 0 || $$n >= $$Last {
goto yydefault goto $$default
} }
yyn = yyAct[yyn] $$n = $$Act[$$n]
if yyChk[yyn] == yychar { /* valid shift */ if $$Chk[$$n] == $$char { /* valid shift */
yychar = -1 $$char = -1
YYVAL = yylval $$VAL = $$lval
yystate = yyn $$state = $$n
if Errflag > 0 { if Errflag > 0 {
Errflag-- Errflag--
} }
goto yystack goto $$stack
} }
yydefault: $$default:
/* default state action */ /* default state action */
yyn = yyDef[yystate] $$n = $$Def[$$state]
if yyn == -2 { if $$n == -2 {
if yychar < 0 { if $$char < 0 {
yychar = yylex1(yylex, &yylval) $$char = $$lex1($$lex, &$$lval)
} }
/* look through exception table */ /* look through exception table */
yyxi := 0 xi := 0
for { for {
if yyExca[yyxi+0] == -1 && yyExca[yyxi+1] == yystate { if $$Exca[xi+0] == -1 && $$Exca[xi+1] == $$state {
break break
} }
yyxi += 2 xi += 2
} }
for yyxi += 2; ; yyxi += 2 { for xi += 2; ; xi += 2 {
yyn = yyExca[yyxi+0] $$n = $$Exca[xi+0]
if yyn < 0 || yyn == yychar { if $$n < 0 || $$n == $$char {
break break
} }
} }
yyn = yyExca[yyxi+1] $$n = $$Exca[xi+1]
if yyn < 0 { if $$n < 0 {
goto ret0 goto ret0
} }
} }
if yyn == 0 { if $$n == 0 {
/* error ... attempt to resume parsing */ /* error ... attempt to resume parsing */
switch Errflag { switch Errflag {
case 0: /* brand new error */ case 0: /* brand new error */
yylex.Error("syntax error") $$lex.Error("syntax error")
Nerrs++ Nerrs++
if yyDebug >= 1 { if $$Debug >= 1 {
fmt.Printf("%s", yyStatname(yystate)) fmt.Printf("%s", $$Statname($$state))
fmt.Printf("saw %s\n", yyTokname(yychar)) fmt.Printf("saw %s\n", $$Tokname($$char))
} }
fallthrough fallthrough
...@@ -3244,64 +3248,64 @@ yydefault: ...@@ -3244,64 +3248,64 @@ yydefault:
Errflag = 3 Errflag = 3
/* find a state where "error" is a legal shift action */ /* find a state where "error" is a legal shift action */
for yyp >= 0 { for $$p >= 0 {
yyn = yyPact[YYS[yyp].yys] + yyErrCode $$n = $$Pact[$$S[$$p].yys] + $$ErrCode
if yyn >= 0 && yyn < yyLast { if $$n >= 0 && $$n < $$Last {
yystate = yyAct[yyn] /* simulate a shift of "error" */ $$state = $$Act[$$n] /* simulate a shift of "error" */
if yyChk[yystate] == yyErrCode { if $$Chk[$$state] == $$ErrCode {
goto yystack goto $$stack
} }
} }
/* the current yyp has no shift onn "error", pop stack */ /* the current p has no shift onn "error", pop stack */
if yyDebug >= 2 { if $$Debug >= 2 {
fmt.Printf("error recovery pops state %d, uncovers %d\n", fmt.Printf("error recovery pops state %d, uncovers %d\n",
YYS[yyp].yys, YYS[yyp-1].yys) $$S[$$p].yys, $$S[$$p-1].yys)
} }
yyp-- $$p--
} }
/* there is no state on the stack with an error shift ... abort */ /* there is no state on the stack with an error shift ... abort */
goto ret1 goto ret1
case 3: /* no shift yet; clobber input char */ case 3: /* no shift yet; clobber input char */
if yyDebug >= 2 { if $$Debug >= 2 {
fmt.Printf("error recovery discards %s\n", yyTokname(yychar)) fmt.Printf("error recovery discards %s\n", $$Tokname($$char))
} }
if yychar == yyEofCode { if $$char == $$EofCode {
goto ret1 goto ret1
} }
yychar = -1 $$char = -1
goto yynewstate /* try again in the same state */ goto $$newstate /* try again in the same state */
} }
} }
/* reduction by production yyn */ /* reduction by production $$n */
if yyDebug >= 2 { if $$Debug >= 2 {
fmt.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) fmt.Printf("reduce %v in:\n\t%v\n", $$n, $$Statname($$state))
} }
yynt := yyn $$nt := $$n
yypt := yyp $$pt := $$p
_ = yypt // guard against "declared and not used" _ = $$pt // guard against "declared and not used"
yyp -= yyR2[yyn] $$p -= $$R2[$$n]
YYVAL = YYS[yyp+1] $$VAL = $$S[$$p+1]
/* consult goto table to find next state */ /* consult goto table to find next state */
yyn = yyR1[yyn] $$n = $$R1[$$n]
yyg := yyPgo[yyn] $$g := $$Pgo[$$n]
yyj := yyg + YYS[yyp].yys + 1 $$j := $$g + $$S[$$p].yys + 1
if yyj >= yyLast { if $$j >= $$Last {
yystate = yyAct[yyg] $$state = $$Act[$$g]
} else { } else {
yystate = yyAct[yyj] $$state = $$Act[$$j]
if yyChk[yystate] != -yyn { if $$Chk[$$state] != -$$n {
yystate = yyAct[yyg] $$state = $$Act[$$g]
} }
} }
// dummy call; replaced with literal code // dummy call; replaced with literal code
yyrun() $$run()
goto yystack /* stack new state and value */ goto $$stack /* stack new state and value */
} }
` `
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
// Distributed under the terms of the Lucent Public License Version 1.02 // Distributed under the terms of the Lucent Public License Version 1.02
// See http://plan9.bell-labs.com/plan9/license.html // See http://plan9.bell-labs.com/plan9/license.html
// Generate parser with prefix "units_":
// goyacc -p "units_"
%{ %{
// units.y // units.y
...@@ -215,7 +218,7 @@ expr0: ...@@ -215,7 +218,7 @@ expr0:
type UnitsLex int type UnitsLex int
func (UnitsLex) Lex(yylval *yySymType) int { func (UnitsLex) Lex(yylval *units_SymType) int {
var c, i int var c, i int
c = peekrune c = peekrune
...@@ -319,7 +322,7 @@ func main() { ...@@ -319,7 +322,7 @@ func main() {
continue continue
} }
peekrune = ':' peekrune = ':'
yyParse(UnitsLex(0)) units_Parse(UnitsLex(0))
} }
/* /*
...@@ -340,7 +343,7 @@ func main() { ...@@ -340,7 +343,7 @@ func main() {
} }
peekrune = '?' peekrune = '?'
nerrors = 0 nerrors = 0
yyParse(UnitsLex(0)) units_Parse(UnitsLex(0))
if nerrors != 0 { if nerrors != 0 {
continue continue
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment