Skip to content

Commit 29e4dee

Browse files
Address audit issues
Eliminate changes which implemented the '-tflag' command line switch, as being unnecessary, along with the API change to the Lex and Error methods.
1 parent 414fb5e commit 29e4dee

File tree

2 files changed

+49
-59
lines changed

2 files changed

+49
-59
lines changed

cmd/goyacc/doc.go

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,32 +66,44 @@ symbols, including types, the parser, and the lexer, generated and
6666
referenced by yacc's generated code. Setting it to distinct values
6767
allows multiple grammars to be placed in a single package.
6868
69-
If the -t flag is specified, goyacc will generate a parser compatible
70-
with bison's token location tracking semantics. For more details:
69+
goyacc will generate a parser compatible with bison's token location
70+
tracking semantics. For more details:
7171
7272
https://www.gnu.org/software/bison/manual/html_node/Tracking-Locations.html
7373
https://www.gnu.org/software/bison/manual/html_node/Token-Locations.html
7474
75-
If this flag is specified, the Lex and Error methods in the Lexer
76-
interface definition change as follows:
75+
The generated Go parser will define two types:
7776
78-
type yyLexer interface {
79-
Lex(lval *yySymType, loc *YYLTYPE) int
80-
Error(loc *YYLTYPE, s string)
77+
type yyPos struct {
78+
line int
79+
column int
8180
}
8281
83-
where YYLTYPE is defined as:
84-
85-
type YYLTYPE struct {
86-
firstLine int
87-
firstColumn int
88-
lastLine int
89-
lastColumn int
82+
type yySymLoc struct {
83+
pos yyPos
84+
end yyPos
9085
}
9186
92-
The token tracking structure is stashed inside the yySymType structure.
93-
This simplifies the changes, since yacc already has to copy the structure
94-
in question.
87+
The pos field refers to the beginning of the token in question,
88+
and the end field to the end it. To avoid having to change the
89+
definition of the lexer's Error method, just before the parser calls
90+
the Error method, it will set a global variable, yyErrLoc to the
91+
address of the problematic token's yySymLoc structure. Since the
92+
lexer provides location information to the parser, and in turn is
93+
provided it, if needed, it's up to the lexer to do so consistently.
94+
95+
As in the above-cited BISON web pages, goyacc will support the use
96+
of @N, where N is an integer from 1 to 9, and will be expanded in
97+
the generated parser to the appropriate variable. If an action rule
98+
wants to print a specific error message, the lexer should be written
99+
to provide one to the parser.
100+
101+
If goyacc was invoked with an explicit prefix, via the '-p' switch,
102+
the above types and variables will have the appropriate prefix.
103+
104+
The token tracking structure yySymLoc is stored inside the yySymType
105+
structure. This simplifies the changes, since goyacc already has to
106+
copy the structure in question.
95107
96108
*/
97109
package main

cmd/goyacc/yacc.go

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ var foutput *bufio.Writer // y.output file
156156

157157
var fmtImported bool // output file has recorded an import of "fmt"
158158

159-
var tflag bool // -t - enable Bison style token location tracking
160159
var oflag string // -o [y.go] - y.go file
161160
var vflag string // -v [y.output] - y.output file
162161
var lflag bool // -l - disable line directives
@@ -167,7 +166,6 @@ func init() {
167166
flag.StringVar(&prefix, "p", "yy", "name prefix to use in generated code")
168167
flag.StringVar(&vflag, "v", "y.output", "create parsing tables")
169168
flag.BoolVar(&lflag, "l", false, "disable line directives")
170-
flag.BoolVar(&tflag, "t", false, "enable token location tracking")
171169
}
172170

173171
var initialstacksize = 16
@@ -386,25 +384,7 @@ func setup() {
386384
fmt.Fprintf(stderr, "yacc: stack size too small\n")
387385
usage()
388386
}
389-
yaccpar = yaccpartext
390-
if tflag {
391-
lexMethStr := fmt.Sprintf("Lex(lval *$$SymType, loc *%sLTYPE)",
392-
strings.ToUpper(prefix))
393-
yaccpar = strings.Replace(yaccpar, "Lex(lval *$$SymType)",
394-
lexMethStr, 1)
395-
errMethStr := fmt.Sprintf("Error(loc *%sLTYPE, s string)",
396-
strings.ToUpper(prefix))
397-
yaccpar = strings.Replace(yaccpar, "Error(s string)", errMethStr, 1)
398-
yaccpar = strings.Replace(yaccpar, "lex.Error(",
399-
"lex.Error(&$$rcvr.lval.$$lloc, ", 1)
400-
lexMethStr = fmt.Sprintf("lex.Lex(lval, &lval.$$lloc)")
401-
yaccpar = strings.Replace(yaccpar, "lex.Lex(lval)", lexMethStr, 1)
402-
} else {
403-
yaccpar = strings.Replace(yaccpar, "$$VAL.$$lloc.firstColumn = $$S[$$p+1].$$lloc.firstColumn", "", 1)
404-
yaccpar = strings.Replace(yaccpar, "$$VAL.$$lloc.lastColumn = $$S[$$pt].$$lloc.lastColumn", "", 1)
405-
}
406-
yaccpar = strings.ReplaceAll(yaccpar, "$$", prefix)
407-
387+
yaccpar = strings.ReplaceAll(yaccpartext, "$$", prefix)
408388
openup()
409389

410390
fmt.Fprintf(ftable, "// Code generated by goyacc %s. DO NOT EDIT.\n", strings.Join(os.Args[1:], " "))
@@ -1072,15 +1052,15 @@ func chfind(t int, s string) int {
10721052
// copy the union declaration to the output, and the define file if present
10731053
//
10741054
func cpyunion() {
1075-
if tflag {
1076-
fmt.Fprintf(ftable, "\ntype %sLTYPE struct {",
1077-
strings.ToUpper(prefix))
1078-
fmt.Fprintf(ftable, "\n\tfirstLine int")
1079-
fmt.Fprintf(ftable, "\n\tfirstColumn int")
1080-
fmt.Fprintf(ftable, "\n\tlastLine int")
1081-
fmt.Fprintf(ftable, "\n\tlastColumn int")
1082-
fmt.Fprintf(ftable, "\n}\n")
1083-
}
1055+
fmt.Fprintf(ftable, "\ntype %sPos struct {", prefix)
1056+
fmt.Fprintf(ftable, "\n\tline\tint")
1057+
fmt.Fprintf(ftable, "\n\tcolumn\tint")
1058+
fmt.Fprintf(ftable, "\n}\n")
1059+
1060+
fmt.Fprintf(ftable, "\ntype %sSymLoc struct {", prefix)
1061+
fmt.Fprintf(ftable, "\n\tpos %sPos", prefix)
1062+
fmt.Fprintf(ftable, "\n\tend %sPos", prefix)
1063+
fmt.Fprintf(ftable, "\n}\n")
10841064

10851065
if !lflag {
10861066
fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno)
@@ -1101,11 +1081,8 @@ out:
11011081
lineno++
11021082
case '{':
11031083
if level == 0 {
1104-
fmt.Fprintf(ftable, "\n\tyys int")
1105-
if tflag {
1106-
fmt.Fprintf(ftable, "\n\t%slloc %sLTYPE", prefix,
1107-
strings.ToUpper(prefix))
1108-
}
1084+
fmt.Fprintf(ftable, "\n\tyys\tint")
1085+
fmt.Fprintf(ftable, "\n\tsymLoc\t%sSymLoc", prefix)
11091086
}
11101087
level++
11111088
case '}':
@@ -1329,13 +1306,10 @@ loop:
13291306
brac++
13301307

13311308
case '@':
1332-
if !tflag {
1333-
errorf("@ not valid without -tflag!")
1334-
}
13351309
c2 := getrune(finput)
13361310
if isdigit(c2) {
1337-
fmt.Fprintf(fcode, "%sDollar[%d].%slloc",
1338-
prefix, int(c2-'0'), prefix)
1311+
fmt.Fprintf(fcode, "%sDollar[%d].symLoc",
1312+
prefix, int(c2-'0'))
13391313
continue loop
13401314
} else {
13411315
errorf("unexpected @")
@@ -3313,6 +3287,7 @@ var yaccpartext = `
33133287
var (
33143288
$$Debug = 0
33153289
$$ErrorVerbose = false
3290+
$$ErrLoc *$$SymLoc
33163291
)
33173292
33183293
type $$Lexer interface {
@@ -3559,6 +3534,7 @@ $$default:
35593534
/* error ... attempt to resume parsing */
35603535
switch Errflag {
35613536
case 0: /* brand new error */
3537+
$$ErrLoc = &$$rcvr.lval.symLoc
35623538
$$lex.Error($$ErrorMessage($$state, $$token))
35633539
Nerrs++
35643540
if $$Debug >= 1 {
@@ -3621,8 +3597,10 @@ $$default:
36213597
}
36223598
$$VAL = $$S[$$p+1]
36233599
3624-
$$VAL.$$lloc.firstColumn = $$S[$$p+1].$$lloc.firstColumn
3625-
$$VAL.$$lloc.lastColumn = $$S[$$pt].$$lloc.lastColumn
3600+
$$VAL.symLoc.pos.line = $$S[$$p+1].symLoc.pos.line
3601+
$$VAL.symLoc.pos.column = $$S[$$p+1].symLoc.pos.column
3602+
$$VAL.symLoc.end.line = $$S[$$pt].symLoc.end.line
3603+
$$VAL.symLoc.end.column = $$S[$$pt].symLoc.end.column
36263604
36273605
/* consult goto table to find next state */
36283606
$$n = $$R1[$$n]

0 commit comments

Comments
 (0)