Change goyacc to be reentrant.
Instead of calling the package scope Lex function,
Parse now takes an argument which is used to
do the lexing.
I reverted to having the generated switch
code inside Parse rather than a separate function because
the function needs 7 arguments or a context structure,
which seems unnecessary.
I used yyrun(), not the original $A so that
it's possible to run the backquoted code through gofmt.

R=rsc, ken2, ken3
CC=golang-dev
https://golang.org/cl/879041
diff --git a/src/cmd/goyacc/doc.go b/src/cmd/goyacc/doc.go
index a3cf075..eea70ad 100644
--- a/src/cmd/goyacc/doc.go
+++ b/src/cmd/goyacc/doc.go
@@ -19,5 +19,18 @@
 the Unix tool units, also written in Go and largely transliterated
 from the Plan 9 C version.
 
+The generated parser is reentrant. Parse expects to be given an
+argument that conforms to the following interface:
+
+	type yyLexer interface {
+		Lex(lval *yySymType) int
+	}
+
+Lex should return the token identifier, and place other token
+information in lval (which replaces the usual yylval).
+
+Code inside the parser may refer to the variable yylex
+which holds the yyLexer passed to Parse.
+
 */
 package documentation
diff --git a/src/cmd/goyacc/goyacc.go b/src/cmd/goyacc/goyacc.go
index 31ab32c..118d277 100644
--- a/src/cmd/goyacc/goyacc.go
+++ b/src/cmd/goyacc/goyacc.go
@@ -49,6 +49,8 @@
 	"fmt"
 	"bufio"
 	"os"
+	"strings"
+	"bytes"
 )
 
 // the following are adjustable
@@ -104,7 +106,7 @@
 )
 
 // output parser flags
-const YYFLAG = -1000
+const yyFlag = -1000
 
 // parse tokens
 const (
@@ -147,8 +149,9 @@
 // I/O descriptors
 var finput *bufio.Reader // input file
 var stderr *bufio.Writer
-var ftable *bufio.Writer  // y.go file
-var foutput *bufio.Writer // y.output file
+var ftable *bufio.Writer    // y.go file
+var fcode = &bytes.Buffer{} // saved code
+var foutput *bufio.Writer   // y.output file
 
 var oflag string // -o [y.go]		- y.go file
 var vflag string // -v [y.output]	- y.output file
@@ -503,22 +506,20 @@
 	}
 
 	// put out names of token names
-	fmt.Fprintf(ftable, "var\tToknames\t =[]string {\n")
+	fmt.Fprintf(ftable, "var\tyyToknames\t =[]string {\n")
 	for i := TOKSTART; i <= ntokens; i++ {
 		fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name)
 	}
 	fmt.Fprintf(ftable, "}\n")
 
 	// put out names of state names
-	fmt.Fprintf(ftable, "var\tStatenames\t =[]string {\n")
+	fmt.Fprintf(ftable, "var\tyyStatenames\t =[]string {\n")
 	//	for i:=TOKSTART; i<=ntokens; i++ {
 	//		fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name);
 	//	}
 	fmt.Fprintf(ftable, "}\n")
 
-	fmt.Fprintf(ftable, "\nfunc\n")
-	fmt.Fprintf(ftable, "yyrun(p int, yypt int) {\n")
-	fmt.Fprintf(ftable, "switch p {\n")
+	fmt.Fprintf(fcode, "switch yynt {\n")
 
 	moreprod()
 	prdptr[0] = []int{NTBASE, start, 1, 0}
@@ -589,7 +590,7 @@
 				break
 			}
 			levprd[nprod] |= ACTFLAG
-			fmt.Fprintf(ftable, "\ncase %v:", nprod)
+			fmt.Fprintf(fcode, "\ncase %v:", nprod)
 			cpyact(curprod, mem)
 
 			// action within rule...
@@ -646,8 +647,8 @@
 			if tempty != nontrst[curprod[0]-NTBASE].value {
 				error("default action causes potential type clash")
 			}
-			fmt.Fprintf(ftable, "\ncase %v:", nprod)
-			fmt.Fprintf(ftable, "\n\tYYVAL.%v = YYS[yypt-0].%v;",
+			fmt.Fprintf(fcode, "\ncase %v:", nprod)
+			fmt.Fprintf(fcode, "\n\tYYVAL.%v = YYS[yypt-0].%v;",
 				typeset[tempty], typeset[tempty])
 		}
 		moreprod()
@@ -663,12 +664,11 @@
 	// dump out the prefix code
 	//
 
-	fmt.Fprintf(ftable, "\n\t}")
-	fmt.Fprintf(ftable, "\n}\n")
+	fmt.Fprintf(fcode, "\n\t}")
 
-	fmt.Fprintf(ftable, "const	YYEOFCODE	= 1\n")
-	fmt.Fprintf(ftable, "const	YYERRCODE	= 2\n")
-	fmt.Fprintf(ftable, "const	YYMAXDEPTH	= %v\n", stacksize)
+	fmt.Fprintf(ftable, "const	yyEofCode	= 1\n")
+	fmt.Fprintf(ftable, "const	yyErrCode	= 2\n")
+	fmt.Fprintf(ftable, "const	yyMaxDepth	= %v\n", stacksize)
 
 	//
 	// copy any postfix code
@@ -682,7 +682,7 @@
 			if c == EOF {
 				break
 			}
-			putrune(ftable, c)
+			ftable.WriteRune(c)
 		}
 	}
 }
@@ -1034,7 +1034,7 @@
 	if !lflag {
 		fmt.Fprintf(ftable, "\n//line %v %v\n", lineno, infile)
 	}
-	fmt.Fprintf(ftable, "type\tYYSTYPE\tstruct")
+	fmt.Fprintf(ftable, "type\tyySymType\tstruct")
 
 	level := 0
 
@@ -1044,7 +1044,7 @@
 		if c == EOF {
 			error("EOF encountered while processing %%union")
 		}
-		putrune(ftable, c)
+		ftable.WriteRune(c)
 		switch c {
 		case '\n':
 			lineno++
@@ -1061,9 +1061,6 @@
 		}
 	}
 	fmt.Fprintf(ftable, "\n")
-	fmt.Fprintf(ftable, "var\tyylval\tYYSTYPE\n")
-	fmt.Fprintf(ftable, "var\tYYVAL\tYYSTYPE\n")
-	fmt.Fprintf(ftable, "var\tYYS\t[%v]YYSTYPE\n", stacksize)
 }
 
 //
@@ -1086,9 +1083,9 @@
 			if c == '}' {
 				return
 			}
-			putrune(ftable, '%')
+			ftable.WriteRune('%')
 		}
-		putrune(ftable, c)
+		ftable.WriteRune(c)
 		if c == '\n' {
 			lineno++
 		}
@@ -1098,74 +1095,6 @@
 	error("eof before %%}")
 }
 
