Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / cmd / goyacc / testdata / expr / expr.y
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This is an example of a goyacc program.
6 // To build it:
7 // goyacc -p "expr" expr.y (produces y.go)
8 // go build -o expr y.go
9 // expr
10 // > <type an expression>
11
12 %{
13
14 package main
15
16 import (
17         "bufio"
18         "bytes"
19         "fmt"
20         "io"
21         "log"
22         "math/big"
23         "os"
24         "unicode/utf8"
25 )
26
27 %}
28
29 %union {
30         num *big.Rat
31 }
32
33 %type   <num>   expr expr1 expr2 expr3
34
35 %token '+' '-' '*' '/' '(' ')'
36
37 %token  <num>   NUM
38
39 %%
40
41 top:
42         expr
43         {
44                 if $1.IsInt() {
45                         fmt.Println($1.Num().String())
46                 } else {
47                         fmt.Println($1.String())
48                 }
49         }
50
51 expr:
52         expr1
53 |       '+' expr
54         {
55                 $$ = $2
56         }
57 |       '-' expr
58         {
59                 $$ = $2.Neg($2)
60         }
61
62 expr1:
63         expr2
64 |       expr1 '+' expr2
65         {
66                 $$ = $1.Add($1, $3)
67         }
68 |       expr1 '-' expr2
69         {
70                 $$ = $1.Sub($1, $3)
71         }
72
73 expr2:
74         expr3
75 |       expr2 '*' expr3
76         {
77                 $$ = $1.Mul($1, $3)
78         }
79 |       expr2 '/' expr3
80         {
81                 $$ = $1.Quo($1, $3)
82         }
83
84 expr3:
85         NUM
86 |       '(' expr ')'
87         {
88                 $$ = $2
89         }
90
91
92 %%
93
94 // The parser expects the lexer to return 0 on EOF.  Give it a name
95 // for clarity.
96 const eof = 0
97
98 // The parser uses the type <prefix>Lex as a lexer. It must provide
99 // the methods Lex(*<prefix>SymType) int and Error(string).
100 type exprLex struct {
101         line []byte
102         peek rune
103 }
104
105 // The parser calls this method to get each new token. This
106 // implementation returns operators and NUM.
107 func (x *exprLex) Lex(yylval *exprSymType) int {
108         for {
109                 c := x.next()
110                 switch c {
111                 case eof:
112                         return eof
113                 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
114                         return x.num(c, yylval)
115                 case '+', '-', '*', '/', '(', ')':
116                         return int(c)
117
118                 // Recognize Unicode multiplication and division
119                 // symbols, returning what the parser expects.
120                 case '×':
121                         return '*'
122                 case '÷':
123                         return '/'
124
125                 case ' ', '\t', '\n', '\r':
126                 default:
127                         log.Printf("unrecognized character %q", c)
128                 }
129         }
130 }
131
132 // Lex a number.
133 func (x *exprLex) num(c rune, yylval *exprSymType) int {
134         add := func(b *bytes.Buffer, c rune) {
135                 if _, err := b.WriteRune(c); err != nil {
136                         log.Fatalf("WriteRune: %s", err)
137                 }
138         }
139         var b bytes.Buffer
140         add(&b, c)
141         L: for {
142                 c = x.next()
143                 switch c {
144                 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E':
145                         add(&b, c)
146                 default:
147                         break L
148                 }
149         }
150         if c != eof {
151                 x.peek = c
152         }
153         yylval.num = &big.Rat{}
154         _, ok := yylval.num.SetString(b.String())
155         if !ok {
156                 log.Printf("bad number %q", b.String())
157                 return eof
158         }
159         return NUM
160 }
161
162 // Return the next rune for the lexer.
163 func (x *exprLex) next() rune {
164         if x.peek != eof {
165                 r := x.peek
166                 x.peek = eof
167                 return r
168         }
169         if len(x.line) == 0 {
170                 return eof
171         }
172         c, size := utf8.DecodeRune(x.line)
173         x.line = x.line[size:]
174         if c == utf8.RuneError && size == 1 {
175                 log.Print("invalid utf8")
176                 return x.next()
177         }
178         return c
179 }
180
181 // The parser calls this method on a parse error.
182 func (x *exprLex) Error(s string) {
183         log.Printf("parse error: %s", s)
184 }
185
186 func main() {
187         in := bufio.NewReader(os.Stdin)
188         for {
189                 if _, err := os.Stdout.WriteString("> "); err != nil {
190                         log.Fatalf("WriteString: %s", err)
191                 }
192                 line, err := in.ReadBytes('\n')
193                 if err == io.EOF {
194                         return
195                 }
196                 if err != nil {
197                         log.Fatalf("ReadBytes: %s", err)
198                 }
199
200                 exprParse(&exprLex{line: line})
201         }
202 }