summaryrefslogtreecommitdiff
path: root/src/cmd/yacc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/yacc')
-rw-r--r--src/cmd/yacc/Makefile12
-rw-r--r--src/cmd/yacc/doc.go5
-rw-r--r--src/cmd/yacc/testdata/expr/README20
-rw-r--r--src/cmd/yacc/testdata/expr/expr.y (renamed from src/cmd/yacc/expr.y)7
-rw-r--r--src/cmd/yacc/testdata/expr/main.go15
-rw-r--r--src/cmd/yacc/yacc.go90
6 files changed, 62 insertions, 87 deletions
diff --git a/src/cmd/yacc/Makefile b/src/cmd/yacc/Makefile
deleted file mode 100644
index f8c8169bd..000000000
--- a/src/cmd/yacc/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-TARG=expr$(shell go env GOEXE)
-
-$(TARG): yacc.go expr.y
- go run yacc.go -p expr expr.y
- go build -o $(TARG) y.go
-
-clean:
- rm -f y.go y.output $(TARG)
diff --git a/src/cmd/yacc/doc.go b/src/cmd/yacc/doc.go
index ceaaf2448..702c9f0d2 100644
--- a/src/cmd/yacc/doc.go
+++ b/src/cmd/yacc/doc.go
@@ -20,8 +20,9 @@ written in C and documented at
Adepts of the original yacc will have no trouble adapting to this
form of the tool.
-The file expr.y in this directory is a yacc grammar for a very simple
-expression parser. It needs the flag "-p expr" (see below).
+The directory $GOROOT/cmd/yacc/testdata/expr is a yacc program
+for a very simple expression parser. See expr.y and main.go in that
+directory for examples of how to write and build yacc programs.
The generated parser is reentrant. Parse expects to be given an
argument that conforms to the following interface:
diff --git a/src/cmd/yacc/testdata/expr/README b/src/cmd/yacc/testdata/expr/README
new file mode 100644
index 000000000..302ef57a7
--- /dev/null
+++ b/src/cmd/yacc/testdata/expr/README
@@ -0,0 +1,20 @@
+This directory contains a simple program demonstrating how to use
+the Go version of yacc.
+
+To build it:
+
+ $ go generate
+ $ go build
+
+or
+
+ $ go generate
+ $ go run expr.go
+
+The file main.go contains the "go generate" command to run yacc to
+create expr.go from expr.y. It also has the package doc comment,
+as godoc will not scan the .y file.
+
+The actual implementation is in expr.y.
+
+The program is not installed in the binary distributions of Go.
diff --git a/src/cmd/yacc/expr.y b/src/cmd/yacc/testdata/expr/expr.y
index 77e9259da..721b1c917 100644
--- a/src/cmd/yacc/expr.y
+++ b/src/cmd/yacc/testdata/expr/expr.y
@@ -11,11 +11,6 @@
%{
-// This tag will be copied to the generated file to prevent that file
-// confusing a future build.
-
-// +build ignore
-
package main
import (
@@ -37,6 +32,8 @@ import (
%type <num> expr expr1 expr2 expr3
+%token '+' '-' '*' '/' '(' ')'
+
%token <num> NUM
%%
diff --git a/src/cmd/yacc/testdata/expr/main.go b/src/cmd/yacc/testdata/expr/main.go
new file mode 100644
index 000000000..8d5b6911f
--- /dev/null
+++ b/src/cmd/yacc/testdata/expr/main.go
@@ -0,0 +1,15 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file holds the go generate command to run yacc on the grammar in expr.y.
+// To build expr:
+// % go generate
+// % go build
+
+//go:generate -command yacc go tool yacc
+//go:generate yacc -o expr.go -p "expr" expr.y
+
+// Expr is a simple expression evaluator that serves as a working example of
+// how to use Go's yacc implemenation.
+package main
diff --git a/src/cmd/yacc/yacc.go b/src/cmd/yacc/yacc.go
index c53403266..4dba376fc 100644
--- a/src/cmd/yacc/yacc.go
+++ b/src/cmd/yacc/yacc.go
@@ -52,9 +52,9 @@ import (
"go/format"
"io/ioutil"
"os"
+ "strconv"
"strings"
"unicode"
- "unicode/utf8"
)
// the following are adjustable
@@ -195,8 +195,9 @@ type Item struct {
}
type Symb struct {
- name string
- value int
+ name string
+ noconst bool
+ value int
}
type Wset struct {
@@ -509,8 +510,7 @@ outer:
// put out non-literal terminals
for i := TOKSTART; i <= ntokens; i++ {
// non-literals
- c := tokset[i].name[0]
- if c != ' ' && c != '$' {
+ if !tokset[i].noconst {
fmt.Fprintf(ftable, "const %v = %v\n", tokset[i].name, tokset[i].value)
}
}
@@ -734,7 +734,7 @@ func defin(nt int, s string) int {
copy(anontrst, nontrst)
nontrst = anontrst
}
- nontrst[nnonter] = Symb{s, 0}
+ nontrst[nnonter] = Symb{name: s}
return NTBASE + nnonter
}
@@ -756,70 +756,26 @@ func defin(nt int, s string) int {
// establish value for token
// single character literal
- if s[0] == ' ' {
- s = s[1:]
- r, size := utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && size == 1 {
- errorf("invalid UTF-8 sequence %q", s)
- }
- val = int(r)
- if val == '\\' { // escape sequence
- switch {
- case len(s) == 2:
- // single character escape sequence
- switch s[1] {
- case '\'':
- val = '\''
- case '"':
- val = '"'
- case '\\':
- val = '\\'
- case 'a':
- val = '\a'
- case 'b':
- val = '\b'
- case 'f':
- val = '\f'
- case 'n':
- val = '\n'
- case 'r':
- val = '\r'
- case 't':
- val = '\t'
- case 'v':
- val = '\v'
- default:
- errorf("invalid escape %s", s)
- }
- case s[1] == 'u' && len(s) == 2+4, // \unnnn sequence
- s[1] == 'U' && len(s) == 2+8: // \Unnnnnnnn sequence
- val = 0
- s = s[2:]
- for s != "" {
- c := int(s[0])
- switch {
- case c >= '0' && c <= '9':
- c -= '0'
- case c >= 'a' && c <= 'f':
- c -= 'a' - 10
- case c >= 'A' && c <= 'F':
- c -= 'A' - 10
- default:
- errorf(`illegal \u or \U construction`)
- }
- val = val*16 + c
- s = s[1:]
- }
- default:
- errorf("invalid escape %s", s)
- }
+ if s[0] == '\'' || s[0] == '"' {
+ q, err := strconv.Unquote(s)
+ if err != nil {
+ errorf("invalid token: %s", err)
+ }
+ rq := []rune(q)
+ if len(rq) != 1 {
+ errorf("character token too long: %s", s)
}
+ val = int(rq[0])
if val == 0 {
errorf("token value 0 is illegal")
}
+ tokset[ntokens].noconst = true
} else {
val = extval
extval++
+ if s[0] == '$' {
+ tokset[ntokens].noconst = true
+ }
}
tokset[ntokens].value = val
@@ -896,7 +852,7 @@ func gettok() int {
case '"', '\'':
match = c
- tokname = " "
+ tokname = string(c)
for {
c = getrune(finput)
if c == '\n' || c == EOF {
@@ -909,6 +865,7 @@ func gettok() int {
if tokflag {
fmt.Printf(">>> IDENTIFIER \"%v\" %v\n", tokname, lineno)
}
+ tokname += string(c)
return IDENTIFIER
}
tokname += string(c)
@@ -1029,7 +986,7 @@ func fdtype(t int) int {
}
func chfind(t int, s string) int {
- if s[0] == ' ' {
+ if s[0] == '"' || s[0] == '\'' {
t = 0
}
for i := 0; i <= ntokens; i++ {
@@ -1516,9 +1473,6 @@ func symnam(i int) string {
} else {
s = tokset[i].name
}
- if s[0] == ' ' {
- s = s[1:]
- }
return s
}