-//func
-//addcode(k int, s string)
-//{
-//	for i := 0; i < len(s); i++ {
-//		addcodec(k, int(s[i]));
-//	}
-//}
-
-//func
-//addcodec(k, c int)
-//{
-//	if codehead == nil || k != codetail.kind || codetail.ndata >= NCode {
-//		cd := new(Code);
-//		cd.kind = k;
-//		cd.data = make([]byte, NCode+UTFmax);
-//		cd.ndata = 0;
-//		cd.next = nil;
-//
-//		if codehead == nil {
-//			codehead = cd;
-//		} else
-//			codetail.next = cd;
-//		codetail = cd;
-//	}
-//
-////!!	codetail.ndata += sys->char2byte(c, codetail.data, codetail.ndata);
-//}
-
-//func
-//dumpcode(til int)
-//{
-//	for ; codehead != nil; codehead = codehead.next {
-//		if codehead.kind == til {
-//			return;
-//		}
-//		if write(ftable, codehead.data, codehead.ndata) != codehead.ndata {
-//			error("can't write output file");
-//		}
-//	}
-//}
-
-//
-// write out the module declaration and any token info
-//
-//func
-//dumpmod()
-//{
-//
-//	for ; codehead != nil; codehead = codehead.next {
-//		if codehead.kind != CodeMod {
-//			break;
-//		}
-//		if write(ftable, codehead.data, codehead.ndata) != codehead.ndata {
-//			error("can't write output file");
-//		}
-//	}
-//
-//	for i:=TOKSTART; i<=ntokens; i++ {
-//		// non-literals
-//		c := tokset[i].name[0];
-//		if c != ' ' && c != '$' {
-//			fmt.Fprintf(ftable, "vonst	%v	%v\n",
-//				tokset[i].name, tokset[i].value);
-//		}
-//	}
-//
-//}
-
 //
 // skip over comments
 // skipcom is called after reading a '/'
@@ -1229,7 +1158,7 @@
 func cpyact(curprod []int, max int) {
 
 	if !lflag {
-		fmt.Fprintf(ftable, "\n//line %v %v\n", lineno, infile)
+		fmt.Fprintf(fcode, "\n//line %v %v\n", lineno, infile)
 	}
 
 	lno := lineno
@@ -1243,14 +1172,14 @@
 		switch c {
 		case ';':
 			if brac == 0 {
-				putrune(ftable, c)
+				ftable.WriteRune(c)
 				return
 			}
 
 		case '{':
 			if brac == 0 {
 			}
-			putrune(ftable, '\t')
+			ftable.WriteRune('\t')
 			brac++
 
 		case '$':
@@ -1268,14 +1197,14 @@
 				c = getrune(finput)
 			}
 			if c == '$' {
-				fmt.Fprintf(ftable, "YYVAL")
+				fmt.Fprintf(fcode, "YYVAL")
 
 				// put out the proper tag...
 				if ntypes != 0 {
 					if tok < 0 {
 						tok = fdtype(curprod[0])
 					}
-					fmt.Fprintf(ftable, ".%v", typeset[tok])
+					fmt.Fprintf(fcode, ".%v", typeset[tok])
 				}
 				continue loop
 			}
@@ -1322,14 +1251,14 @@
 					error("$name or $name@number not found")
 				}
 			} else {
-				putrune(ftable, '$')
+				fcode.WriteRune('$')
 				if s < 0 {
-					putrune(ftable, '-')
+					fcode.WriteRune('-')
 				}
 				ungetrune(finput, c)
 				continue loop
 			}
-			fmt.Fprintf(ftable, "YYS[yypt-%v]", max-j-1)
+			fmt.Fprintf(fcode, "YYS[yypt-%v]", max-j-1)
 
 			// put out the proper tag
 			if ntypes != 0 {
@@ -1339,7 +1268,7 @@
 				if tok < 0 {
 					tok = fdtype(curprod[j])
 				}
-				fmt.Fprintf(ftable, ".%v", typeset[tok])
+				fmt.Fprintf(fcode, ".%v", typeset[tok])
 			}
 			continue loop
 
@@ -1348,7 +1277,7 @@
 			if brac != 0 {
 				break
 			}
-			putrune(ftable, c)
+			fcode.WriteRune(c)
 			return
 
 		case '/':
@@ -1358,8 +1287,8 @@
 				break
 			}
 			// a comment
-			putrune(ftable, c)
-			putrune(ftable, nc)
+			fcode.WriteRune(c)
+			fcode.WriteRune(nc)
 			c = getrune(finput)
 			for c != EOF {
 				switch {
@@ -1371,14 +1300,14 @@
 				case c == '*' && nc == '*': // end of /* comment?
 					nnc := getrune(finput)
 					if nnc == '/' {
-						putrune(ftable, '*')
-						putrune(ftable, '/')
+						fcode.WriteRune('*')
+						fcode.WriteRune('/')
 						c = getrune(finput)
 						break swt
 					}
 					ungetrune(finput, nnc)
 				}
-				putrune(ftable, c)
+				fcode.WriteRune(c)
 				c = getrune(finput)
 			}
 			error("EOF inside comment")
@@ -1386,11 +1315,11 @@
 		case '\'', '"':
 			// character string or constant
 			match := c
-			putrune(ftable, c)
+			fcode.WriteRune(c)
 			c = getrune(finput)
 			for c != EOF {
 				if c == '\\' {
-					putrune(ftable, c)
+					fcode.WriteRune(c)
 					c = getrune(finput)
 					if c == '\n' {
 						lineno++
@@ -1401,7 +1330,7 @@
 				if c == '\n' {
 					error("newline in string or char const")
 				}
-				putrune(ftable, c)
+				fcode.WriteRune(c)
 				c = getrune(finput)
 			}
 			error("EOF in string or character constant")
@@ -1414,7 +1343,7 @@
 			lineno++
 		}
 
-		putrune(ftable, c)
+		fcode.WriteRune(c)
 	}
 }
 
@@ -2137,7 +2066,7 @@
 func output() {
 	var c, u, v int
 
-	fmt.Fprintf(ftable, "var\tYYEXCA = []int {\n")
+	fmt.Fprintf(ftable, "var\tyyExca = []int {\n")
 
 	noset := mkset()
 
@@ -2210,10 +2139,10 @@
 	}
 
 	fmt.Fprintf(ftable, "}\n")
-	fmt.Fprintf(ftable, "const\tYYNPROD\t= %v\n", nprod)
-	fmt.Fprintf(ftable, "const\tYYPRIVATE\t= %v\n", PRIVATE)
-	fmt.Fprintf(ftable, "var\tYYTOKENNAMES []string\n")
-	fmt.Fprintf(ftable, "var\tYYSTATES []string\n")
+	fmt.Fprintf(ftable, "const\tyyNprod\t= %v\n", nprod)
+	fmt.Fprintf(ftable, "const\tyyPrivate\t= %v\n", PRIVATE)
+	fmt.Fprintf(ftable, "var\tyyTokenNames []string\n")
+	fmt.Fprintf(ftable, "var\tyyStates []string\n")
 }
 
 //
