github.com/benhoyt/goawk@v1.8.1/parser/parser_test.go (about) 1 // Test parser package 2 3 package parser_test 4 5 import ( 6 "fmt" 7 "strings" 8 "testing" 9 10 "github.com/benhoyt/goawk/parser" 11 ) 12 13 // NOTE: apart from TestParseAndString, the parser doesn't have 14 // extensive tests of its own; the idea is to test the parser in the 15 // interp tests. 16 17 func TestParseAndString(t *testing.T) { 18 // This program should have one of every AST element to ensure 19 // we can parse and String()ify each. 20 source := strings.TrimSpace(` 21 BEGIN { 22 print "begin one" 23 } 24 25 BEGIN { 26 print "begin two" 27 } 28 29 { 30 print "empty pattern" 31 } 32 33 $0 { 34 print "normal pattern" 35 print 1, 2, 3 36 printf "%.3f", 3.14159 37 print "x" >"file" 38 print "x" >>"append" 39 print "y" |"prog" 40 delete a[k] 41 if (c) { 42 get(a, k) 43 } 44 if (1 + 2) { 45 get(a, k) 46 } else { 47 set(a, k, v) 48 } 49 for (i = 0; i < 10; i++) { 50 print i 51 continue 52 } 53 for (k in a) { 54 break 55 } 56 while (0) { 57 print "x" 58 } 59 do { 60 print "y" 61 exit status 62 } while (x) 63 next 64 "cmd" |getline 65 "cmd" |getline x 66 getline 67 getline x 68 getline <"file" 69 getline x <"file" 70 x = 0 71 y = z = 0 72 b += 1 73 c -= 2 74 d *= 3 75 e /= 4 76 g ^= 5 77 h %= 6 78 (x ? "t" : "f") 79 ((b && c) || d) 80 (k in a) 81 ((x, y, z) in a) 82 (s ~ "foo") 83 (b < 1) 84 (c <= 2) 85 (d > 3) 86 (e >= 4) 87 (g == 5) 88 (h != 6) 89 ((x y) z) 90 ((b + c) + d) 91 ((b * c) * d) 92 ((b - c) - d) 93 ((b / c) / d) 94 (b ^ (c ^ d)) 95 x++ 96 x-- 97 ++y 98 --y 99 1234 100 1.5 101 "This is a string" 102 if (/a.b/) { 103 print "match" 104 } 105 $1 106 $(1 + 2) 107 !x 108 +x 109 -x 110 var 111 a[key] 112 a[x, y, z] 113 f() 114 set(a, k, v) 115 sub(regex, repl) 116 sub(regex, repl, s) 117 gsub(regex, repl) 118 gsub(regex, repl, s) 119 split(s, a) 120 split(s, a, regex) 121 match(s, regex) 122 rand() 123 srand() 124 srand(1) 125 length() 126 length($1) 127 sprintf("") 128 sprintf("%.3f", 3.14159) 129 sprintf("%.3f %d", 3.14159, 42) 130 cos(1) 131 sin(1) 132 exp(1) 133 log(1) 134 sqrt(1) 135 int("42") 136 tolower("FOO") 137 toupper("foo") 138 system("ls") 139 close("file") 140 atan2(x, y) 141 index(haystack, needle) 142 { 143 print "block statement" 144 f() 145 } 146 } 147 148 (NR == 1), (NR == 2) { 149 print "range pattern" 150 } 151 152 ($1 == "foo") 153 154 END { 155 print "end one" 156 } 157 158 END { 159 print "end two" 160 } 161 162 function f() { 163 } 164 165 function get(a, k) { 166 return a[k] 167 } 168 169 function set(a, k, v) { 170 a[k] = v 171 return 172 } 173 `) 174 prog, err := parser.ParseProgram([]byte(source), nil) 175 if err != nil { 176 t.Fatalf("error parsing program: %v", err) 177 } 178 progStr := prog.String() 179 if progStr != source { 180 t.Fatalf("expected first, got second:\n%s\n----------\n%s", source, progStr) 181 } 182 } 183 184 func Example_valid() { 185 prog, err := parser.ParseProgram([]byte("$0 { print $1 }"), nil) 186 if err != nil { 187 fmt.Println(err) 188 } else { 189 fmt.Println(prog) 190 } 191 // Output: 192 // $0 { 193 // print $1 194 // } 195 } 196 197 func Example_error() { 198 prog, err := parser.ParseProgram([]byte("{ for if }"), nil) 199 if err != nil { 200 fmt.Println(err) 201 } else { 202 fmt.Println(prog) 203 } 204 // Output: 205 // parse error at 1:7: expected ( instead of if 206 }