@@ -2616,7 +2545,7 @@
 		if tystate[i] == 0 && adb > 1 {
 			fmt.Fprintf(ftable, "State %v: null\n", i)
 		}
-		indgo[i] = YYFLAG
+		indgo[i] = yyFlag
 	}
 
 	i = nxti()
@@ -2636,7 +2565,7 @@
 			for i = 0; i < 10; i++ {
 				fmt.Fprintf(ftable, "%v  ", amem[p+i])
 			}
-			putrune(ftable, '\n')
+			ftable.WriteRune('\n')
 		}
 	}
 
@@ -2788,10 +2717,10 @@
 // write out the optimized parser
 //
 func aoutput() {
-	fmt.Fprintf(ftable, "const\tYYLAST\t= %v\n", maxa+1)
-	arout("YYACT", amem, maxa+1)
-	arout("YYPACT", indgo, nstate)
-	arout("YYPGO", pgo, nnonter+1)
+	fmt.Fprintf(ftable, "const\tyyLast\t= %v\n", maxa+1)
+	arout("yyAct", amem, maxa+1)
+	arout("yyPact", indgo, nstate)
+	arout("yyPgo", pgo, nnonter+1)
 }
 
 //
@@ -2800,7 +2729,7 @@
 func others() {
 	var i, j int
 
-	arout("YYR1", levprd, nprod)
+	arout("yyR1", levprd, nprod)
 	aryfil(temp1, nprod, 0)
 
 	//
@@ -2809,7 +2738,7 @@
 	for i = 1; i < nprod; i++ {
 		temp1[i] = len(prdptr[i]) - 2
 	}
-	arout("YYR2", temp1, nprod)
+	arout("yyR2", temp1, nprod)
 
 	aryfil(temp1, nstate, -1000)
 	for i = 0; i <= ntokens; i++ {
@@ -2822,8 +2751,8 @@
 			temp1[j] = -i
 		}
 	}
-	arout("YYCHK", temp1, nstate)
-	arout("YYDEF", defact, nstate)
+	arout("yyChk", temp1, nstate)
+	arout("yyDef", defact, nstate)
 
 	// put out token translation tables
 	// table 1 has 0-256
@@ -2848,7 +2777,7 @@
 			temp1[i] = YYLEXUNK
 		}
 	}
-	arout("YYTOK1", temp1, c+1)
+	arout("yyTok1", temp1, c+1)
 
 	// table 2 has PRIVATE-PRIVATE+256
 	aryfil(temp1, 256, 0)
@@ -2867,10 +2796,10 @@
 			}
 		}
 	}
-	arout("YYTOK2", temp1, c+1)
+	arout("yyTok2", temp1, c+1)
 
 	// table 3 has everything else
-	fmt.Fprintf(ftable, "var\tYYTOK3\t= []int {\n")
+	fmt.Fprintf(ftable, "var\tyyTok3\t= []int {\n")
 	c = 0
 	for i = 1; i <= ntokens; i++ {
 		j = tokset[i].value
@@ -2884,7 +2813,7 @@
 		fmt.Fprintf(ftable, "%4d,%4d,", j, i)
 		c++
 		if c%5 == 0 {
-			putrune(ftable, '\n')
+			ftable.WriteRune('\n')
 		}
 	}
 	fmt.Fprintf(ftable, "%4d,\n };\n", 0)
@@ -2892,22 +2821,25 @@
 	// copy parser text
 	c = getrune(finput)
 	for c != EOF {
-		putrune(ftable, c)
+		ftable.WriteRune(c)
 		c = getrune(finput)
 	}
 
+	parts := strings.Split(yaccpar, "yyrun()", 2)
 	// copy yaccpar
-	fmt.Fprintf(ftable, "%v", yaccpar)
+	fmt.Fprintf(ftable, "%v", parts[0])
+	ftable.Write(fcode.Bytes())
+	fmt.Fprintf(ftable, "%v", parts[1])
 }
 
 func arout(s string, v []int, n int) {
 	fmt.Fprintf(ftable, "var\t%v\t= []int {\n", s)
 	for i := 0; i < n; i++ {
 		if i%10 == 0 {
-			putrune(ftable, '\n')
+			ftable.WriteRune('\n')
 		}
 		fmt.Fprintf(ftable, "%4d", v[i])
-		putrune(ftable, ',')
+		ftable.WriteRune(',')
 	}
 	fmt.Fprintf(ftable, "\n};\n")
 }
@@ -2978,7 +2910,7 @@
 }
 
 func usage() {
-	fmt.Fprintf(stderr, "usage: gacc [-o output] [-v parsetable] input\n")
+	fmt.Fprintf(stderr, "usage: goyacc [-o output] [-v parsetable] input\n")
 	exit(1)
 }
 
@@ -3144,224 +3076,228 @@
 var yaccpar = `
 /*	parser for yacc output	*/
 
-var	Nerrs		= 0		/* number of errors */
-var	Errflag		= 0		/* error recovery flag */
-var	Debug		= 0
-const	YYFLAG		= -1000
+var yyDebug = 0
 
-func
-Tokname(yyc int) string {
-	if yyc > 0 && yyc <= len(Toknames) {
-		if Toknames[yyc-1] != "" {
-			return Toknames[yyc-1];
-		}
-	}
-	return fmt.Sprintf("tok-%v", yyc);
+type yyLexer interface {
+	Lex(lval *yySymType) int
 }
 
-func
-Statname(yys int) string {
-	if yys >= 0 && yys < len(Statenames) {
-		if Statenames[yys] != "" {
-			return Statenames[yys];
+const yyFlag = -1000
+
+func yyTokname(yyc int) string {
+	if yyc > 0 && yyc <= len(yyToknames) {
+		if yyToknames[yyc-1] != "" {
+			return yyToknames[yyc-1]
 		}
 	}
-	return fmt.Sprintf("state-%v", yys);
+	return fmt.Sprintf("tok-%v", yyc)
 }
 
-func
-lex1() int {
-	var yychar int;
-	var c int;
+func yyStatname(yys int) string {
+	if yys >= 0 && yys < len(yyStatenames) {
+		if yyStatenames[yys] != "" {
+			return yyStatenames[yys]
+		}
+	}
+	return fmt.Sprintf("state-%v", yys)
+}
 
-	yychar = Lex();
+func yylex1(yylex yyLexer, lval *yySymType) int {
+	var yychar int
+	var c int
+
+	yychar = yylex.Lex(lval)
 	if yychar <= 0 {
-		c = YYTOK1[0];
-		goto out;
+		c = yyTok1[0]
+		goto out
 	}
-	if yychar < len(YYTOK1) {
-		c = YYTOK1[yychar];
-		goto out;
+	if yychar < len(yyTok1) {
+		c = yyTok1[yychar]
+		goto out
 	}
-	if yychar >= YYPRIVATE {
-		if yychar < YYPRIVATE+len(YYTOK2) {
-			c = YYTOK2[yychar-YYPRIVATE];
-			goto out;
+	if yychar >= yyPrivate {
+		if yychar < yyPrivate+len(yyTok2) {
+			c = yyTok2[yychar-yyPrivate]
+			goto out
 		}
 	}
-	for i:=0; i<len(YYTOK3); i+=2 {
-		c = YYTOK3[i+0];
+	for i := 0; i < len(yyTok3); i += 2 {
+		c = yyTok3[i+0]
 		if c == yychar {
-			c = YYTOK3[i+1];
-			goto out;
+			c = yyTok3[i+1]
+			goto out
 		}
 	}
-	c = 0;
+	c = 0
 
 out:
 	if c == 0 {
-		c = YYTOK2[1];	/* unknown char */
+		c = yyTok2[1] /* unknown char */
 	}
-	if Debug >= 3 {
-		fmt.Printf("lex %.4lux %s\n", yychar, Tokname(c));
+	if yyDebug >= 3 {
+		fmt.Printf("lex %.4x %s\n", uint(yychar), yyTokname(c))
 	}
-	return c;
+	return c
 }
 
-func
-Parse() int {
-	var yyj, yystate, yyn, yyg, yyxi, yyp int;
-	var yychar int;
-	var yypt, yynt int;
+func yyParse(yylex yyLexer) int {
+	var yyn int
+	var yylval yySymType
+	var YYVAL yySymType
+	YYS := make([]yySymType, yyMaxDepth)
 
-	yystate = 0;
-	yychar = -1;
-	Nerrs = 0;
-	Errflag = 0;
-	yyp = -1;
-	goto yystack;
+	Nerrs := 0   /* number of errors */
+	Errflag := 0 /* error recovery flag */
+	yystate := 0
+	yychar := -1
+	yyp := -1
+	goto yystack
 
 ret0:
-	return 0;
+	return 0
 
 ret1:
-	return 1;
+	return 1
 
 yystack:
 	/* put a state and value onto the stack */
-	if Debug >= 4 {
-		fmt.Printf("char %v in %v", Tokname(yychar), Statname(yystate));
+	if yyDebug >= 4 {
+		fmt.Printf("char %v in %v", yyTokname(yychar), yyStatname(yystate))
 	}
 
-	yyp++;
+	yyp++
 	if yyp >= len(YYS) {
-		Error("yacc stack overflow");
-		goto ret1;
+		nyys := make([]yySymType, len(YYS)*2)
+		copy(nyys, YYS)
+		YYS = nyys
 	}
-	YYS[yyp] = YYVAL;
-	YYS[yyp].yys = yystate;
+	YYS[yyp] = YYVAL
+	YYS[yyp].yys = yystate
 
 yynewstate:
-	yyn = YYPACT[yystate];
-	if yyn <= YYFLAG {
-		goto yydefault; /* simple state */
+	yyn = yyPact[yystate]
+	if yyn <= yyFlag {
+		goto yydefault /* simple state */
 	}
 	if yychar < 0 {
-		yychar = lex1();
+		yychar = yylex1(yylex, &yylval)
 	}
-	yyn += yychar;
-	if yyn < 0 || yyn >= YYLAST {
-		goto yydefault;
+	yyn += yychar
+	if yyn < 0 || yyn >= yyLast {
+		goto yydefault
 	}
-	yyn = YYACT[yyn];
-	if YYCHK[yyn] == yychar { /* valid shift */
-		yychar = -1;
-		YYVAL = yylval;
-		yystate = yyn;
+	yyn = yyAct[yyn]
+	if yyChk[yyn] == yychar { /* valid shift */
+		yychar = -1
+		YYVAL = yylval
+		yystate = yyn
 		if Errflag > 0 {
-			Errflag--;
+			Errflag--
 		}
-		goto yystack;
+		goto yystack
 	}
 
 yydefault:
 	/* default state action */
-	yyn = YYDEF[yystate];
+	yyn = yyDef[yystate]
 	if yyn == -2 {
 		if yychar < 0 {
-			yychar = lex1();
+			yychar = yylex1(yylex, &yylval)
 		}
 
 		/* look through exception table */
-		for yyxi=0;; yyxi+=2 {
-			if YYEXCA[yyxi+0] == -1 && YYEXCA[yyxi+1] == yystate {
-				break;
+		yyxi := 0
+		for {
+			if yyExca[yyxi+0] == -1 && yyExca[yyxi+1] == yystate {
+				break
 			}
+			yyxi += 2
 		}
-		for yyxi += 2;; yyxi += 2 {
-			yyn = YYEXCA[yyxi+0];
+		for yyxi += 2; ; yyxi += 2 {
+			yyn = yyExca[yyxi+0]
 			if yyn < 0 || yyn == yychar {
-				break;
+				break
 			}
 		}
-		yyn = YYEXCA[yyxi+1];
+		yyn = yyExca[yyxi+1]
 		if yyn < 0 {
-			goto ret0;
+			goto ret0
 		}
 	}
 	if yyn == 0 {
 		/* error ... attempt to resume parsing */
 		switch Errflag {
-		case 0:   /* brand new error */
-			Error("syntax error");
-			Nerrs++;
-			if Debug >= 1 {
-				fmt.Printf("%s", Statname(yystate));
-				fmt.Printf("saw %s\n", Tokname(yychar));
+		case 0: /* brand new error */
+			yyError("syntax error")
+			Nerrs++
+			if yyDebug >= 1 {
+				fmt.Printf("%s", yyStatname(yystate))
+				fmt.Printf("saw %s\n", yyTokname(yychar))
 			}
-			fallthrough;
+			fallthrough
 
-		case 1,2: /* incompletely recovered error ... try again */
-			Errflag = 3;
+		case 1, 2: /* incompletely recovered error ... try again */
+			Errflag = 3
 
 			/* find a state where "error" is a legal shift action */
 			for yyp >= len(YYS) {
-				yyn = YYPACT[YYS[yyp].yys] + YYERRCODE;
-				if yyn >= 0 && yyn < YYLAST {
-					yystate = YYACT[yyn];  /* simulate a shift of "error" */
-					if YYCHK[yystate] == YYERRCODE {
-						goto yystack;
+				yyn = yyPact[YYS[yyp].yys] + yyErrCode
+				if yyn >= 0 && yyn < yyLast {
+					yystate = yyAct[yyn] /* simulate a shift of "error" */
+					if yyChk[yystate] == yyErrCode {
+						goto yystack
 					}
 				}
 
 				/* the current yyp has no shift onn "error", pop stack */
-				if Debug >= 2 {
+				if yyDebug >= 2 {
 					fmt.Printf("error recovery pops state %d, uncovers %d\n",
-						YYS[yyp].yys, YYS[yyp-1].yys );
+						YYS[yyp].yys, YYS[yyp-1].yys)
 				}
-				yyp--;
+				yyp--
 			}
 			/* there is no state on the stack with an error shift ... abort */
-			goto ret1;
+			goto ret1
 
-		case 3:  /* no shift yet; clobber input char */
-			if Debug >= 2 {
-				fmt.Printf("error recovery discards %s\n", Tokname(yychar));
+		case 3: /* no shift yet; clobber input char */
+			if yyDebug >= 2 {
+				fmt.Printf("error recovery discards %s\n", yyTokname(yychar))
 			}
-			if yychar == YYEOFCODE {
-				goto ret1;
+			if yychar == yyEofCode {
+				goto ret1
 			}
-			yychar = -1;
-			goto yynewstate;   /* try again in the same state */
+			yychar = -1
+			goto yynewstate /* try again in the same state */
 		}
 	}
 
 	/* reduction by production yyn */
-	if Debug >= 2 {
-		fmt.Printf("reduce %v in:\n\t%v", yyn, Statname(yystate));
+	if yyDebug >= 2 {
+		fmt.Printf("reduce %v in:\n\t%v", yyn, yyStatname(yystate))
 	}
 
-	yynt = yyn;
-	yypt = yyp;
+	yynt := yyn
+	yypt := yyp
+	_ = yypt		// guard against "declared and not used"
 
-	yyp -= YYR2[yyn];
-	YYVAL = YYS[yyp+1];
+	yyp -= yyR2[yyn]
+	YYVAL = YYS[yyp+1]
 
 	/* consult goto table to find next state */
-	yyn = YYR1[yyn];
-	yyg = YYPGO[yyn];
-	yyj = yyg + YYS[yyp].yys + 1;
+	yyn = yyR1[yyn]
+	yyg := yyPgo[yyn]
+	yyj := yyg + YYS[yyp].yys + 1
 
-	if yyj >= YYLAST {
-		yystate = YYACT[yyg];
+	if yyj >= yyLast {
+		yystate = yyAct[yyg]
 	} else {
-		yystate = YYACT[yyj];
-		if YYCHK[yystate] != -yyn {
-			yystate = YYACT[yyg];
+		yystate = yyAct[yyj]
+		if yyChk[yystate] != -yyn {
+			yystate = yyAct[yyg]
 		}
 	}
-
-	yyrun(yynt, yypt);
-	goto yystack;  /* stack new state and value */
+	// dummy call; replaced with literal code
+	yyrun()
+	goto yystack /* stack new state and value */
 }
 `
diff --git a/src/cmd/goyacc/units.y b/src/cmd/goyacc/units.y
index 9be7fa4..b909d11 100644
--- a/src/cmd/goyacc/units.y
+++ b/src/cmd/goyacc/units.y
@@ -23,48 +23,44 @@
 
 package main
 
-import
-(
-	"flag";
-	"fmt";
-	"bufio";
-	"os";
-	"math";
-	"strconv";
-	"utf8";
+import (
+	"flag"
+	"fmt"
+	"bufio"
+	"os"
+	"math"
+	"strconv"
+	"utf8"
 )
 
-const
-(
-	Ndim	= 15;				// number of dimensions
-	Maxe	= 695;				// log of largest number
+const (
+	Ndim = 15  // number of dimensions
+	Maxe = 695 // log of largest number
 )
 
-type
-Node struct {
-	vval	float64;
-	dim	[Ndim]int8;
+type Node struct {
+	vval float64
+	dim  [Ndim]int8
 }
 
-type
-Var struct {
-	name	string;
-	node	Node;
+type Var struct {
+	name string
+	node Node
 }
 
-var	fi		*bufio.Reader		// input
-var	fund		[Ndim]*Var		// names of fundamental units
-var	line		string			// current input line
-var	lineno		int			// current input line number
-var	linep		int			// index to next rune in unput
-var	nerrors		int			// error count
-var	one		Node			// constant one
-var	peekrune	int			// backup runt from input
-var	retnode1	Node
-var	retnode2	Node
-var	retnode		Node
-var	sym		string
-var	vflag		bool
+var fi *bufio.Reader // input
+var fund [Ndim]*Var  // names of fundamental units
+var line string      // current input line
+var lineno int       // current input line number
+var linep int        // index to next rune in unput
+var nerrors int      // error count
+var one Node         // constant one
+var peekrune int     // backup runt from input
+var retnode1 Node
+var retnode2 Node
+var retnode Node
+var sym string
+var vflag bool
 
 %}
 
@@ -217,481 +213,462 @@
 	}
 %%
 
-func
-Lex() int {
-	var c, i int;
+type UnitsLex int
 
-	c = peekrune;
-	peekrune = ' ';
+func (l UnitsLex) Lex(yylval *yySymType) int {
+	var c, i int
+
+	c = peekrune
+	peekrune = ' '
 
 loop:
 	if (c >= '0' && c <= '9') || c == '.' {
-		goto numb;
+		goto numb
 	}
 	if ralpha(c) {
-		goto alpha;
+		goto alpha
 	}
 	switch c {
 	case ' ', '\t':
-		c = getrune();
-		goto loop;
+		c = getrune()
+		goto loop
 	case '×':
-		return '*';
+		return '*'
 	case '÷':
-		return '/';
+		return '/'
 	case '¹', 'ⁱ':
-		yylval.numb = 1;
-		return SUP;
+		yylval.numb = 1
+		return SUP
 	case '²', '⁲':
-		yylval.numb = 2;
-		return SUP;
+		yylval.numb = 2
+		return SUP
 	case '³', '⁳':
-		yylval.numb = 3;
-		return SUP;
+		yylval.numb = 3
+		return SUP
 	}
-	return c;
+	return c
 
 alpha:
-	sym = "";
-	for i=0;; i++ {
-		sym += string(c);
-		c = getrune();
+	sym = ""
+	for i = 0; ; i++ {
+		sym += string(c)
+		c = getrune()
 		if !ralpha(c) {
-			break;
+			break
 		}
 	}
-	peekrune = c;
-	yylval.vvar = lookup(0);
-	return VAR;
+	peekrune = c
+	yylval.vvar = lookup(0)
+	return VAR
 
 numb:
-	sym = "";
-	for i=0;; i++ {
-		sym += string(c);
-		c = getrune();
+	sym = ""
+	for i = 0; ; i++ {
+		sym += string(c)
+		c = getrune()
 		if !rdigit(c) {
-			break;
+			break
 		}
 	}
-	peekrune = c;
-	f, err := strconv.Atof64(sym);
+	peekrune = c
+	f, err := strconv.Atof64(sym)
 	if err != nil {
-		fmt.Printf("error converting %v", sym);
-		f = 0;
+		fmt.Printf("error converting %v\n", sym)
+		f = 0
 	}
-	yylval.vval = f;
-	return VAL;
+	yylval.vval = f
+	return VAL
 }
 
-func
-main() {
-	var file string;
+func main() {
+	var file string
 
-	flag.BoolVar(&vflag, "v", false, "verbose");
+	flag.BoolVar(&vflag, "v", false, "verbose")
 
-	flag.Parse();
+	flag.Parse()
 
-	file = os.Getenv("GOROOT") + "/src/cmd/goyacc/units.txt";
+	file = os.Getenv("GOROOT") + "/src/cmd/goyacc/units.txt"
 	if flag.NArg() > 0 {
-		file = flag.Arg(0);
+		file = flag.Arg(0)
 	}
 
-	f,err := os.Open(file, os.O_RDONLY, 0);
+	f, err := os.Open(file, os.O_RDONLY, 0)
 	if err != nil {
-		fmt.Printf("error opening %v: %v", file, err);
-		os.Exit(1);
+		fmt.Printf("error opening %v: %v\n", file, err)
+		os.Exit(1)
 	}
-	fi = bufio.NewReader(f);
+	fi = bufio.NewReader(f)
 
-	one.vval = 1;
+	one.vval = 1
 
 	/*
 	 * read the 'units' file to
 	 * develope a database
 	 */
-	lineno = 0;
+	lineno = 0
 	for {
-		lineno++;
+		lineno++
 		if readline() {
-			break;
+			break
 		}
 		if len(line) == 0 || line[0] == '/' {
-			continue;
+			continue
 		}
-		peekrune = ':';
-		Parse();
+		peekrune = ':'
+		yyParse(UnitsLex(0))
 	}
 
 	/*
 	 * read the console to
 	 * print ratio of pairs
 	 */
-	fi = bufio.NewReader(os.NewFile(0, "stdin"));
+	fi = bufio.NewReader(os.NewFile(0, "stdin"))
 
-	lineno = 0;
+	lineno = 0
 	for {
 		if (lineno & 1) != 0 {
-			fmt.Printf("you want: ");
-		} else
-			fmt.Printf("you have: ");
-		if readline() {
-			break;
+			fmt.Printf("you want: ")
+		} else {
+			fmt.Printf("you have: ")
 		}
-		peekrune = '?';
-		nerrors = 0;
-		Parse();
+		if readline() {
+			break
+		}
+		peekrune = '?'
+		nerrors = 0
+		yyParse(UnitsLex(0))
 		if nerrors != 0 {
-			continue;
+			continue
 		}
 		if (lineno & 1) != 0 {
 			if specialcase(&retnode, &retnode2, &retnode1) {
-				fmt.Printf("\tis %v\n", &retnode);
+				fmt.Printf("\tis %v\n", &retnode)
 			} else {
-				div(&retnode, &retnode2, &retnode1);
-				fmt.Printf("\t* %v\n", &retnode);
-				div(&retnode, &retnode1, &retnode2);
-				fmt.Printf("\t/ %v\n", &retnode);
+				div(&retnode, &retnode2, &retnode1)
+				fmt.Printf("\t* %v\n", &retnode)
+				div(&retnode, &retnode1, &retnode2)
+				fmt.Printf("\t/ %v\n", &retnode)
 			}
-		} else
-			retnode2 = retnode1;
-		lineno++;
+		} else {
+			retnode2 = retnode1
+		}
+		lineno++
 	}
-	fmt.Printf("\n");
-	os.Exit(0);
+	fmt.Printf("\n")
+	os.Exit(0)
 }
 
 /*
  * all characters that have some
  * meaning. rest are usable as names
  */
-func
-ralpha(c int) bool {
+func ralpha(c int) bool {
 	switch c {
-	case	0, '+', '-', '*', '/', '[', ']', '(', ')',
+	case 0, '+', '-', '*', '/', '[', ']', '(', ')',
 		'^', ':', '?', ' ', '\t', '.', '|', '#',
 		'×', '÷', '¹', 'ⁱ', '²', '⁲', '³', '⁳':
-			return false;
+		return false
 	}
-	return true;
+	return true
 }
 
 /*
  * number forming character
  */
-func
-rdigit(c int) bool {
+func rdigit(c int) bool {
 	switch c {
-	case	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 		'.', 'e', '+', '-':
-		return true;
+		return true
 	}
-	return false;
+	return false
 }
 
-func
-Error(s string, v ...interface{}) {
+func yyError(s string) {
+	Error("syntax error, last name: %v", sym)
+}
 
-	/*
-	 * hack to intercept message from yaccpar
-	 */
-	if s == "syntax error" {
-		Error("syntax error, last name: %v", sym);
-		return;
-	}
-	fmt.Printf("%v: %v\n\t", lineno, line);
-	fmt.Printf(s, v);
-	fmt.Printf("\n");
+func Error(s string, v ...interface{}) {
+	fmt.Printf("%v: %v\n\t", lineno, line)
+	fmt.Printf(s, v)
+	fmt.Printf("\n")
 
-	nerrors++;
+	nerrors++
 	if nerrors > 5 {
-		fmt.Printf("too many errors\n");
-		os.Exit(1);
+		fmt.Printf("too many errors\n")
+		os.Exit(1)
 	}
 }
 
-func
-add(c,a,b *Node) {
-	var i int;
-	var d int8;
+func add(c, a, b *Node) {
+	var i int
+	var d int8
 
-	for i=0; i<Ndim; i++ {
-		d = a.dim[i];
-		c.dim[i] = d;
+	for i = 0; i < Ndim; i++ {
+		d = a.dim[i]
+		c.dim[i] = d
 		if d != b.dim[i] {
-			Error("add must be like units");
+			Error("add must be like units")
 		}
 	}
-	c.vval = fadd(a.vval, b.vval);
+	c.vval = fadd(a.vval, b.vval)
 }
 
-func
-sub(c,a,b *Node) {
-	var i int;
-	var d int8;
+func sub(c, a, b *Node) {
+	var i int
+	var d int8
 
-	for i=0; i<Ndim; i++ {
-		d = a.dim[i];
-		c.dim[i] = d;
+	for i = 0; i < Ndim; i++ {
+		d = a.dim[i]
+		c.dim[i] = d
 		if d != b.dim[i] {
-			Error("sub must be like units");
+			Error("sub must be like units")
 		}
 	}
-	c.vval = fadd(a.vval, -b.vval);
+	c.vval = fadd(a.vval, -b.vval)
 }
 
-func
-mul(c,a,b *Node) {
-	var i int;
+func mul(c, a, b *Node) {
+	var i int
 
-	for i=0; i<Ndim; i++ {
-		c.dim[i] = a.dim[i] + b.dim[i];
+	for i = 0; i < Ndim; i++ {
+		c.dim[i] = a.dim[i] + b.dim[i]
 	}
-	c.vval = fmul(a.vval, b.vval);
+	c.vval = fmul(a.vval, b.vval)
 }
 
-func
-div(c,a,b *Node) {
-	var i int;
+func div(c, a, b *Node) {
+	var i int
 
-	for i=0; i<Ndim; i++ {
-		c.dim[i] = a.dim[i] - b.dim[i];
+	for i = 0; i < Ndim; i++ {
+		c.dim[i] = a.dim[i] - b.dim[i]
 	}
-	c.vval = fdiv(a.vval, b.vval);
+	c.vval = fdiv(a.vval, b.vval)
 }
 
-func
-xpn(c,a *Node, b int) {
-	var i int;
+func xpn(c, a *Node, b int) {
+	var i int
 
-	*c = one;
+	*c = one
 	if b < 0 {
-		b = -b;
-		for i=0; i<b; i++ {
-			div(c, c, a);
+		b = -b
+		for i = 0; i < b; i++ {
+			div(c, c, a)
 		}
-	} else
-	for i=0; i<b; i++ {
-		mul(c, c, a);
+	} else {
+		for i = 0; i < b; i++ {
+			mul(c, c, a)
+		}
 	}
 }
 
-func
-specialcase(c,a,b *Node) bool {
-	var i int;
-	var d, d1, d2 int8;
+func specialcase(c, a, b *Node) bool {
+	var i int
+	var d, d1, d2 int8
 
-	d1 = 0;
-	d2 = 0;
-	for i=1; i<Ndim; i++ {
-		d = a.dim[i];
+	d1 = 0
+	d2 = 0
+	for i = 1; i < Ndim; i++ {
+		d = a.dim[i]
 		if d != 0 {
 			if d != 1 || d1 != 0 {
-				return false;
+				return false
 			}
-			d1 = int8(i);
+			d1 = int8(i)
 		}
-		d = b.dim[i];
+		d = b.dim[i]
 		if d != 0 {
 			if d != 1 || d2 != 0 {
-				return false;
+				return false
 			}
-			d2 = int8(i);
+			d2 = int8(i)
 		}
 	}
 	if d1 == 0 || d2 == 0 {
-		return false;
+		return false
 	}
 
 	if fund[d1].name == "°C" && fund[d2].name == "°F" &&
-	   b.vval == 1 {
-		for ll:=0; ll<len(c.dim); ll++ {
-			c.dim[ll] = b.dim[ll];
+		b.vval == 1 {
+		for ll := 0; ll < len(c.dim); ll++ {
+			c.dim[ll] = b.dim[ll]
 		}
-		c.vval = a.vval * 9. / 5. + 32.;
-		return true;
+		c.vval = a.vval*9./5. + 32.
+		return true
 	}
 
 	if fund[d1].name == "°F" && fund[d2].name == "°C" &&
-	   b.vval == 1 {
-		for ll:=0; ll<len(c.dim); ll++ {
-			c.dim[ll] = b.dim[ll];
+		b.vval == 1 {
+		for ll := 0; ll < len(c.dim); ll++ {
+			c.dim[ll] = b.dim[ll]
 		}
-		c.vval = (a.vval - 32.) * 5. / 9.;
-		return true;
+		c.vval = (a.vval - 32.) * 5. / 9.
+		return true
 	}
-	return false;
+	return false
 }
 
-func
-printdim(str string, d, n int) string {
-	var v *Var;
+func printdim(str string, d, n int) string {
+	var v *Var
 
 	if n != 0 {
-		v = fund[d];
+		v = fund[d]
 		if v != nil {
-			str += fmt.Sprintf("%v", v.name);
-		} else
-			str += fmt.Sprintf("[%d]", d);
+			str += fmt.Sprintf("%v", v.name)
+		} else {
+			str += fmt.Sprintf("[%d]", d)
+		}
 		switch n {
 		case 1:
-			break;
+			break
 		case 2:
-			str += "²";
+			str += "²"
 		case 3:
-			str += "³";
+			str += "³"
 		default:
-			str += fmt.Sprintf("^%d", n);
+			str += fmt.Sprintf("^%d", n)
 		}
 	}
-	return str;
+	return str
 }
 
-func
-(n Node) String() string {
-	var str string;
-	var f, i, d int;
+func (n Node) String() string {
+	var str string
+	var f, i, d int
 
-	str = fmt.Sprintf("%.7e ", n.vval);
+	str = fmt.Sprintf("%.7e ", n.vval)
 
-	f = 0;
-	for i=1; i<Ndim; i++ {
-		d = int(n.dim[i]);
+	f = 0
+	for i = 1; i < Ndim; i++ {
+		d = int(n.dim[i])
 		if d > 0 {
-			str = printdim(str, i, d);
-		} else
-		if d < 0 {
-			f = 1;
+			str = printdim(str, i, d)
+		} else if d < 0 {
+			f = 1
 		}
 	}
 
 	if f != 0 {
-		str += " /";
-		for i=1; i<Ndim; i++ {
-			d = int(n.dim[i]);
+		str += " /"
+		for i = 1; i < Ndim; i++ {
+			d = int(n.dim[i])
 			if d < 0 {
-				str = printdim(str, i, -d);
+				str = printdim(str, i, -d)
 			}
 		}
 	}
 
-	return str;
+	return str
 }
 
-func
-(v *Var) String() string {
-	var str string;
-	str = fmt.Sprintf("%v %v", v.name, v.node);
-	return str;
+func (v *Var) String() string {
+	var str string
+	str = fmt.Sprintf("%v %v", v.name, v.node)
+	return str
 }
 
-func
-readline() bool {
-	s,err := fi.ReadString('\n');
+func readline() bool {
+	s, err := fi.ReadString('\n')
 	if err != nil {
-		return true;
+		return true
 	}
-	line = s;
-	linep = 0;
-	return false;
+	line = s
+	linep = 0
+	return false
 }
 
-func
-getrune() int {
-	var c,n int;
+func getrune() int {
+	var c, n int
 
 	if linep >= len(line) {
-		return 0;
+		return 0
 	}
-	c,n = utf8.DecodeRuneInString(line[linep:len(line)]);
-	linep += n;
+	c, n = utf8.DecodeRuneInString(line[linep:len(line)])
+	linep += n
 	if c == '\n' {
-		c = 0;
+		c = 0
 	}
-	return c;
+	return c
 }
 
-var	symmap	= make(map[string]*Var);	// symbol table
+var symmap = make(map[string]*Var) // symbol table
 
-func
-lookup(f int) *Var {
-	var p float64;
-	var w *Var;
+func lookup(f int) *Var {
+	var p float64
+	var w *Var
 
-	v,ok := symmap[sym];
+	v, ok := symmap[sym]
 	if ok {
-		return v;
+		return v
 	}
 	if f != 0 {
-		return nil;
+		return nil
 	}
-	v = new(Var);
-	v.name = sym;
-	symmap[sym] = v;
+	v = new(Var)
+	v.name = sym
+	symmap[sym] = v
 
-	p = 1;
+	p = 1
 	for {
-		p = fmul(p, pname());
+		p = fmul(p, pname())
 		if p == 0 {
-			break;
+			break
 		}
-		w = lookup(1);
+		w = lookup(1)
 		if w != nil {
-			v.node = w.node;
-			v.node.vval = fmul(v.node.vval, p);
-			break;
+			v.node = w.node
+			v.node.vval = fmul(v.node.vval, p)
+			break
 		}
 	}
-	return v;
+	return v
 }
 
-type
-Prefix struct
-{
-	vval	float64;
-	name	string;
+type Prefix struct {
+	vval float64
+	name string
 }
 
-var	prefix	 = []Prefix {			// prefix table
-	Prefix { 1e-24,		"yocto" },
-	Prefix { 1e-21,		"zepto" },
-	Prefix { 1e-18,		"atto"  },
-	Prefix { 1e-15,		"femto" },
-	Prefix { 1e-12,		"pico"  },
-	Prefix { 1e-9,		"nano"  },
-	Prefix { 1e-6,		"micro" },
-	Prefix { 1e-6,		"μ"     },
-	Prefix { 1e-3,		"milli" },
-	Prefix { 1e-2,		"centi" },
-	Prefix { 1e-1,		"deci"  },
-	Prefix { 1e1,		"deka"  },
-	Prefix { 1e2,		"hecta" },
-	Prefix { 1e2,		"hecto" },
-	Prefix { 1e3,		"kilo"  },
-	Prefix { 1e6,		"mega"  },
-	Prefix { 1e6,		"meg"   },
-	Prefix { 1e9,		"giga"  },
-	Prefix { 1e12,		"tera"  },
-	Prefix { 1e15,		"peta"  },
-	Prefix { 1e18,		"exa"   },
-	Prefix { 1e21,		"zetta" },
-	Prefix { 1e24,		"yotta" },
+var prefix = []Prefix{ // prefix table
+	Prefix{1e-24, "yocto"},
+	Prefix{1e-21, "zepto"},
+	Prefix{1e-18, "atto"},
+	Prefix{1e-15, "femto"},
+	Prefix{1e-12, "pico"},
+	Prefix{1e-9, "nano"},
+	Prefix{1e-6, "micro"},
+	Prefix{1e-6, "μ"},
+	Prefix{1e-3, "milli"},
+	Prefix{1e-2, "centi"},
+	Prefix{1e-1, "deci"},
+	Prefix{1e1, "deka"},
+	Prefix{1e2, "hecta"},
+	Prefix{1e2, "hecto"},
+	Prefix{1e3, "kilo"},
+	Prefix{1e6, "mega"},
+	Prefix{1e6, "meg"},
+	Prefix{1e9, "giga"},
+	Prefix{1e12, "tera"},
+	Prefix{1e15, "peta"},
+	Prefix{1e18, "exa"},
+	Prefix{1e21, "zetta"},
+	Prefix{1e24, "yotta"},
 }
 
-func
-pname() float64 {
-	var i, j, n int;
-	var s string;
+func pname() float64 {
+	var i, j, n int
+	var s string
 
 	/*
 	 * rip off normal prefixs
 	 */
-	n = len(sym);
-	for i=0; i<len(prefix); i++ {
-		s = prefix[i].name;
-		j = len(s);
+	n = len(sym)
+	for i = 0; i < len(prefix); i++ {
+		s = prefix[i].name
+		j = len(s)
 		if j < n && sym[0:j] == s {
-			sym = sym[j:n];
-			return prefix[i].vval;
+			sym = sym[j:n]
+			return prefix[i].vval
 		}
 	}
 
@@ -699,82 +676,83 @@
 	 * rip off 's' suffixes
 	 */
 	if n > 2 && sym[n-1] == 's' {
-		sym = sym[0:n-1];
-		return 1;
+		sym = sym[0 : n-1]
+		return 1
 	}
 
-	return 0;
+	return 0
 }
 
 
 // careful multiplication
 // exponents (log) are checked before multiply
-func
-fmul(a, b float64) float64 {
-	var l float64;
+func fmul(a, b float64) float64 {
+	var l float64
 
 	if b <= 0 {
 		if b == 0 {
-			return 0;
+			return 0
 		}
-		l = math.Log(-b);
-	} else
-		l = math.Log(b);
+		l = math.Log(-b)
+	} else {
+		l = math.Log(b)
+	}
 
 	if a <= 0 {
 		if a == 0 {
-			return 0;
+			return 0
 		}
-		l += math.Log(-a);
-	} else
-		l += math.Log(a);
+		l += math.Log(-a)
+	} else {
+		l += math.Log(a)
+	}
 
 	if l > Maxe {
-		Error("overflow in multiply");
-		return 1;
+		Error("overflow in multiply")
+		return 1
 	}
 	if l < -Maxe {
-		Error("underflow in multiply");
-		return 0;
+		Error("underflow in multiply")
+		return 0
 	}
-	return a*b;
+	return a * b
 }
 
 // careful division
 // exponents (log) are checked before divide
-func
-fdiv(a, b float64) float64 {
-	var l float64;
+func fdiv(a, b float64) float64 {
+	var l float64
 
 	if b <= 0 {
 		if b == 0 {
-			Error("division by zero: %v %v", a, b);
-			return 1;
+			Error("division by zero: %v %v", a, b)
+			return 1
 		}
-		l = math.Log(-b);
-	} else
-		l = math.Log(b);
+		l = math.Log(-b)
+	} else {
+		l = math.Log(b)
+	}
 
 	if a <= 0 {
 		if a == 0 {
-			return 0;
+			return 0
 		}
-		l -= math.Log(-a);
-	} else
-		l -= math.Log(a);
+		l -= math.Log(-a)
+	} else {
+		l -= math.Log(a)
+	}
 
 	if l < -Maxe {
-		Error("overflow in divide");
-		return 1;
+		Error("overflow in divide")
+		return 1
 	}
 	if l > Maxe {
-		Error("underflow in divide");
-		return 0;
+		Error("underflow in divide")
+		return 0
 	}
-	return a/b;
+	return a / b
 }
 
-func
-fadd(a, b float64) float64 {
-	return a + b;
+func fadd(a, b float64) float64 {
+	return a + b
 }