1 | // Copyright 2019 The CC 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 | package cc // import "modernc.org/cc/v3"
|
---|
6 |
|
---|
7 | import (
|
---|
8 | "bytes"
|
---|
9 | "fmt"
|
---|
10 | "hash/maphash"
|
---|
11 | "strings"
|
---|
12 | )
|
---|
13 |
|
---|
14 | const (
|
---|
15 | unicodePrivateAreaFirst = 0xe000
|
---|
16 | unicodePrivateAreaLast = 0xf8ff
|
---|
17 | )
|
---|
18 |
|
---|
19 | var (
|
---|
20 | noDeclSpecs = &DeclarationSpecifiers{}
|
---|
21 | panicOnParserError bool //TODOOK
|
---|
22 |
|
---|
23 | idChar = dict.sid("char")
|
---|
24 | idComma = dict.sid(",")
|
---|
25 | idConst = dict.sid("const")
|
---|
26 | idEq = dict.sid("=")
|
---|
27 | idFFlush = dict.sid("fflush")
|
---|
28 | idFprintf = dict.sid("fprintf")
|
---|
29 | idFunc = dict.sid("__func__")
|
---|
30 | idLBracket = dict.sid("[")
|
---|
31 | idLParen = dict.sid("(")
|
---|
32 | idRBracket = dict.sid("]")
|
---|
33 | idRParen = dict.sid(")")
|
---|
34 | idSemicolon = dict.sid(";")
|
---|
35 | idStatic = dict.sid("static")
|
---|
36 | idStderr = dict.sid("stderr")
|
---|
37 | )
|
---|
38 |
|
---|
39 | // Values of Token.Rune for lexemes.
|
---|
40 | const (
|
---|
41 | _ = iota + unicodePrivateAreaFirst //TODOOK
|
---|
42 |
|
---|
43 | ACCUM // _Accum
|
---|
44 | ADDASSIGN // +=
|
---|
45 | ALIGNAS // _Alignas
|
---|
46 | ALIGNOF // _Alignof
|
---|
47 | ANDAND // &&
|
---|
48 | ANDASSIGN // &=
|
---|
49 | ARROW // ->
|
---|
50 | ASM // __asm__
|
---|
51 | ATOMIC // _Atomic
|
---|
52 | ATTRIBUTE // __attribute__
|
---|
53 | AUTO // auto
|
---|
54 | BOOL // _Bool
|
---|
55 | BREAK // break
|
---|
56 | BUILTINCHOOSEEXPR // __builtin_choose_expr
|
---|
57 | BUILTINTYPESCOMPATIBLE // __builtin_types_compatible_p
|
---|
58 | CASE // case
|
---|
59 | CHAR // char
|
---|
60 | CHARCONST // 'a'
|
---|
61 | COMPLEX // _Complex
|
---|
62 | CONST // const
|
---|
63 | CONTINUE // continue
|
---|
64 | DDD // ...
|
---|
65 | DEC // --
|
---|
66 | DECIMAL128 // _Decimal128
|
---|
67 | DECIMAL32 // _Decimal32
|
---|
68 | DECIMAL64 // _Decimal64
|
---|
69 | DEFAULT // default
|
---|
70 | DIVASSIGN // /=
|
---|
71 | DO // do
|
---|
72 | DOUBLE // double
|
---|
73 | ELSE // else
|
---|
74 | ENUM // enum
|
---|
75 | ENUMCONST // foo in enum x { foo, bar };
|
---|
76 | EQ // ==
|
---|
77 | EXTERN // extern
|
---|
78 | FLOAT // float
|
---|
79 | FLOAT128 // _Float128
|
---|
80 | FLOAT16 // __fp16
|
---|
81 | FLOAT32 // _Float32
|
---|
82 | FLOAT32X // _Float32x
|
---|
83 | FLOAT64 // _Float64
|
---|
84 | FLOAT64X // _Float64x
|
---|
85 | FLOAT80 // __float80
|
---|
86 | FLOATCONST // 1.23
|
---|
87 | FOR // for
|
---|
88 | FRACT // _Fract
|
---|
89 | GEQ // >=
|
---|
90 | GOTO // goto
|
---|
91 | IDENTIFIER // foo
|
---|
92 | IF // if
|
---|
93 | IMAG // __imag__
|
---|
94 | INC // ++
|
---|
95 | INLINE // inline
|
---|
96 | INT // int
|
---|
97 | INT8 // __int8
|
---|
98 | INT16 // __int16
|
---|
99 | INT32 // __int32
|
---|
100 | INT64 // __int64
|
---|
101 | INT128 // __int128
|
---|
102 | INTCONST // 42
|
---|
103 | LABEL // __label__
|
---|
104 | LEQ // <=
|
---|
105 | LONG // long
|
---|
106 | LONGCHARCONST // L'a'
|
---|
107 | LONGSTRINGLITERAL // L"foo"
|
---|
108 | LSH // <<
|
---|
109 | LSHASSIGN // <<=
|
---|
110 | MODASSIGN // %=
|
---|
111 | MULASSIGN // *=
|
---|
112 | NEQ // !=
|
---|
113 | NORETURN // _Noreturn
|
---|
114 | ORASSIGN // |=
|
---|
115 | OROR // ||
|
---|
116 | PPNUMBER // .32e.
|
---|
117 | PPPASTE // ##
|
---|
118 | PRAGMASTDC // __pragma_stdc
|
---|
119 | REAL // __real__
|
---|
120 | REGISTER // register
|
---|
121 | RESTRICT // restrict
|
---|
122 | RETURN // return
|
---|
123 | RSH // >>
|
---|
124 | RSHASSIGN // >>=
|
---|
125 | SAT // _Sat
|
---|
126 | SHORT // short
|
---|
127 | SIGNED // signed
|
---|
128 | SIZEOF // sizeof
|
---|
129 | STATIC // static
|
---|
130 | STRINGLITERAL // "foo"
|
---|
131 | STRUCT // struct
|
---|
132 | SUBASSIGN // -=
|
---|
133 | SWITCH // switch
|
---|
134 | THREADLOCAL // _Thread_local
|
---|
135 | TYPEDEF // typedef
|
---|
136 | TYPEDEFNAME // int_t in typedef int int_t;
|
---|
137 | TYPEOF // typeof
|
---|
138 | UNION // union
|
---|
139 | UNSIGNED // unsigned
|
---|
140 | VOID // void
|
---|
141 | VOLATILE // volatile
|
---|
142 | WHILE // while
|
---|
143 | XORASSIGN // ^=
|
---|
144 |
|
---|
145 | lastTok
|
---|
146 | )
|
---|
147 |
|
---|
148 | var (
|
---|
149 | tokNames = map[rune]StringID{
|
---|
150 | ACCUM: dict.sid("ACCUM"),
|
---|
151 | ADDASSIGN: dict.sid("ADDASSIGN"),
|
---|
152 | ALIGNAS: dict.sid("ALIGNAS"),
|
---|
153 | ALIGNOF: dict.sid("ALIGNOF"),
|
---|
154 | ANDAND: dict.sid("ANDAND"),
|
---|
155 | ANDASSIGN: dict.sid("ANDASSIGN"),
|
---|
156 | ARROW: dict.sid("ARROW"),
|
---|
157 | ASM: dict.sid("ASM"),
|
---|
158 | ATOMIC: dict.sid("ATOMIC"),
|
---|
159 | ATTRIBUTE: dict.sid("ATTRIBUTE"),
|
---|
160 | AUTO: dict.sid("AUTO"),
|
---|
161 | BOOL: dict.sid("BOOL"),
|
---|
162 | BREAK: dict.sid("BREAK"),
|
---|
163 | BUILTINCHOOSEEXPR: dict.sid("BUILTINCHOOSEEXPR"),
|
---|
164 | BUILTINTYPESCOMPATIBLE: dict.sid("BUILTINTYPESCOMPATIBLE"),
|
---|
165 | CASE: dict.sid("CASE"),
|
---|
166 | CHAR: dict.sid("CHAR"),
|
---|
167 | CHARCONST: dict.sid("CHARCONST"),
|
---|
168 | COMPLEX: dict.sid("COMPLEX"),
|
---|
169 | CONST: dict.sid("CONST"),
|
---|
170 | CONTINUE: dict.sid("CONTINUE"),
|
---|
171 | DDD: dict.sid("DDD"),
|
---|
172 | DEC: dict.sid("DEC"),
|
---|
173 | DECIMAL128: dict.sid("DECIMAL128"),
|
---|
174 | DECIMAL32: dict.sid("DECIMAL32"),
|
---|
175 | DECIMAL64: dict.sid("DECIMAL64"),
|
---|
176 | DEFAULT: dict.sid("DEFAULT"),
|
---|
177 | DIVASSIGN: dict.sid("DIVASSIGN"),
|
---|
178 | DO: dict.sid("DO"),
|
---|
179 | DOUBLE: dict.sid("DOUBLE"),
|
---|
180 | ELSE: dict.sid("ELSE"),
|
---|
181 | ENUM: dict.sid("ENUM"),
|
---|
182 | ENUMCONST: dict.sid("ENUMCONST"),
|
---|
183 | EQ: dict.sid("EQ"),
|
---|
184 | EXTERN: dict.sid("EXTERN"),
|
---|
185 | FLOAT128: dict.sid("FLOAT128"),
|
---|
186 | FLOAT16: dict.sid("FLOAT16"),
|
---|
187 | FLOAT32: dict.sid("FLOAT32"),
|
---|
188 | FLOAT32X: dict.sid("FLOAT32X"),
|
---|
189 | FLOAT64: dict.sid("FLOAT64"),
|
---|
190 | FLOAT64X: dict.sid("FLOAT64X"),
|
---|
191 | FLOAT80: dict.sid("FLOAT80"),
|
---|
192 | FLOAT: dict.sid("FLOAT"),
|
---|
193 | FLOATCONST: dict.sid("FLOATCONST"),
|
---|
194 | FOR: dict.sid("FOR"),
|
---|
195 | FRACT: dict.sid("FRACT"),
|
---|
196 | GEQ: dict.sid("GEQ"),
|
---|
197 | GOTO: dict.sid("GOTO"),
|
---|
198 | IDENTIFIER: dict.sid("IDENTIFIER"),
|
---|
199 | IF: dict.sid("IF"),
|
---|
200 | IMAG: dict.sid("IMAG"),
|
---|
201 | INC: dict.sid("INC"),
|
---|
202 | INLINE: dict.sid("INLINE"),
|
---|
203 | INT8: dict.sid("INT8"),
|
---|
204 | INT16: dict.sid("INT16"),
|
---|
205 | INT32: dict.sid("INT32"),
|
---|
206 | INT64: dict.sid("INT64"),
|
---|
207 | INT128: dict.sid("INT128"),
|
---|
208 | INT: dict.sid("INT"),
|
---|
209 | INTCONST: dict.sid("INTCONST"),
|
---|
210 | LABEL: dict.sid("LABEL"),
|
---|
211 | LEQ: dict.sid("LEQ"),
|
---|
212 | LONG: dict.sid("LONG"),
|
---|
213 | LONGCHARCONST: dict.sid("LONGCHARCONST"),
|
---|
214 | LONGSTRINGLITERAL: dict.sid("LONGSTRINGLITERAL"),
|
---|
215 | LSH: dict.sid("LSH"),
|
---|
216 | LSHASSIGN: dict.sid("LSHASSIGN"),
|
---|
217 | MODASSIGN: dict.sid("MODASSIGN"),
|
---|
218 | MULASSIGN: dict.sid("MULASSIGN"),
|
---|
219 | NEQ: dict.sid("NEQ"),
|
---|
220 | NORETURN: dict.sid("NORETURN"),
|
---|
221 | ORASSIGN: dict.sid("ORASSIGN"),
|
---|
222 | OROR: dict.sid("OROR"),
|
---|
223 | PPNUMBER: dict.sid("PPNUMBER"),
|
---|
224 | PPPASTE: dict.sid("PPPASTE"),
|
---|
225 | PRAGMASTDC: dict.sid("PPPRAGMASTDC"),
|
---|
226 | REAL: dict.sid("REAL"),
|
---|
227 | REGISTER: dict.sid("REGISTER"),
|
---|
228 | RESTRICT: dict.sid("RESTRICT"),
|
---|
229 | RETURN: dict.sid("RETURN"),
|
---|
230 | RSH: dict.sid("RSH"),
|
---|
231 | RSHASSIGN: dict.sid("RSHASSIGN"),
|
---|
232 | SAT: dict.sid("SAT"),
|
---|
233 | SHORT: dict.sid("SHORT"),
|
---|
234 | SIGNED: dict.sid("SIGNED"),
|
---|
235 | SIZEOF: dict.sid("SIZEOF"),
|
---|
236 | STATIC: dict.sid("STATIC"),
|
---|
237 | STRINGLITERAL: dict.sid("STRINGLITERAL"),
|
---|
238 | STRUCT: dict.sid("STRUCT"),
|
---|
239 | SUBASSIGN: dict.sid("SUBASSIGN"),
|
---|
240 | SWITCH: dict.sid("SWITCH"),
|
---|
241 | THREADLOCAL: dict.sid("THREADLOCAL"),
|
---|
242 | TYPEDEF: dict.sid("TYPEDEF"),
|
---|
243 | TYPEDEFNAME: dict.sid("TYPEDEFNAME"),
|
---|
244 | TYPEOF: dict.sid("TYPEOF"),
|
---|
245 | UNION: dict.sid("UNION"),
|
---|
246 | UNSIGNED: dict.sid("UNSIGNED"),
|
---|
247 | VOID: dict.sid("VOID"),
|
---|
248 | VOLATILE: dict.sid("VOLATILE"),
|
---|
249 | WHILE: dict.sid("WHILE"),
|
---|
250 | XORASSIGN: dict.sid("XORASSIGN"),
|
---|
251 | }
|
---|
252 |
|
---|
253 | keywords = map[StringID]rune{
|
---|
254 |
|
---|
255 | // [0], 6.4.1
|
---|
256 | dict.sid("auto"): AUTO,
|
---|
257 | dict.sid("break"): BREAK,
|
---|
258 | dict.sid("case"): CASE,
|
---|
259 | dict.sid("char"): CHAR,
|
---|
260 | dict.sid("const"): CONST,
|
---|
261 | dict.sid("continue"): CONTINUE,
|
---|
262 | dict.sid("default"): DEFAULT,
|
---|
263 | dict.sid("do"): DO,
|
---|
264 | dict.sid("double"): DOUBLE,
|
---|
265 | dict.sid("else"): ELSE,
|
---|
266 | dict.sid("enum"): ENUM,
|
---|
267 | dict.sid("extern"): EXTERN,
|
---|
268 | dict.sid("float"): FLOAT,
|
---|
269 | dict.sid("for"): FOR,
|
---|
270 | dict.sid("goto"): GOTO,
|
---|
271 | dict.sid("if"): IF,
|
---|
272 | dict.sid("inline"): INLINE,
|
---|
273 | dict.sid("int"): INT,
|
---|
274 | dict.sid("long"): LONG,
|
---|
275 | dict.sid("register"): REGISTER,
|
---|
276 | dict.sid("restrict"): RESTRICT,
|
---|
277 | dict.sid("return"): RETURN,
|
---|
278 | dict.sid("short"): SHORT,
|
---|
279 | dict.sid("signed"): SIGNED,
|
---|
280 | dict.sid("sizeof"): SIZEOF,
|
---|
281 | dict.sid("static"): STATIC,
|
---|
282 | dict.sid("struct"): STRUCT,
|
---|
283 | dict.sid("switch"): SWITCH,
|
---|
284 | dict.sid("typedef"): TYPEDEF,
|
---|
285 | dict.sid("union"): UNION,
|
---|
286 | dict.sid("unsigned"): UNSIGNED,
|
---|
287 | dict.sid("void"): VOID,
|
---|
288 | dict.sid("volatile"): VOLATILE,
|
---|
289 | dict.sid("while"): WHILE,
|
---|
290 |
|
---|
291 | dict.sid("_Alignas"): ALIGNAS,
|
---|
292 | dict.sid("_Alignof"): ALIGNOF,
|
---|
293 | dict.sid("_Atomic"): ATOMIC,
|
---|
294 | dict.sid("_Bool"): BOOL,
|
---|
295 | dict.sid("_Complex"): COMPLEX,
|
---|
296 | dict.sid("_Noreturn"): NORETURN,
|
---|
297 | dict.sid("_Thread_local"): THREADLOCAL,
|
---|
298 | dict.sid("__alignof"): ALIGNOF,
|
---|
299 | dict.sid("__alignof__"): ALIGNOF,
|
---|
300 | dict.sid("__asm"): ASM,
|
---|
301 | dict.sid("__asm__"): ASM,
|
---|
302 | dict.sid("__attribute"): ATTRIBUTE,
|
---|
303 | dict.sid("__attribute__"): ATTRIBUTE,
|
---|
304 | dict.sid("__complex"): COMPLEX,
|
---|
305 | dict.sid("__complex__"): COMPLEX,
|
---|
306 | dict.sid("__const"): CONST,
|
---|
307 | dict.sid("__inline"): INLINE,
|
---|
308 | dict.sid("__inline__"): INLINE,
|
---|
309 | dict.sid("__int16"): INT16,
|
---|
310 | dict.sid("__int32"): INT32,
|
---|
311 | dict.sid("__int64"): INT64,
|
---|
312 | dict.sid("__int8"): INT8,
|
---|
313 | dict.sid("__pragma_stdc"): PRAGMASTDC,
|
---|
314 | dict.sid("__restrict"): RESTRICT,
|
---|
315 | dict.sid("__restrict__"): RESTRICT,
|
---|
316 | dict.sid("__signed"): SIGNED,
|
---|
317 | dict.sid("__signed__"): SIGNED,
|
---|
318 | dict.sid("__thread"): THREADLOCAL,
|
---|
319 | dict.sid("__typeof"): TYPEOF,
|
---|
320 | dict.sid("__typeof__"): TYPEOF,
|
---|
321 | dict.sid("__volatile"): VOLATILE,
|
---|
322 | dict.sid("__volatile__"): VOLATILE,
|
---|
323 | dict.sid("typeof"): TYPEOF,
|
---|
324 | }
|
---|
325 |
|
---|
326 | gccKeywords = map[StringID]rune{
|
---|
327 | dict.sid("_Accum"): ACCUM,
|
---|
328 | dict.sid("_Decimal128"): DECIMAL128,
|
---|
329 | dict.sid("_Decimal32"): DECIMAL32,
|
---|
330 | dict.sid("_Decimal64"): DECIMAL64,
|
---|
331 | dict.sid("_Float128"): FLOAT128,
|
---|
332 | dict.sid("_Float16"): FLOAT16,
|
---|
333 | dict.sid("_Float32"): FLOAT32,
|
---|
334 | dict.sid("_Float32x"): FLOAT32X,
|
---|
335 | dict.sid("_Float64"): FLOAT64,
|
---|
336 | dict.sid("_Float64x"): FLOAT64X,
|
---|
337 | dict.sid("_Fract"): FRACT,
|
---|
338 | dict.sid("_Sat"): SAT,
|
---|
339 | dict.sid("__builtin_choose_expr"): BUILTINCHOOSEEXPR,
|
---|
340 | dict.sid("__builtin_types_compatible_p"): BUILTINTYPESCOMPATIBLE,
|
---|
341 | dict.sid("__float80"): FLOAT80,
|
---|
342 | dict.sid("__fp16"): FLOAT16,
|
---|
343 | dict.sid("__imag"): IMAG,
|
---|
344 | dict.sid("__imag__"): IMAG,
|
---|
345 | dict.sid("__int128"): INT128,
|
---|
346 | dict.sid("__label__"): LABEL,
|
---|
347 | dict.sid("__real"): REAL,
|
---|
348 | dict.sid("__real__"): REAL,
|
---|
349 | }
|
---|
350 | )
|
---|
351 |
|
---|
352 | func init() {
|
---|
353 | for r := rune(0xe001); r < lastTok; r++ {
|
---|
354 | if _, ok := tokNames[r]; !ok {
|
---|
355 | panic(internalError())
|
---|
356 | }
|
---|
357 | }
|
---|
358 | for k, v := range keywords {
|
---|
359 | gccKeywords[k] = v
|
---|
360 | }
|
---|
361 | }
|
---|
362 |
|
---|
363 | func tokName(r rune) string {
|
---|
364 | switch {
|
---|
365 | case r < 0:
|
---|
366 | return "<EOF>"
|
---|
367 | case r >= unicodePrivateAreaFirst && r <= unicodePrivateAreaLast:
|
---|
368 | return tokNames[r].String()
|
---|
369 | default:
|
---|
370 | return fmt.Sprintf("%+q", r)
|
---|
371 | }
|
---|
372 | }
|
---|
373 |
|
---|
374 | type parser struct {
|
---|
375 | block *CompoundStatement
|
---|
376 | ctx *context
|
---|
377 | currFn *FunctionDefinition
|
---|
378 | declScope Scope
|
---|
379 | fileScope Scope
|
---|
380 | hash *maphash.Hash
|
---|
381 | in chan *[]Token
|
---|
382 | inBuf []Token
|
---|
383 | inBufp *[]Token
|
---|
384 | key sharedFunctionDefinitionKey
|
---|
385 | prev Token
|
---|
386 | resolveScope Scope
|
---|
387 | resolvedIn Scope // Typedef name
|
---|
388 | scopes int
|
---|
389 | sepLen int
|
---|
390 | seps []StringID
|
---|
391 | strcatLen int
|
---|
392 | strcats []StringID
|
---|
393 | switches int
|
---|
394 |
|
---|
395 | tok Token
|
---|
396 |
|
---|
397 | closed bool
|
---|
398 | errored bool
|
---|
399 | ignoreKeywords bool
|
---|
400 | typedefNameEnabled bool
|
---|
401 | }
|
---|
402 |
|
---|
403 | func newParser(ctx *context, in chan *[]Token) *parser {
|
---|
404 | s := Scope{}
|
---|
405 | var hash *maphash.Hash
|
---|
406 | if s := ctx.cfg.SharedFunctionDefinitions; s != nil {
|
---|
407 | hash = &s.hash
|
---|
408 | }
|
---|
409 | return &parser{
|
---|
410 | ctx: ctx,
|
---|
411 | declScope: s,
|
---|
412 | fileScope: s,
|
---|
413 | hash: hash,
|
---|
414 | in: in,
|
---|
415 | resolveScope: s,
|
---|
416 | }
|
---|
417 | }
|
---|
418 |
|
---|
419 | func (p *parser) openScope(skip bool) {
|
---|
420 | p.scopes++
|
---|
421 | p.declScope = p.declScope.new()
|
---|
422 | if skip {
|
---|
423 | p.declScope[scopeSkip] = nil
|
---|
424 | }
|
---|
425 | p.resolveScope = p.declScope
|
---|
426 | // var a []string
|
---|
427 | // for s := p.declScope; s != nil; s = s.Parent() {
|
---|
428 | // a = append(a, fmt.Sprintf("%p", s))
|
---|
429 | // }
|
---|
430 | // trc("openScope(%v) %p: %v", skip, p.declScope, strings.Join(a, " "))
|
---|
431 | }
|
---|
432 |
|
---|
433 | func (p *parser) closeScope() {
|
---|
434 | // declScope := p.declScope
|
---|
435 | p.declScope = p.declScope.Parent()
|
---|
436 | p.resolveScope = p.declScope
|
---|
437 | p.scopes--
|
---|
438 | // var a []string
|
---|
439 | // for s := p.declScope; s != nil; s = s.Parent() {
|
---|
440 | // a = append(a, fmt.Sprintf("%p", s))
|
---|
441 | // }
|
---|
442 | // trc("%p.closeScope %v", declScope, strings.Join(a, " "))
|
---|
443 | }
|
---|
444 |
|
---|
445 | func (p *parser) err0(consume bool, msg string, args ...interface{}) {
|
---|
446 | if panicOnParserError { //TODOOK
|
---|
447 | s := fmt.Sprintf("FAIL: "+msg, args...)
|
---|
448 | panic(fmt.Sprintf("%s\n%s: ", s, PrettyString(p.tok))) //TODOOK
|
---|
449 | }
|
---|
450 | // s := fmt.Sprintf("FAIL: "+p.tok.Position().String()+": "+msg, args...)
|
---|
451 | // caller("%s: %s: ", s, PrettyString(p.tok))
|
---|
452 | p.errored = true
|
---|
453 | if consume {
|
---|
454 | p.tok.Rune = 0
|
---|
455 | }
|
---|
456 | if p.ctx.err(p.tok.Position(), "`%s`: "+msg, append([]interface{}{p.tok}, args...)...) {
|
---|
457 | p.closed = true
|
---|
458 | }
|
---|
459 | }
|
---|
460 |
|
---|
461 | func (p *parser) err(msg string, args ...interface{}) { p.err0(true, msg, args...) }
|
---|
462 |
|
---|
463 | func (p *parser) rune() rune {
|
---|
464 | if p.tok.Rune == 0 {
|
---|
465 | p.next()
|
---|
466 | }
|
---|
467 | return p.tok.Rune
|
---|
468 | }
|
---|
469 |
|
---|
470 | func (p *parser) shift() (r Token) {
|
---|
471 | if p.tok.Rune == 0 {
|
---|
472 | p.next()
|
---|
473 | }
|
---|
474 | r = p.tok
|
---|
475 | p.tok.Rune = 0
|
---|
476 | // dbg("", shift(r))
|
---|
477 | return r
|
---|
478 | }
|
---|
479 |
|
---|
480 | func (p *parser) unget(toks ...Token) { //TODO injected __func__ has two trailing semicolons, why?
|
---|
481 | p.inBuf = append(toks, p.inBuf...)
|
---|
482 | // fmt.Printf("unget %q\n", tokStr(toks, "|")) //TODO-
|
---|
483 | }
|
---|
484 |
|
---|
485 | func (p *parser) peek(handleTypedefname bool) rune {
|
---|
486 | if p.closed {
|
---|
487 | return -1
|
---|
488 | }
|
---|
489 |
|
---|
490 | if len(p.inBuf) == 0 {
|
---|
491 | if p.inBufp != nil {
|
---|
492 | tokenPool.Put(p.inBufp)
|
---|
493 | }
|
---|
494 | var ok bool
|
---|
495 | if p.inBufp, ok = <-p.in; !ok {
|
---|
496 | // dbg("parser: EOF")
|
---|
497 | return -1
|
---|
498 | }
|
---|
499 |
|
---|
500 | p.inBuf = *p.inBufp
|
---|
501 | // dbg("parser receives: %q", tokStr(p.inBuf, "|"))
|
---|
502 | // fmt.Printf("parser receives %v: %q\n", p.inBuf[0].Position(), tokStr(p.inBuf, "|")) //TODO-
|
---|
503 | }
|
---|
504 | tok := p.inBuf[0]
|
---|
505 | r := tok.Rune
|
---|
506 | if r == IDENTIFIER {
|
---|
507 | if x, ok := p.ctx.keywords[p.inBuf[0].Value]; ok && !p.ignoreKeywords {
|
---|
508 | return x
|
---|
509 | }
|
---|
510 |
|
---|
511 | if handleTypedefname {
|
---|
512 | nm := tok.Value
|
---|
513 | seq := tok.seq
|
---|
514 | for s := p.resolveScope; s != nil; s = s.Parent() {
|
---|
515 | for _, v := range s[nm] {
|
---|
516 | switch x := v.(type) {
|
---|
517 | case *Declarator:
|
---|
518 | if !x.isVisible(seq) {
|
---|
519 | continue
|
---|
520 | }
|
---|
521 |
|
---|
522 | if x.IsTypedefName && p.peek(false) != ':' {
|
---|
523 | return TYPEDEFNAME
|
---|
524 | }
|
---|
525 |
|
---|
526 | return IDENTIFIER
|
---|
527 | case *Enumerator:
|
---|
528 | return IDENTIFIER
|
---|
529 | case *EnumSpecifier, *StructOrUnionSpecifier, *StructDeclarator, *LabeledStatement:
|
---|
530 | // nop
|
---|
531 | default:
|
---|
532 | panic(internalErrorf("%T", x))
|
---|
533 | }
|
---|
534 | }
|
---|
535 | }
|
---|
536 | }
|
---|
537 | }
|
---|
538 | return r
|
---|
539 | }
|
---|
540 |
|
---|
541 | func (p *parser) next() {
|
---|
542 | if p.closed {
|
---|
543 | // dbg("parser: EOF")
|
---|
544 | p.tok.Rune = -1
|
---|
545 | return
|
---|
546 | }
|
---|
547 |
|
---|
548 | more:
|
---|
549 | if len(p.inBuf) == 0 {
|
---|
550 | if p.inBufp != nil {
|
---|
551 | tokenPool.Put(p.inBufp)
|
---|
552 | }
|
---|
553 | var ok bool
|
---|
554 | if p.inBufp, ok = <-p.in; !ok {
|
---|
555 | // dbg("parser: EOF")
|
---|
556 | p.closed = true
|
---|
557 | p.tok.Rune = -1
|
---|
558 | return
|
---|
559 | }
|
---|
560 |
|
---|
561 | p.inBuf = *p.inBufp
|
---|
562 | // dbg("parser receives: %q", tokStr(p.inBuf, "|"))
|
---|
563 | // fmt.Printf("parser receives %v: %q\n", p.inBuf[0].Position(), tokStr(p.inBuf, "|")) //TODO-
|
---|
564 | }
|
---|
565 | p.tok = p.inBuf[0]
|
---|
566 | switch p.tok.Rune {
|
---|
567 | case STRINGLITERAL, LONGSTRINGLITERAL:
|
---|
568 | switch p.prev.Rune {
|
---|
569 | case STRINGLITERAL, LONGSTRINGLITERAL:
|
---|
570 | p.strcatLen += len(p.tok.Value.String())
|
---|
571 | p.strcats = append(p.strcats, p.tok.Value)
|
---|
572 | p.sepLen += len(p.tok.Sep.String())
|
---|
573 | p.seps = append(p.seps, p.tok.Sep)
|
---|
574 | p.inBuf = p.inBuf[1:]
|
---|
575 | goto more
|
---|
576 | default:
|
---|
577 | p.strcatLen = len(p.tok.Value.String())
|
---|
578 | p.strcats = []StringID{p.tok.Value}
|
---|
579 | p.sepLen = len(p.tok.Sep.String())
|
---|
580 | p.seps = []StringID{p.tok.Sep}
|
---|
581 | p.prev = p.tok
|
---|
582 | p.inBuf = p.inBuf[1:]
|
---|
583 | goto more
|
---|
584 | }
|
---|
585 | default:
|
---|
586 | switch p.prev.Rune {
|
---|
587 | case STRINGLITERAL, LONGSTRINGLITERAL:
|
---|
588 | p.tok = p.prev
|
---|
589 | var b bytes.Buffer
|
---|
590 | b.Grow(p.strcatLen)
|
---|
591 | for _, v := range p.strcats {
|
---|
592 | b.WriteString(v.String())
|
---|
593 | }
|
---|
594 | p.tok.Value = dict.id(b.Bytes())
|
---|
595 | b.Reset()
|
---|
596 | b.Grow(p.sepLen)
|
---|
597 | for _, v := range p.seps {
|
---|
598 | b.WriteString(v.String())
|
---|
599 | }
|
---|
600 | p.tok.Sep = dict.id(b.Bytes())
|
---|
601 | p.prev.Rune = 0
|
---|
602 | default:
|
---|
603 | p.inBuf = p.inBuf[1:]
|
---|
604 | }
|
---|
605 | }
|
---|
606 | p.resolvedIn = nil
|
---|
607 | out:
|
---|
608 | switch p.tok.Rune {
|
---|
609 | case IDENTIFIER:
|
---|
610 | nm := p.tok.Value
|
---|
611 | if x, ok := p.ctx.keywords[nm]; ok && !p.ignoreKeywords {
|
---|
612 | p.tok.Rune = x
|
---|
613 | break
|
---|
614 | }
|
---|
615 |
|
---|
616 | if p.typedefNameEnabled {
|
---|
617 | seq := p.tok.seq
|
---|
618 | // dbg("checking for typedefname in scope %p", p.resolveScope)
|
---|
619 | for s := p.resolveScope; s != nil; s = s.Parent() {
|
---|
620 | // dbg("scope %p", s)
|
---|
621 | for _, v := range s[nm] {
|
---|
622 | // dbg("%v: %T", nm, v)
|
---|
623 | switch x := v.(type) {
|
---|
624 | case *Declarator:
|
---|
625 | if !x.isVisible(seq) {
|
---|
626 | continue
|
---|
627 | }
|
---|
628 |
|
---|
629 | // dbg("", x.isVisible(pos), x.IsTypedefName)
|
---|
630 | if x.IsTypedefName && p.peek(false) != ':' {
|
---|
631 | p.tok.Rune = TYPEDEFNAME
|
---|
632 | p.resolvedIn = s
|
---|
633 | }
|
---|
634 |
|
---|
635 | p.typedefNameEnabled = false
|
---|
636 | break out
|
---|
637 | case *Enumerator:
|
---|
638 | if x.isVisible(seq) {
|
---|
639 | break out
|
---|
640 | }
|
---|
641 | case *EnumSpecifier, *StructOrUnionSpecifier, *StructDeclarator, *LabeledStatement:
|
---|
642 | // nop
|
---|
643 | default:
|
---|
644 | panic(internalError())
|
---|
645 | }
|
---|
646 | }
|
---|
647 | }
|
---|
648 | }
|
---|
649 | case PPNUMBER:
|
---|
650 | switch s := p.tok.Value.String(); {
|
---|
651 | case strings.ContainsAny(s, ".+-ijpIJP"):
|
---|
652 | p.tok.Rune = FLOATCONST
|
---|
653 | case strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X"):
|
---|
654 | p.tok.Rune = INTCONST
|
---|
655 | case strings.ContainsAny(s, "Ee"):
|
---|
656 | p.tok.Rune = FLOATCONST
|
---|
657 | default:
|
---|
658 | p.tok.Rune = INTCONST
|
---|
659 | }
|
---|
660 | }
|
---|
661 | if p.ctx.cfg.SharedFunctionDefinitions != nil {
|
---|
662 | p.hashTok()
|
---|
663 | }
|
---|
664 | // dbg("parser.next p.tok %v", PrettyString(p.tok))
|
---|
665 | // fmt.Printf("%s%s/* %s */", p.tok.Sep, p.tok.Value, tokName(p.tok.Rune)) //TODO-
|
---|
666 | }
|
---|
667 |
|
---|
668 | func (p *parser) hashTok() {
|
---|
669 | n := p.tok.Rune
|
---|
670 | for i := 0; i < 4; i++ {
|
---|
671 | p.hash.WriteByte(byte(n))
|
---|
672 | n >>= 8
|
---|
673 | }
|
---|
674 | n = int32(p.tok.Value)
|
---|
675 | for i := 0; i < 4; i++ {
|
---|
676 | p.hash.WriteByte(byte(n))
|
---|
677 | n >>= 8
|
---|
678 | }
|
---|
679 | }
|
---|
680 |
|
---|
681 | // [0], 6.5.1 Primary expressions
|
---|
682 | //
|
---|
683 | // primary-expression:
|
---|
684 | // identifier
|
---|
685 | // constant
|
---|
686 | // string-literal
|
---|
687 | // ( expression )
|
---|
688 | // ( compound-statement )
|
---|
689 | func (p *parser) primaryExpression() *PrimaryExpression {
|
---|
690 | var kind PrimaryExpressionCase
|
---|
691 | var resolvedIn Scope
|
---|
692 | var resolvedTo Node
|
---|
693 | out:
|
---|
694 | switch p.rune() {
|
---|
695 | case IDENTIFIER:
|
---|
696 | kind = PrimaryExpressionIdent
|
---|
697 | nm := p.tok.Value
|
---|
698 | seq := p.tok.seq
|
---|
699 | for s := p.resolveScope; s != nil; s = s.Parent() {
|
---|
700 | for _, v := range s[nm] {
|
---|
701 | switch x := v.(type) {
|
---|
702 | case *Enumerator:
|
---|
703 | if x.isVisible(seq) {
|
---|
704 | resolvedIn = s
|
---|
705 | resolvedTo = x
|
---|
706 | p.tok.Rune = ENUMCONST
|
---|
707 | kind = PrimaryExpressionEnum
|
---|
708 | break out
|
---|
709 | }
|
---|
710 | case *Declarator:
|
---|
711 | if x.IsTypedefName || !x.isVisible(seq) {
|
---|
712 | continue
|
---|
713 | }
|
---|
714 |
|
---|
715 | resolvedIn = s
|
---|
716 | resolvedTo = x
|
---|
717 | break out
|
---|
718 | case *EnumSpecifier, *StructOrUnionSpecifier, *StructDeclarator, *LabeledStatement:
|
---|
719 | // nop
|
---|
720 | default:
|
---|
721 | panic(internalError())
|
---|
722 | }
|
---|
723 | }
|
---|
724 | }
|
---|
725 |
|
---|
726 | if !p.ctx.cfg.ignoreUndefinedIdentifiers && p.ctx.cfg.RejectLateBinding {
|
---|
727 | p.err0(false, "front-end: undefined: %s", nm)
|
---|
728 | }
|
---|
729 | case INTCONST:
|
---|
730 | kind = PrimaryExpressionInt
|
---|
731 | case FLOATCONST:
|
---|
732 | kind = PrimaryExpressionFloat
|
---|
733 | case ENUMCONST:
|
---|
734 | kind = PrimaryExpressionEnum
|
---|
735 | case CHARCONST:
|
---|
736 | kind = PrimaryExpressionChar
|
---|
737 | case LONGCHARCONST:
|
---|
738 | kind = PrimaryExpressionLChar
|
---|
739 | case STRINGLITERAL:
|
---|
740 | kind = PrimaryExpressionString
|
---|
741 | case LONGSTRINGLITERAL:
|
---|
742 | kind = PrimaryExpressionLString
|
---|
743 | case '(':
|
---|
744 | t := p.shift()
|
---|
745 | switch p.peek(false) {
|
---|
746 | case '{':
|
---|
747 | if p.ctx.cfg.RejectStatementExpressions {
|
---|
748 | p.err0(false, "statement expressions not allowed")
|
---|
749 | }
|
---|
750 | s := p.compoundStatement(nil, nil)
|
---|
751 | var t2 Token
|
---|
752 | switch p.rune() {
|
---|
753 | case ')':
|
---|
754 | t2 = p.shift()
|
---|
755 | default:
|
---|
756 | p.err("expected )")
|
---|
757 | }
|
---|
758 | return &PrimaryExpression{Case: PrimaryExpressionStmt, Token: t, CompoundStatement: s, Token2: t2, lexicalScope: p.declScope}
|
---|
759 | default:
|
---|
760 | e := p.expression()
|
---|
761 | var t2 Token
|
---|
762 | switch p.rune() {
|
---|
763 | case ')':
|
---|
764 | t2 = p.shift()
|
---|
765 | default:
|
---|
766 | p.err("expected )")
|
---|
767 | }
|
---|
768 | return &PrimaryExpression{Case: PrimaryExpressionExpr, Token: t, Expression: e, Token2: t2, lexicalScope: p.declScope}
|
---|
769 | }
|
---|
770 | default:
|
---|
771 | p.err("expected primary-expression")
|
---|
772 | return nil
|
---|
773 | }
|
---|
774 |
|
---|
775 | return &PrimaryExpression{Case: kind, Token: p.shift(), lexicalScope: p.declScope, resolvedIn: resolvedIn, resolvedTo: resolvedTo}
|
---|
776 | }
|
---|
777 |
|
---|
778 | // [0], 6.5.2 Postfix operators
|
---|
779 | //
|
---|
780 | // postfix-expression:
|
---|
781 | // primary-expression
|
---|
782 | // postfix-expression [ expression ]
|
---|
783 | // postfix-expression ( argument-expression-list_opt )
|
---|
784 | // postfix-expression . identifier
|
---|
785 | // postfix-expression -> identifier
|
---|
786 | // postfix-expression ++
|
---|
787 | // postfix-expression --
|
---|
788 | // ( type-name ) { initializer-list }
|
---|
789 | // ( type-name ) { initializer-list , }
|
---|
790 | // __builtin_types_compatible_p ( type-name , type-name )
|
---|
791 | func (p *parser) postfixExpression(typ *TypeName) (r *PostfixExpression) {
|
---|
792 | var t, t2, t3, t4, t5 Token
|
---|
793 | out:
|
---|
794 | switch {
|
---|
795 | case typ != nil:
|
---|
796 | switch p.rune() {
|
---|
797 | case '{':
|
---|
798 | t3 = p.shift()
|
---|
799 | default:
|
---|
800 | p.err("expected {")
|
---|
801 | return nil
|
---|
802 | }
|
---|
803 |
|
---|
804 | var list *InitializerList
|
---|
805 | switch p.rune() {
|
---|
806 | case '}':
|
---|
807 | if p.ctx.cfg.RejectEmptyInitializerList {
|
---|
808 | p.err0(false, "expected initializer-list")
|
---|
809 | }
|
---|
810 | default:
|
---|
811 | list = p.initializerList(nil)
|
---|
812 | if p.rune() == ',' {
|
---|
813 | t4 = p.shift()
|
---|
814 | }
|
---|
815 | }
|
---|
816 | switch p.rune() {
|
---|
817 | case '}':
|
---|
818 | t5 = p.shift()
|
---|
819 | default:
|
---|
820 | p.err("expected }")
|
---|
821 | }
|
---|
822 | r = &PostfixExpression{Case: PostfixExpressionComplit, Token: t, TypeName: typ, Token2: t2, Token3: t3, InitializerList: list, Token4: t4, Token5: t5}
|
---|
823 | break out
|
---|
824 | default:
|
---|
825 | switch p.rune() {
|
---|
826 | case BUILTINCHOOSEEXPR:
|
---|
827 | t = p.shift()
|
---|
828 | switch p.rune() {
|
---|
829 | case '(':
|
---|
830 | t2 = p.shift()
|
---|
831 | default:
|
---|
832 | p.err("expected (")
|
---|
833 | }
|
---|
834 | expr1 := p.assignmentExpression()
|
---|
835 | switch p.rune() {
|
---|
836 | case ',':
|
---|
837 | t3 = p.shift()
|
---|
838 | default:
|
---|
839 | p.err("expected ,")
|
---|
840 | }
|
---|
841 | expr2 := p.assignmentExpression()
|
---|
842 | switch p.rune() {
|
---|
843 | case ',':
|
---|
844 | t4 = p.shift()
|
---|
845 | default:
|
---|
846 | p.err("expected ,")
|
---|
847 | }
|
---|
848 | expr3 := p.assignmentExpression()
|
---|
849 | switch p.rune() {
|
---|
850 | case ')':
|
---|
851 | t5 = p.shift()
|
---|
852 | default:
|
---|
853 | p.err("expected )")
|
---|
854 | }
|
---|
855 | return &PostfixExpression{Case: PostfixExpressionChooseExpr, Token: t, Token2: t2, Token3: t3, Token4: t4, Token5: t5, AssignmentExpression: expr1, AssignmentExpression2: expr2, AssignmentExpression3: expr3}
|
---|
856 | case BUILTINTYPESCOMPATIBLE:
|
---|
857 | t = p.shift()
|
---|
858 | switch p.rune() {
|
---|
859 | case '(':
|
---|
860 | t2 = p.shift()
|
---|
861 | default:
|
---|
862 | p.err("expected (")
|
---|
863 | }
|
---|
864 | typ := p.typeName()
|
---|
865 | switch p.rune() {
|
---|
866 | case ',':
|
---|
867 | t3 = p.shift()
|
---|
868 | default:
|
---|
869 | p.err("expected ,")
|
---|
870 | }
|
---|
871 | typ2 := p.typeName()
|
---|
872 | switch p.rune() {
|
---|
873 | case ')':
|
---|
874 | t4 = p.shift()
|
---|
875 | default:
|
---|
876 | p.err("expected )")
|
---|
877 | }
|
---|
878 | return &PostfixExpression{Case: PostfixExpressionTypeCmp, Token: t, Token2: t2, TypeName: typ, Token3: t3, TypeName2: typ2, Token4: t4}
|
---|
879 | case '(':
|
---|
880 | switch p.peek(true) {
|
---|
881 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
882 | ATTRIBUTE, CONST, RESTRICT, VOLATILE:
|
---|
883 | p.typedefNameEnabled = true
|
---|
884 | t = p.shift()
|
---|
885 | typ := p.typeName()
|
---|
886 | p.typedefNameEnabled = false
|
---|
887 | switch p.rune() {
|
---|
888 | case ')':
|
---|
889 | t2 = p.shift()
|
---|
890 | default:
|
---|
891 | p.err("expected )")
|
---|
892 | }
|
---|
893 | switch p.rune() {
|
---|
894 | case '{':
|
---|
895 | t3 = p.shift()
|
---|
896 | default:
|
---|
897 | p.err("expected {")
|
---|
898 | }
|
---|
899 | var list *InitializerList
|
---|
900 | switch p.rune() {
|
---|
901 | case '}':
|
---|
902 | if p.ctx.cfg.RejectEmptyInitializerList {
|
---|
903 | p.err0(false, "expected initializer-list")
|
---|
904 | }
|
---|
905 | default:
|
---|
906 | list = p.initializerList(nil)
|
---|
907 | if p.rune() == ',' {
|
---|
908 | t4 = p.shift()
|
---|
909 | }
|
---|
910 | }
|
---|
911 | switch p.rune() {
|
---|
912 | case '}':
|
---|
913 | t5 = p.shift()
|
---|
914 | default:
|
---|
915 | p.err("expected }")
|
---|
916 | }
|
---|
917 | r = &PostfixExpression{Case: PostfixExpressionComplit, Token: t, TypeName: typ, Token2: t2, Token3: t3, InitializerList: list, Token4: t4, Token5: t5}
|
---|
918 | break out
|
---|
919 | }
|
---|
920 |
|
---|
921 | fallthrough
|
---|
922 | default:
|
---|
923 | pe := p.primaryExpression()
|
---|
924 | if pe == nil {
|
---|
925 | return nil
|
---|
926 | }
|
---|
927 |
|
---|
928 | r = &PostfixExpression{Case: PostfixExpressionPrimary, PrimaryExpression: pe}
|
---|
929 | }
|
---|
930 | }
|
---|
931 |
|
---|
932 | for {
|
---|
933 | switch p.rune() {
|
---|
934 | case '[':
|
---|
935 | t = p.shift()
|
---|
936 | e := p.expression()
|
---|
937 | switch p.rune() {
|
---|
938 | case ']':
|
---|
939 | t2 = p.shift()
|
---|
940 | default:
|
---|
941 | p.err("expected ]")
|
---|
942 | }
|
---|
943 | r = &PostfixExpression{Case: PostfixExpressionIndex, PostfixExpression: r, Token: t, Expression: e, Token2: t2}
|
---|
944 | case '(':
|
---|
945 | t = p.shift()
|
---|
946 | list := p.argumentExpressionListOpt()
|
---|
947 | switch p.rune() {
|
---|
948 | case ')':
|
---|
949 | t2 = p.shift()
|
---|
950 | default:
|
---|
951 | p.err("expected )")
|
---|
952 | }
|
---|
953 | r = &PostfixExpression{Case: PostfixExpressionCall, PostfixExpression: r, Token: t, ArgumentExpressionList: list, Token2: t2}
|
---|
954 | case '.':
|
---|
955 | t = p.shift()
|
---|
956 | switch p.rune() {
|
---|
957 | case IDENTIFIER:
|
---|
958 | t2 = p.shift()
|
---|
959 | default:
|
---|
960 | p.err("expected identifier")
|
---|
961 | }
|
---|
962 | r = &PostfixExpression{Case: PostfixExpressionSelect, PostfixExpression: r, Token: t, Token2: t2}
|
---|
963 | case ARROW:
|
---|
964 | t = p.shift()
|
---|
965 | switch p.rune() {
|
---|
966 | case IDENTIFIER:
|
---|
967 | t2 = p.shift()
|
---|
968 | default:
|
---|
969 | p.err("expected identifier")
|
---|
970 | }
|
---|
971 | r = &PostfixExpression{Case: PostfixExpressionPSelect, PostfixExpression: r, Token: t, Token2: t2}
|
---|
972 | case INC:
|
---|
973 | r = &PostfixExpression{Case: PostfixExpressionInc, PostfixExpression: r, Token: p.shift()}
|
---|
974 | case DEC:
|
---|
975 | r = &PostfixExpression{Case: PostfixExpressionDec, PostfixExpression: r, Token: p.shift()}
|
---|
976 | default:
|
---|
977 | return r
|
---|
978 | }
|
---|
979 | }
|
---|
980 | }
|
---|
981 |
|
---|
982 | // argument-expression-list:
|
---|
983 | // assignment-expression
|
---|
984 | // argument-expression-list , assignment-expression
|
---|
985 | func (p *parser) argumentExpressionListOpt() (r *ArgumentExpressionList) {
|
---|
986 | if p.rune() == ')' {
|
---|
987 | return nil
|
---|
988 | }
|
---|
989 |
|
---|
990 | e := p.assignmentExpression()
|
---|
991 | if e == nil {
|
---|
992 | return nil
|
---|
993 | }
|
---|
994 |
|
---|
995 | r = &ArgumentExpressionList{AssignmentExpression: e}
|
---|
996 | for prev := r; ; prev = prev.ArgumentExpressionList {
|
---|
997 | switch p.rune() {
|
---|
998 | case ',':
|
---|
999 | t := p.shift()
|
---|
1000 | prev.ArgumentExpressionList = &ArgumentExpressionList{Token: t, AssignmentExpression: p.assignmentExpression()}
|
---|
1001 | case ')':
|
---|
1002 | return r
|
---|
1003 | default:
|
---|
1004 | p.err("expected , or )")
|
---|
1005 | return r
|
---|
1006 | }
|
---|
1007 | }
|
---|
1008 | }
|
---|
1009 |
|
---|
1010 | // [0], 6.5.3 Unary operators
|
---|
1011 | //
|
---|
1012 | // unary-expression:
|
---|
1013 | // postfix-expression
|
---|
1014 | // ++ unary-expression
|
---|
1015 | // -- unary-expression
|
---|
1016 | // unary-operator cast-expression
|
---|
1017 | // sizeof unary-expression
|
---|
1018 | // sizeof ( type-name )
|
---|
1019 | // && identifier
|
---|
1020 | // _Alignof unary-expression
|
---|
1021 | // _Alignof ( type-name )
|
---|
1022 | // __imag__ unary-expression
|
---|
1023 | // __real__ unary-expression
|
---|
1024 | //
|
---|
1025 | // unary-operator: one of
|
---|
1026 | // & * + - ~ !
|
---|
1027 | func (p *parser) unaryExpression(typ *TypeName) *UnaryExpression {
|
---|
1028 | if typ != nil {
|
---|
1029 | return &UnaryExpression{Case: UnaryExpressionPostfix, PostfixExpression: p.postfixExpression(typ), lexicalScope: p.declScope}
|
---|
1030 | }
|
---|
1031 |
|
---|
1032 | var kind UnaryExpressionCase
|
---|
1033 | var t, t2, t3 Token
|
---|
1034 | switch p.rune() {
|
---|
1035 | case INC:
|
---|
1036 | t = p.shift()
|
---|
1037 | return &UnaryExpression{Case: UnaryExpressionInc, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1038 | case DEC:
|
---|
1039 | t = p.shift()
|
---|
1040 | return &UnaryExpression{Case: UnaryExpressionDec, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1041 | case '&':
|
---|
1042 | kind = UnaryExpressionAddrof
|
---|
1043 | case '*':
|
---|
1044 | kind = UnaryExpressionDeref
|
---|
1045 | case '+':
|
---|
1046 | kind = UnaryExpressionPlus
|
---|
1047 | case '-':
|
---|
1048 | kind = UnaryExpressionMinus
|
---|
1049 | case '~':
|
---|
1050 | kind = UnaryExpressionCpl
|
---|
1051 | case '!':
|
---|
1052 | kind = UnaryExpressionNot
|
---|
1053 | case SIZEOF:
|
---|
1054 | t = p.shift()
|
---|
1055 | switch p.rune() {
|
---|
1056 | case '(':
|
---|
1057 | switch p.peek(true) {
|
---|
1058 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
1059 | ATTRIBUTE, CONST, RESTRICT, VOLATILE:
|
---|
1060 | p.typedefNameEnabled = true
|
---|
1061 | t2 = p.shift()
|
---|
1062 | typ := p.typeName()
|
---|
1063 | p.typedefNameEnabled = false
|
---|
1064 | switch p.rune() {
|
---|
1065 | case ')':
|
---|
1066 | t3 = p.shift()
|
---|
1067 | default:
|
---|
1068 | p.err("expected )")
|
---|
1069 | }
|
---|
1070 | if p.peek(false) == '{' {
|
---|
1071 | return &UnaryExpression{Case: UnaryExpressionSizeofExpr, Token: t, UnaryExpression: p.unaryExpression(typ), lexicalScope: p.declScope}
|
---|
1072 | }
|
---|
1073 |
|
---|
1074 | return &UnaryExpression{Case: UnaryExpressionSizeofType, Token: t, Token2: t2, TypeName: typ, Token3: t3, lexicalScope: p.declScope}
|
---|
1075 | }
|
---|
1076 |
|
---|
1077 | fallthrough
|
---|
1078 | default:
|
---|
1079 | return &UnaryExpression{Case: UnaryExpressionSizeofExpr, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1080 | }
|
---|
1081 | case ANDAND:
|
---|
1082 | t = p.shift()
|
---|
1083 | var t2 Token
|
---|
1084 | switch p.rune() {
|
---|
1085 | case IDENTIFIER:
|
---|
1086 | t2 = p.shift()
|
---|
1087 | default:
|
---|
1088 | p.err("expected identifier")
|
---|
1089 | }
|
---|
1090 | return &UnaryExpression{Case: UnaryExpressionLabelAddr, Token: t, Token2: t2, lexicalScope: p.declScope}
|
---|
1091 | case ALIGNOF:
|
---|
1092 | t = p.shift()
|
---|
1093 | switch p.rune() {
|
---|
1094 | case '(':
|
---|
1095 | switch p.peek(true) {
|
---|
1096 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
1097 | ATTRIBUTE, CONST, RESTRICT, VOLATILE,
|
---|
1098 | ALIGNAS:
|
---|
1099 | t2 = p.shift()
|
---|
1100 | typ := p.typeName()
|
---|
1101 | switch p.rune() {
|
---|
1102 | case ')':
|
---|
1103 | t3 = p.shift()
|
---|
1104 | default:
|
---|
1105 | p.err("expected )")
|
---|
1106 | }
|
---|
1107 | return &UnaryExpression{Case: UnaryExpressionAlignofType, Token: t, Token2: t2, TypeName: typ, Token3: t2, lexicalScope: p.declScope}
|
---|
1108 | default:
|
---|
1109 | return &UnaryExpression{Case: UnaryExpressionAlignofExpr, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1110 | }
|
---|
1111 | default:
|
---|
1112 | return &UnaryExpression{Case: UnaryExpressionAlignofExpr, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1113 | }
|
---|
1114 | case IMAG:
|
---|
1115 | t = p.shift()
|
---|
1116 | return &UnaryExpression{Case: UnaryExpressionImag, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1117 | case REAL:
|
---|
1118 | t = p.shift()
|
---|
1119 | return &UnaryExpression{Case: UnaryExpressionReal, Token: t, UnaryExpression: p.unaryExpression(nil), lexicalScope: p.declScope}
|
---|
1120 | default:
|
---|
1121 | return &UnaryExpression{Case: UnaryExpressionPostfix, PostfixExpression: p.postfixExpression(nil), lexicalScope: p.declScope}
|
---|
1122 | }
|
---|
1123 |
|
---|
1124 | t = p.shift()
|
---|
1125 | return &UnaryExpression{Case: kind, Token: t, CastExpression: p.castExpression(), lexicalScope: p.declScope}
|
---|
1126 | }
|
---|
1127 |
|
---|
1128 | // [0], 6.5.4 Cast operators
|
---|
1129 | //
|
---|
1130 | // cast-expression:
|
---|
1131 | // unary-expression
|
---|
1132 | // ( type-name ) cast-expression
|
---|
1133 | func (p *parser) castExpression() *CastExpression {
|
---|
1134 | var t, t2 Token
|
---|
1135 | switch p.rune() {
|
---|
1136 | case '(':
|
---|
1137 | switch p.peek(true) {
|
---|
1138 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
1139 | ATTRIBUTE, CONST, RESTRICT, VOLATILE:
|
---|
1140 | p.typedefNameEnabled = true
|
---|
1141 | t = p.shift()
|
---|
1142 | typ := p.typeName()
|
---|
1143 | p.typedefNameEnabled = false
|
---|
1144 | switch p.rune() {
|
---|
1145 | case ')':
|
---|
1146 | t2 = p.shift()
|
---|
1147 | default:
|
---|
1148 | p.err("expected )")
|
---|
1149 | }
|
---|
1150 | if p.peek(false) == '{' {
|
---|
1151 | return &CastExpression{Case: CastExpressionUnary, UnaryExpression: p.unaryExpression(typ)}
|
---|
1152 | }
|
---|
1153 |
|
---|
1154 | return &CastExpression{Case: CastExpressionCast, Token: t, TypeName: typ, Token2: t2, CastExpression: p.castExpression()}
|
---|
1155 | }
|
---|
1156 |
|
---|
1157 | fallthrough
|
---|
1158 | default:
|
---|
1159 | return &CastExpression{Case: CastExpressionUnary, UnaryExpression: p.unaryExpression(nil)}
|
---|
1160 | }
|
---|
1161 | }
|
---|
1162 |
|
---|
1163 | // [0], 6.5.5 Multiplicative operators
|
---|
1164 | //
|
---|
1165 | // multiplicative-expression:
|
---|
1166 | // cast-expression
|
---|
1167 | // multiplicative-expression * cast-expression
|
---|
1168 | // multiplicative-expression / cast-expression
|
---|
1169 | // multiplicative-expression % cast-expression
|
---|
1170 | func (p *parser) multiplicativeExpression() (r *MultiplicativeExpression) {
|
---|
1171 | r = &MultiplicativeExpression{Case: MultiplicativeExpressionCast, CastExpression: p.castExpression()}
|
---|
1172 | for {
|
---|
1173 | var kind MultiplicativeExpressionCase
|
---|
1174 | switch p.rune() {
|
---|
1175 | case '*':
|
---|
1176 | kind = MultiplicativeExpressionMul
|
---|
1177 | case '/':
|
---|
1178 | kind = MultiplicativeExpressionDiv
|
---|
1179 | case '%':
|
---|
1180 | kind = MultiplicativeExpressionMod
|
---|
1181 | default:
|
---|
1182 | return r
|
---|
1183 | }
|
---|
1184 |
|
---|
1185 | t := p.shift()
|
---|
1186 | r = &MultiplicativeExpression{Case: kind, MultiplicativeExpression: r, Token: t, CastExpression: p.castExpression()}
|
---|
1187 | }
|
---|
1188 | }
|
---|
1189 |
|
---|
1190 | // [0], 6.5.6 Additive operators
|
---|
1191 | //
|
---|
1192 | // additive-expression:
|
---|
1193 | // multiplicative-expression
|
---|
1194 | // additive-expression + multiplicative-expression
|
---|
1195 | // additive-expression - multiplicative-expression
|
---|
1196 | func (p *parser) additiveExpression() (r *AdditiveExpression) {
|
---|
1197 | r = &AdditiveExpression{Case: AdditiveExpressionMul, MultiplicativeExpression: p.multiplicativeExpression()}
|
---|
1198 | for {
|
---|
1199 | var kind AdditiveExpressionCase
|
---|
1200 | switch p.rune() {
|
---|
1201 | case '+':
|
---|
1202 | kind = AdditiveExpressionAdd
|
---|
1203 | case '-':
|
---|
1204 | kind = AdditiveExpressionSub
|
---|
1205 | default:
|
---|
1206 | return r
|
---|
1207 | }
|
---|
1208 |
|
---|
1209 | t := p.shift()
|
---|
1210 | r = &AdditiveExpression{Case: kind, AdditiveExpression: r, Token: t, MultiplicativeExpression: p.multiplicativeExpression(), lexicalScope: p.declScope}
|
---|
1211 | }
|
---|
1212 | }
|
---|
1213 |
|
---|
1214 | // [0], 6.5.7 Bitwise shift operators
|
---|
1215 | //
|
---|
1216 | // shift-expression:
|
---|
1217 | // additive-expression
|
---|
1218 | // shift-expression << additive-expression
|
---|
1219 | // shift-expression >> additive-expression
|
---|
1220 | func (p *parser) shiftExpression() (r *ShiftExpression) {
|
---|
1221 | r = &ShiftExpression{Case: ShiftExpressionAdd, AdditiveExpression: p.additiveExpression()}
|
---|
1222 | for {
|
---|
1223 | var kind ShiftExpressionCase
|
---|
1224 | switch p.rune() {
|
---|
1225 | case LSH:
|
---|
1226 | kind = ShiftExpressionLsh
|
---|
1227 | case RSH:
|
---|
1228 | kind = ShiftExpressionRsh
|
---|
1229 | default:
|
---|
1230 | return r
|
---|
1231 | }
|
---|
1232 |
|
---|
1233 | t := p.shift()
|
---|
1234 | r = &ShiftExpression{Case: kind, ShiftExpression: r, Token: t, AdditiveExpression: p.additiveExpression()}
|
---|
1235 | }
|
---|
1236 | }
|
---|
1237 |
|
---|
1238 | // [0], 6.5.8 Relational operators
|
---|
1239 | //
|
---|
1240 | // relational-expression:
|
---|
1241 | // shift-expression
|
---|
1242 | // relational-expression < shift-expression
|
---|
1243 | // relational-expression > shift-expression
|
---|
1244 | // relational-expression <= shift-expression
|
---|
1245 | // relational-expression >= shift-expression
|
---|
1246 | func (p *parser) relationalExpression() (r *RelationalExpression) {
|
---|
1247 | r = &RelationalExpression{Case: RelationalExpressionShift, ShiftExpression: p.shiftExpression()}
|
---|
1248 | for {
|
---|
1249 | var kind RelationalExpressionCase
|
---|
1250 | switch p.rune() {
|
---|
1251 | case '<':
|
---|
1252 | kind = RelationalExpressionLt
|
---|
1253 | case '>':
|
---|
1254 | kind = RelationalExpressionGt
|
---|
1255 | case LEQ:
|
---|
1256 | kind = RelationalExpressionLeq
|
---|
1257 | case GEQ:
|
---|
1258 | kind = RelationalExpressionGeq
|
---|
1259 | default:
|
---|
1260 | return r
|
---|
1261 | }
|
---|
1262 |
|
---|
1263 | t := p.shift()
|
---|
1264 | r = &RelationalExpression{Case: kind, RelationalExpression: r, Token: t, ShiftExpression: p.shiftExpression()}
|
---|
1265 | }
|
---|
1266 | }
|
---|
1267 |
|
---|
1268 | // [0], 6.5.9 Equality operators
|
---|
1269 | //
|
---|
1270 | // equality-expression:
|
---|
1271 | // relational-expression
|
---|
1272 | // equality-expression == relational-expression
|
---|
1273 | // equality-expression != relational-expression
|
---|
1274 | func (p *parser) equalityExpression() (r *EqualityExpression) {
|
---|
1275 | r = &EqualityExpression{Case: EqualityExpressionRel, RelationalExpression: p.relationalExpression()}
|
---|
1276 | for {
|
---|
1277 | var kind EqualityExpressionCase
|
---|
1278 | switch p.rune() {
|
---|
1279 | case EQ:
|
---|
1280 | kind = EqualityExpressionEq
|
---|
1281 | case NEQ:
|
---|
1282 | kind = EqualityExpressionNeq
|
---|
1283 | default:
|
---|
1284 | return r
|
---|
1285 | }
|
---|
1286 |
|
---|
1287 | t := p.shift()
|
---|
1288 | r = &EqualityExpression{Case: kind, EqualityExpression: r, Token: t, RelationalExpression: p.relationalExpression()}
|
---|
1289 | }
|
---|
1290 | }
|
---|
1291 |
|
---|
1292 | // [0], 6.5.10 Bitwise AND operator
|
---|
1293 | //
|
---|
1294 | // AND-expression:
|
---|
1295 | // equality-expression
|
---|
1296 | // AND-expression & equality-expression
|
---|
1297 | func (p *parser) andExpression() (r *AndExpression) {
|
---|
1298 | r = &AndExpression{Case: AndExpressionEq, EqualityExpression: p.equalityExpression()}
|
---|
1299 | for {
|
---|
1300 | switch p.rune() {
|
---|
1301 | case '&':
|
---|
1302 | t := p.shift()
|
---|
1303 | r = &AndExpression{Case: AndExpressionAnd, AndExpression: r, Token: t, EqualityExpression: p.equalityExpression()}
|
---|
1304 | default:
|
---|
1305 | return r
|
---|
1306 | }
|
---|
1307 | }
|
---|
1308 | }
|
---|
1309 |
|
---|
1310 | // [0], 6.5.11 Bitwise exclusive OR operator
|
---|
1311 | //
|
---|
1312 | // exclusive-OR-expression:
|
---|
1313 | // AND-expression
|
---|
1314 | // exclusive-OR-expression ^ AND-expression
|
---|
1315 | func (p *parser) exclusiveOrExpression() (r *ExclusiveOrExpression) {
|
---|
1316 | r = &ExclusiveOrExpression{Case: ExclusiveOrExpressionAnd, AndExpression: p.andExpression()}
|
---|
1317 | for {
|
---|
1318 | switch p.rune() {
|
---|
1319 | case '^':
|
---|
1320 | t := p.shift()
|
---|
1321 | r = &ExclusiveOrExpression{Case: ExclusiveOrExpressionXor, ExclusiveOrExpression: r, Token: t, AndExpression: p.andExpression()}
|
---|
1322 | default:
|
---|
1323 | return r
|
---|
1324 | }
|
---|
1325 | }
|
---|
1326 | }
|
---|
1327 |
|
---|
1328 | // [0], 6.5.12 Bitwise inclusive OR operator
|
---|
1329 | //
|
---|
1330 | // inclusive-OR-expression:
|
---|
1331 | // exclusive-OR-expression
|
---|
1332 | // inclusive-OR-expression | exclusive-OR-expression
|
---|
1333 | func (p *parser) inclusiveOrExpression() (r *InclusiveOrExpression) {
|
---|
1334 | r = &InclusiveOrExpression{Case: InclusiveOrExpressionXor, ExclusiveOrExpression: p.exclusiveOrExpression()}
|
---|
1335 | for {
|
---|
1336 | switch p.rune() {
|
---|
1337 | case '|':
|
---|
1338 | t := p.shift()
|
---|
1339 | r = &InclusiveOrExpression{Case: InclusiveOrExpressionOr, InclusiveOrExpression: r, Token: t, ExclusiveOrExpression: p.exclusiveOrExpression()}
|
---|
1340 | default:
|
---|
1341 | return r
|
---|
1342 | }
|
---|
1343 | }
|
---|
1344 | }
|
---|
1345 |
|
---|
1346 | // [0], 6.5.13 Logical AND operator
|
---|
1347 | //
|
---|
1348 | // logical-AND-expression:
|
---|
1349 | // inclusive-OR-expression
|
---|
1350 | // logical-AND-expression && inclusive-OR-expression
|
---|
1351 | func (p *parser) logicalAndExpression() (r *LogicalAndExpression) {
|
---|
1352 | r = &LogicalAndExpression{Case: LogicalAndExpressionOr, InclusiveOrExpression: p.inclusiveOrExpression()}
|
---|
1353 | for {
|
---|
1354 | switch p.rune() {
|
---|
1355 | case ANDAND:
|
---|
1356 | t := p.shift()
|
---|
1357 | r = &LogicalAndExpression{Case: LogicalAndExpressionLAnd, LogicalAndExpression: r, Token: t, InclusiveOrExpression: p.inclusiveOrExpression()}
|
---|
1358 | default:
|
---|
1359 | return r
|
---|
1360 | }
|
---|
1361 | }
|
---|
1362 | }
|
---|
1363 |
|
---|
1364 | // [0], 6.5.14 Logical OR operator
|
---|
1365 | //
|
---|
1366 | // logical-OR-expression:
|
---|
1367 | // logical-AND-expression
|
---|
1368 | // logical-OR-expression || logical-AND-expression
|
---|
1369 | func (p *parser) logicalOrExpression() (r *LogicalOrExpression) {
|
---|
1370 | r = &LogicalOrExpression{Case: LogicalOrExpressionLAnd, LogicalAndExpression: p.logicalAndExpression()}
|
---|
1371 | for {
|
---|
1372 | switch p.rune() {
|
---|
1373 | case OROR:
|
---|
1374 | t := p.shift()
|
---|
1375 | r = &LogicalOrExpression{Case: LogicalOrExpressionLOr, LogicalOrExpression: r, Token: t, LogicalAndExpression: p.logicalAndExpression()}
|
---|
1376 | default:
|
---|
1377 | return r
|
---|
1378 | }
|
---|
1379 | }
|
---|
1380 | }
|
---|
1381 |
|
---|
1382 | // [0], 6.5.15 Conditional operator
|
---|
1383 | //
|
---|
1384 | // conditional-expression:
|
---|
1385 | // logical-OR-expression
|
---|
1386 | // logical-OR-expression ? expression : conditional-expression
|
---|
1387 | func (p *parser) conditionalExpression() (r *ConditionalExpression) {
|
---|
1388 | lo := p.logicalOrExpression()
|
---|
1389 | var t, t2 Token
|
---|
1390 | switch p.rune() {
|
---|
1391 | case '?':
|
---|
1392 | t = p.shift()
|
---|
1393 | var e *Expression
|
---|
1394 | switch p.rune() {
|
---|
1395 | case ':':
|
---|
1396 | if p.ctx.cfg.RejectMissingConditionalExpr {
|
---|
1397 | p.err("expected expression")
|
---|
1398 | }
|
---|
1399 | default:
|
---|
1400 | e = p.expression()
|
---|
1401 | }
|
---|
1402 | switch p.rune() {
|
---|
1403 | case ':':
|
---|
1404 | t2 = p.shift()
|
---|
1405 | default:
|
---|
1406 | p.err("expected :")
|
---|
1407 | }
|
---|
1408 | return &ConditionalExpression{Case: ConditionalExpressionCond, LogicalOrExpression: lo, Token: t, Expression: e, Token2: t2, ConditionalExpression: p.conditionalExpression()}
|
---|
1409 | default:
|
---|
1410 | return &ConditionalExpression{Case: ConditionalExpressionLOr, LogicalOrExpression: lo}
|
---|
1411 | }
|
---|
1412 | }
|
---|
1413 |
|
---|
1414 | // [0], 6.5.16 Assignment operators
|
---|
1415 | //
|
---|
1416 | // assignment-expression:
|
---|
1417 | // conditional-expression
|
---|
1418 | // unary-expression assignment-operator assignment-expression
|
---|
1419 | //
|
---|
1420 | // assignment-operator: one of
|
---|
1421 | // = *= /= %= += -= <<= >>= &= ^= |=
|
---|
1422 | func (p *parser) assignmentExpression() (r *AssignmentExpression) {
|
---|
1423 | ce := p.conditionalExpression()
|
---|
1424 | if ce == nil || ce.Case != ConditionalExpressionLOr {
|
---|
1425 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1426 | }
|
---|
1427 |
|
---|
1428 | loe := ce.LogicalOrExpression
|
---|
1429 | if loe == nil || loe.Case != LogicalOrExpressionLAnd {
|
---|
1430 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1431 | }
|
---|
1432 |
|
---|
1433 | lae := loe.LogicalAndExpression
|
---|
1434 | if lae == nil || lae.Case != LogicalAndExpressionOr {
|
---|
1435 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1436 | }
|
---|
1437 |
|
---|
1438 | ioe := lae.InclusiveOrExpression
|
---|
1439 | if ioe == nil || ioe.Case != InclusiveOrExpressionXor {
|
---|
1440 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1441 | }
|
---|
1442 |
|
---|
1443 | eoe := ioe.ExclusiveOrExpression
|
---|
1444 | if eoe == nil || eoe.Case != ExclusiveOrExpressionAnd {
|
---|
1445 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1446 | }
|
---|
1447 |
|
---|
1448 | ae := eoe.AndExpression
|
---|
1449 | if ae == nil || ae.Case != AndExpressionEq {
|
---|
1450 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1451 | }
|
---|
1452 |
|
---|
1453 | ee := ae.EqualityExpression
|
---|
1454 | if ee == nil || ee.Case != EqualityExpressionRel {
|
---|
1455 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1456 | }
|
---|
1457 |
|
---|
1458 | re := ee.RelationalExpression
|
---|
1459 | if re == nil || re.Case != RelationalExpressionShift {
|
---|
1460 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1461 | }
|
---|
1462 |
|
---|
1463 | se := re.ShiftExpression
|
---|
1464 | if se == nil || se.Case != ShiftExpressionAdd {
|
---|
1465 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1466 | }
|
---|
1467 |
|
---|
1468 | adde := se.AdditiveExpression
|
---|
1469 | if adde == nil || adde.Case != AdditiveExpressionMul {
|
---|
1470 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1471 | }
|
---|
1472 |
|
---|
1473 | me := adde.MultiplicativeExpression
|
---|
1474 | if me == nil || me.Case != MultiplicativeExpressionCast {
|
---|
1475 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1476 | }
|
---|
1477 |
|
---|
1478 | cast := me.CastExpression
|
---|
1479 | if cast == nil || cast.Case != CastExpressionUnary {
|
---|
1480 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1481 | }
|
---|
1482 |
|
---|
1483 | var kind AssignmentExpressionCase
|
---|
1484 | switch p.rune() {
|
---|
1485 | case '=':
|
---|
1486 | kind = AssignmentExpressionAssign
|
---|
1487 | case MULASSIGN:
|
---|
1488 | kind = AssignmentExpressionMul
|
---|
1489 | case DIVASSIGN:
|
---|
1490 | kind = AssignmentExpressionDiv
|
---|
1491 | case MODASSIGN:
|
---|
1492 | kind = AssignmentExpressionMod
|
---|
1493 | case ADDASSIGN:
|
---|
1494 | kind = AssignmentExpressionAdd
|
---|
1495 | case SUBASSIGN:
|
---|
1496 | kind = AssignmentExpressionSub
|
---|
1497 | case LSHASSIGN:
|
---|
1498 | kind = AssignmentExpressionLsh
|
---|
1499 | case RSHASSIGN:
|
---|
1500 | kind = AssignmentExpressionRsh
|
---|
1501 | case ANDASSIGN:
|
---|
1502 | kind = AssignmentExpressionAnd
|
---|
1503 | case XORASSIGN:
|
---|
1504 | kind = AssignmentExpressionXor
|
---|
1505 | case ORASSIGN:
|
---|
1506 | kind = AssignmentExpressionOr
|
---|
1507 | default:
|
---|
1508 | return &AssignmentExpression{Case: AssignmentExpressionCond, ConditionalExpression: ce, lexicalScope: p.declScope}
|
---|
1509 | }
|
---|
1510 |
|
---|
1511 | t := p.shift()
|
---|
1512 | return &AssignmentExpression{Case: kind, UnaryExpression: cast.UnaryExpression, Token: t, AssignmentExpression: p.assignmentExpression(), lexicalScope: p.declScope}
|
---|
1513 | }
|
---|
1514 |
|
---|
1515 | // [0], 6.5.17 Comma operator
|
---|
1516 | //
|
---|
1517 | // expression:
|
---|
1518 | // assignment-expression
|
---|
1519 | // expression , assignment-expression
|
---|
1520 | func (p *parser) expression() (r *Expression) {
|
---|
1521 | r = &Expression{Case: ExpressionAssign, AssignmentExpression: p.assignmentExpression()}
|
---|
1522 | for {
|
---|
1523 | switch p.rune() {
|
---|
1524 | case ',':
|
---|
1525 | t := p.shift()
|
---|
1526 | r = &Expression{Case: ExpressionComma, Expression: r, Token: t, AssignmentExpression: p.assignmentExpression()}
|
---|
1527 | default:
|
---|
1528 | return r
|
---|
1529 | }
|
---|
1530 | }
|
---|
1531 | }
|
---|
1532 |
|
---|
1533 | // [0], 6.6 Constant expressions
|
---|
1534 | //
|
---|
1535 | // constant-expression:
|
---|
1536 | // conditional-expression
|
---|
1537 | func (p *parser) constantExpression() (r *ConstantExpression) {
|
---|
1538 | return &ConstantExpression{ConditionalExpression: p.conditionalExpression()}
|
---|
1539 | }
|
---|
1540 |
|
---|
1541 | // [0], 6.7 Declarations
|
---|
1542 | //
|
---|
1543 | // declaration:
|
---|
1544 | // declaration-specifiers init-declarator-list_opt attribute-specifier-list_opt ;
|
---|
1545 | func (p *parser) declaration(ds *DeclarationSpecifiers, d *Declarator) (r *Declaration) {
|
---|
1546 | defer func() {
|
---|
1547 | if cs := p.block; cs != nil && r != nil {
|
---|
1548 | cs.declarations = append(cs.declarations, r)
|
---|
1549 | }
|
---|
1550 | }()
|
---|
1551 |
|
---|
1552 | if ds == nil {
|
---|
1553 | ds = p.declarationSpecifiers(nil, nil)
|
---|
1554 | }
|
---|
1555 | if ds == noDeclSpecs {
|
---|
1556 | ds = nil
|
---|
1557 | }
|
---|
1558 | if d == nil {
|
---|
1559 | switch p.rune() {
|
---|
1560 | case ';':
|
---|
1561 | p.typedefNameEnabled = true
|
---|
1562 | return &Declaration{DeclarationSpecifiers: ds, Token: p.shift()}
|
---|
1563 | }
|
---|
1564 | }
|
---|
1565 |
|
---|
1566 | list := p.initDeclaratorList(d, ds.typedef())
|
---|
1567 | p.typedefNameEnabled = true
|
---|
1568 | var t Token
|
---|
1569 | switch p.rune() {
|
---|
1570 | case ';':
|
---|
1571 | t = p.shift()
|
---|
1572 | default:
|
---|
1573 | p.err("expected ;")
|
---|
1574 | }
|
---|
1575 | return &Declaration{DeclarationSpecifiers: ds, InitDeclaratorList: list, Token: t}
|
---|
1576 | }
|
---|
1577 |
|
---|
1578 | // declaration-specifiers:
|
---|
1579 | // storage-class-specifier declaration-specifiers_opt
|
---|
1580 | // type-specifier declaration-specifiers_opt
|
---|
1581 | // type-qualifier declaration-specifiers_opt
|
---|
1582 | // function-specifier declaration-specifiers_opt
|
---|
1583 | // alignment-specifier declaration-specifiers_opt
|
---|
1584 | // attribute-specifier declaration-specifiers_opt
|
---|
1585 | func (p *parser) declarationSpecifiers(extern, inline *bool) (r *DeclarationSpecifiers) {
|
---|
1586 | switch p.rune() {
|
---|
1587 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL:
|
---|
1588 | if extern != nil && p.rune() == EXTERN {
|
---|
1589 | *extern = true
|
---|
1590 | }
|
---|
1591 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersStorage, StorageClassSpecifier: p.storageClassSpecifier()}
|
---|
1592 | if r.StorageClassSpecifier.Case == StorageClassSpecifierTypedef {
|
---|
1593 | r.class = fTypedef
|
---|
1594 | }
|
---|
1595 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF:
|
---|
1596 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
1597 | case CONST, RESTRICT, VOLATILE:
|
---|
1598 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
1599 | case INLINE, NORETURN:
|
---|
1600 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersFunc, FunctionSpecifier: p.functionSpecifier(inline)}
|
---|
1601 | case ALIGNAS:
|
---|
1602 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersAlignSpec, AlignmentSpecifier: p.alignmentSpecifier()}
|
---|
1603 | case ATOMIC:
|
---|
1604 | switch p.peek(false) {
|
---|
1605 | case '(':
|
---|
1606 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
1607 | default:
|
---|
1608 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
1609 | }
|
---|
1610 | case ATTRIBUTE:
|
---|
1611 | r = &DeclarationSpecifiers{Case: DeclarationSpecifiersAttribute, AttributeSpecifier: p.attributeSpecifier()}
|
---|
1612 | default:
|
---|
1613 | p.err("expected declaration-specifiers")
|
---|
1614 | return nil
|
---|
1615 | }
|
---|
1616 | r0 := r
|
---|
1617 | for prev := r; ; prev = prev.DeclarationSpecifiers {
|
---|
1618 | switch p.rune() {
|
---|
1619 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL:
|
---|
1620 | if extern != nil && p.rune() == EXTERN {
|
---|
1621 | *extern = true
|
---|
1622 | }
|
---|
1623 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersStorage, StorageClassSpecifier: p.storageClassSpecifier()}
|
---|
1624 | if prev.DeclarationSpecifiers.StorageClassSpecifier.Case == StorageClassSpecifierTypedef {
|
---|
1625 | r0.class |= fTypedef
|
---|
1626 | }
|
---|
1627 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF:
|
---|
1628 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
1629 | case CONST, RESTRICT, VOLATILE:
|
---|
1630 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
1631 | case INLINE, NORETURN:
|
---|
1632 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersFunc, FunctionSpecifier: p.functionSpecifier(inline)}
|
---|
1633 | case ALIGNAS:
|
---|
1634 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersAlignSpec, AlignmentSpecifier: p.alignmentSpecifier()}
|
---|
1635 | case ATOMIC:
|
---|
1636 | switch p.peek(false) {
|
---|
1637 | case '(':
|
---|
1638 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
1639 | default:
|
---|
1640 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
1641 | }
|
---|
1642 | case ATTRIBUTE:
|
---|
1643 | prev.DeclarationSpecifiers = &DeclarationSpecifiers{Case: DeclarationSpecifiersAttribute, AttributeSpecifier: p.attributeSpecifier()}
|
---|
1644 | default:
|
---|
1645 | return r
|
---|
1646 | }
|
---|
1647 | }
|
---|
1648 | }
|
---|
1649 |
|
---|
1650 | // init-declarator-list:
|
---|
1651 | // init-declarator
|
---|
1652 | // init-declarator-list , attribute-specifier-list_opt init-declarator
|
---|
1653 | func (p *parser) initDeclaratorList(d *Declarator, isTypedefName bool) (r *InitDeclaratorList) {
|
---|
1654 | r = &InitDeclaratorList{InitDeclarator: p.initDeclarator(d, isTypedefName)}
|
---|
1655 | for prev := r; ; prev = prev.InitDeclaratorList {
|
---|
1656 | switch p.rune() {
|
---|
1657 | case ',':
|
---|
1658 | t := p.shift()
|
---|
1659 | attr := p.attributeSpecifierListOpt()
|
---|
1660 | // if attr != nil {
|
---|
1661 | // trc("%v: ATTRS", attr.Position())
|
---|
1662 | // }
|
---|
1663 | prev.InitDeclaratorList = &InitDeclaratorList{Token: t, AttributeSpecifierList: attr, InitDeclarator: p.initDeclarator(nil, isTypedefName)}
|
---|
1664 | default:
|
---|
1665 | return r
|
---|
1666 | }
|
---|
1667 | }
|
---|
1668 | }
|
---|
1669 |
|
---|
1670 | func (p *parser) attributeSpecifierListOpt() (r *AttributeSpecifierList) {
|
---|
1671 | if p.rune() == ATTRIBUTE {
|
---|
1672 | r = p.attributeSpecifierList()
|
---|
1673 | }
|
---|
1674 | return r
|
---|
1675 | }
|
---|
1676 |
|
---|
1677 | // init-declarator:
|
---|
1678 | // declarator attribute-specifier-list_opt
|
---|
1679 | // declarator attribute-specifier-list_opt = initializer
|
---|
1680 | func (p *parser) initDeclarator(d *Declarator, isTypedefName bool) *InitDeclarator {
|
---|
1681 | if d == nil {
|
---|
1682 | d = p.declarator(true, isTypedefName, nil)
|
---|
1683 | }
|
---|
1684 | attr := p.attributeSpecifierListOpt()
|
---|
1685 | // if attr != nil {
|
---|
1686 | // trc("%v: ATTRS", attr.Position())
|
---|
1687 | // }
|
---|
1688 | switch p.rune() {
|
---|
1689 | case '=':
|
---|
1690 | t := p.shift()
|
---|
1691 | return &InitDeclarator{Case: InitDeclaratorInit, Declarator: d, AttributeSpecifierList: attr, Token: t, Initializer: p.initializer(nil)}
|
---|
1692 | }
|
---|
1693 |
|
---|
1694 | return &InitDeclarator{Case: InitDeclaratorDecl, Declarator: d, AttributeSpecifierList: attr}
|
---|
1695 | }
|
---|
1696 |
|
---|
1697 | // [0], 6.7.1 Storage-class specifiers
|
---|
1698 | //
|
---|
1699 | // storage-class-specifier:
|
---|
1700 | // typedef
|
---|
1701 | // extern
|
---|
1702 | // static
|
---|
1703 | // auto
|
---|
1704 | // register
|
---|
1705 | func (p *parser) storageClassSpecifier() *StorageClassSpecifier {
|
---|
1706 | var kind StorageClassSpecifierCase
|
---|
1707 | switch p.rune() {
|
---|
1708 | case TYPEDEF:
|
---|
1709 | kind = StorageClassSpecifierTypedef
|
---|
1710 | case EXTERN:
|
---|
1711 | kind = StorageClassSpecifierExtern
|
---|
1712 | case STATIC:
|
---|
1713 | kind = StorageClassSpecifierStatic
|
---|
1714 | case AUTO:
|
---|
1715 | kind = StorageClassSpecifierAuto
|
---|
1716 | case REGISTER:
|
---|
1717 | kind = StorageClassSpecifierRegister
|
---|
1718 | case THREADLOCAL:
|
---|
1719 | kind = StorageClassSpecifierThreadLocal
|
---|
1720 | default:
|
---|
1721 | p.err("expected storage-class-specifier")
|
---|
1722 | return nil
|
---|
1723 | }
|
---|
1724 |
|
---|
1725 | return &StorageClassSpecifier{Case: kind, Token: p.shift()}
|
---|
1726 | }
|
---|
1727 |
|
---|
1728 | // [0], 6.7.2 Type specifiers
|
---|
1729 | //
|
---|
1730 | // type-specifier:
|
---|
1731 | // void
|
---|
1732 | // char
|
---|
1733 | // short
|
---|
1734 | // int
|
---|
1735 | // long
|
---|
1736 | // float
|
---|
1737 | // __fp16
|
---|
1738 | // __float80
|
---|
1739 | // double
|
---|
1740 | // signed
|
---|
1741 | // unsigned
|
---|
1742 | // _Bool
|
---|
1743 | // _Complex
|
---|
1744 | // _Float128
|
---|
1745 | // struct-or-union-specifier
|
---|
1746 | // enum-specifier
|
---|
1747 | // typedef-name
|
---|
1748 | // typeof ( expression )
|
---|
1749 | // typeof ( type-name )
|
---|
1750 | // atomic-type-specifier
|
---|
1751 | // _Frac
|
---|
1752 | // _Sat
|
---|
1753 | // _Accum
|
---|
1754 | // _Float32
|
---|
1755 | func (p *parser) typeSpecifier() *TypeSpecifier {
|
---|
1756 | var kind TypeSpecifierCase
|
---|
1757 | switch p.rune() {
|
---|
1758 | case VOID:
|
---|
1759 | kind = TypeSpecifierVoid
|
---|
1760 | case CHAR:
|
---|
1761 | kind = TypeSpecifierChar
|
---|
1762 | case SHORT:
|
---|
1763 | kind = TypeSpecifierShort
|
---|
1764 | case INT:
|
---|
1765 | kind = TypeSpecifierInt
|
---|
1766 | case INT8:
|
---|
1767 | kind = TypeSpecifierInt8
|
---|
1768 | case INT16:
|
---|
1769 | kind = TypeSpecifierInt16
|
---|
1770 | case INT32:
|
---|
1771 | kind = TypeSpecifierInt32
|
---|
1772 | case INT64:
|
---|
1773 | kind = TypeSpecifierInt64
|
---|
1774 | case INT128:
|
---|
1775 | kind = TypeSpecifierInt128
|
---|
1776 | case LONG:
|
---|
1777 | kind = TypeSpecifierLong
|
---|
1778 | case FLOAT:
|
---|
1779 | kind = TypeSpecifierFloat
|
---|
1780 | case FLOAT16:
|
---|
1781 | kind = TypeSpecifierFloat16
|
---|
1782 | case FLOAT80:
|
---|
1783 | kind = TypeSpecifierFloat80
|
---|
1784 | case FLOAT32:
|
---|
1785 | kind = TypeSpecifierFloat32
|
---|
1786 | case FLOAT32X:
|
---|
1787 | kind = TypeSpecifierFloat32x
|
---|
1788 | case FLOAT64:
|
---|
1789 | kind = TypeSpecifierFloat64
|
---|
1790 | case FLOAT64X:
|
---|
1791 | kind = TypeSpecifierFloat64x
|
---|
1792 | case FLOAT128:
|
---|
1793 | kind = TypeSpecifierFloat128
|
---|
1794 | case DECIMAL32:
|
---|
1795 | kind = TypeSpecifierDecimal32
|
---|
1796 | case DECIMAL64:
|
---|
1797 | kind = TypeSpecifierDecimal64
|
---|
1798 | case DECIMAL128:
|
---|
1799 | kind = TypeSpecifierDecimal128
|
---|
1800 | case DOUBLE:
|
---|
1801 | kind = TypeSpecifierDouble
|
---|
1802 | case SIGNED:
|
---|
1803 | kind = TypeSpecifierSigned
|
---|
1804 | case UNSIGNED:
|
---|
1805 | kind = TypeSpecifierUnsigned
|
---|
1806 | case BOOL:
|
---|
1807 | kind = TypeSpecifierBool
|
---|
1808 | case COMPLEX:
|
---|
1809 | kind = TypeSpecifierComplex
|
---|
1810 | case FRACT:
|
---|
1811 | kind = TypeSpecifierFract
|
---|
1812 | case SAT:
|
---|
1813 | kind = TypeSpecifierSat
|
---|
1814 | case ACCUM:
|
---|
1815 | kind = TypeSpecifierAccum
|
---|
1816 | case TYPEDEFNAME:
|
---|
1817 | kind = TypeSpecifierTypedefName
|
---|
1818 | case STRUCT, UNION:
|
---|
1819 | r := &TypeSpecifier{Case: TypeSpecifierStructOrUnion, StructOrUnionSpecifier: p.structOrUnionSpecifier()}
|
---|
1820 | p.typedefNameEnabled = false
|
---|
1821 | return r
|
---|
1822 | case ENUM:
|
---|
1823 | r := &TypeSpecifier{Case: TypeSpecifierEnum, EnumSpecifier: p.enumSpecifier()}
|
---|
1824 | p.typedefNameEnabled = false
|
---|
1825 | return r
|
---|
1826 | case TYPEOF:
|
---|
1827 | var t, t2, t3 Token
|
---|
1828 | t = p.shift()
|
---|
1829 | switch p.rune() {
|
---|
1830 | case '(':
|
---|
1831 | t2 = p.shift()
|
---|
1832 | default:
|
---|
1833 | p.err("expected (")
|
---|
1834 | }
|
---|
1835 | switch p.rune() {
|
---|
1836 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
1837 | ATTRIBUTE, CONST, RESTRICT, VOLATILE,
|
---|
1838 | ALIGNAS:
|
---|
1839 | typ := p.typeName()
|
---|
1840 | switch p.rune() {
|
---|
1841 | case ')':
|
---|
1842 | t3 = p.shift()
|
---|
1843 | default:
|
---|
1844 | p.err("expected )")
|
---|
1845 | }
|
---|
1846 | return &TypeSpecifier{Case: TypeSpecifierTypeofType, Token: t, Token2: t2, TypeName: typ, Token3: t3}
|
---|
1847 | default:
|
---|
1848 | e := p.expression()
|
---|
1849 | switch p.rune() {
|
---|
1850 | case ')':
|
---|
1851 | t3 = p.shift()
|
---|
1852 | default:
|
---|
1853 | p.err("expected )")
|
---|
1854 | }
|
---|
1855 | return &TypeSpecifier{Case: TypeSpecifierTypeofExpr, Token: t, Token2: t2, Expression: e, Token3: t3}
|
---|
1856 | }
|
---|
1857 | case ATOMIC:
|
---|
1858 | return &TypeSpecifier{Case: TypeSpecifierAtomic, AtomicTypeSpecifier: p.atomicTypeSpecifier()}
|
---|
1859 | default:
|
---|
1860 | p.err("expected type-specifier")
|
---|
1861 | return nil
|
---|
1862 | }
|
---|
1863 |
|
---|
1864 | p.typedefNameEnabled = false
|
---|
1865 | return &TypeSpecifier{Case: kind, Token: p.shift(), resolvedIn: p.resolvedIn}
|
---|
1866 | }
|
---|
1867 |
|
---|
1868 | // [0], 6.7.2.1 Structure and union specifiers
|
---|
1869 | //
|
---|
1870 | // struct-or-union-specifier:
|
---|
1871 | // struct-or-union attribute-specifier-list_opt identifier_opt { struct-declaration-list }
|
---|
1872 | // struct-or-union attribute-specifier-list_opt identifier
|
---|
1873 | func (p *parser) structOrUnionSpecifier() *StructOrUnionSpecifier {
|
---|
1874 | switch p.rune() {
|
---|
1875 | case STRUCT, UNION:
|
---|
1876 | default:
|
---|
1877 | p.err("expected struct-or-union-specifier")
|
---|
1878 | return nil
|
---|
1879 | }
|
---|
1880 |
|
---|
1881 | sou := p.structOrUnion()
|
---|
1882 | attr := p.attributeSpecifierListOpt()
|
---|
1883 | // if attr != nil {
|
---|
1884 | // trc("%v: ATTRS", attr.Position())
|
---|
1885 | // }
|
---|
1886 | var t, t2, t3 Token
|
---|
1887 | switch p.rune() {
|
---|
1888 | case IDENTIFIER:
|
---|
1889 | t = p.shift()
|
---|
1890 | if p.rune() != '{' {
|
---|
1891 | return &StructOrUnionSpecifier{Case: StructOrUnionSpecifierTag, StructOrUnion: sou, AttributeSpecifierList: attr, Token: t, lexicalScope: p.declScope}
|
---|
1892 | }
|
---|
1893 |
|
---|
1894 | fallthrough
|
---|
1895 | case '{':
|
---|
1896 | maxAlign := p.ctx.maxAlign
|
---|
1897 | p.openScope(true)
|
---|
1898 | p.typedefNameEnabled = true
|
---|
1899 | p.resolveScope = p.declScope.Parent()
|
---|
1900 | t2 = p.shift()
|
---|
1901 | var list *StructDeclarationList
|
---|
1902 | switch p.peek(false) {
|
---|
1903 | case '}':
|
---|
1904 | if p.ctx.cfg.RejectEmptyStructs {
|
---|
1905 | p.err("expected struct-declarator-list")
|
---|
1906 | }
|
---|
1907 | default:
|
---|
1908 | list = p.structDeclarationList()
|
---|
1909 | }
|
---|
1910 | p.closeScope()
|
---|
1911 | switch p.rune() {
|
---|
1912 | case '}':
|
---|
1913 | t3 = p.shift()
|
---|
1914 | default:
|
---|
1915 | p.err("expected }")
|
---|
1916 | }
|
---|
1917 | r := &StructOrUnionSpecifier{Case: StructOrUnionSpecifierDef, StructOrUnion: sou, AttributeSpecifierList: attr, Token: t, Token2: t2, StructDeclarationList: list, Token3: t3, lexicalScope: p.declScope, maxAlign: maxAlign}
|
---|
1918 | if t.Value != 0 {
|
---|
1919 | p.declScope.declare(t.Value, r)
|
---|
1920 | }
|
---|
1921 | return r
|
---|
1922 | default:
|
---|
1923 | p.err("expected identifier or {")
|
---|
1924 | return nil
|
---|
1925 | }
|
---|
1926 | }
|
---|
1927 |
|
---|
1928 | // struct-or-union:
|
---|
1929 | // struct
|
---|
1930 | // union
|
---|
1931 | func (p *parser) structOrUnion() *StructOrUnion {
|
---|
1932 | var kind StructOrUnionCase
|
---|
1933 | switch p.rune() {
|
---|
1934 | case STRUCT:
|
---|
1935 | kind = StructOrUnionStruct
|
---|
1936 | case UNION:
|
---|
1937 | kind = StructOrUnionUnion
|
---|
1938 | default:
|
---|
1939 | p.err("expected struct-or-union")
|
---|
1940 | return nil
|
---|
1941 | }
|
---|
1942 |
|
---|
1943 | p.typedefNameEnabled = false
|
---|
1944 | return &StructOrUnion{Case: kind, Token: p.shift()}
|
---|
1945 | }
|
---|
1946 |
|
---|
1947 | // struct-declaration-list:
|
---|
1948 | // struct-declaration
|
---|
1949 | // struct-declaration-list struct-declaration
|
---|
1950 | func (p *parser) structDeclarationList() (r *StructDeclarationList) {
|
---|
1951 | r = &StructDeclarationList{StructDeclaration: p.structDeclaration()}
|
---|
1952 | for prev := r; ; prev = prev.StructDeclarationList {
|
---|
1953 | switch p.rune() {
|
---|
1954 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
1955 | ATTRIBUTE, CONST, RESTRICT, VOLATILE,
|
---|
1956 | ALIGNAS:
|
---|
1957 | prev.StructDeclarationList = &StructDeclarationList{StructDeclaration: p.structDeclaration()}
|
---|
1958 | case ';':
|
---|
1959 | p.shift()
|
---|
1960 | if p.ctx.cfg.RejectEmptyFields {
|
---|
1961 | p.err("expected struct-declaration")
|
---|
1962 | }
|
---|
1963 | default:
|
---|
1964 | return r
|
---|
1965 | }
|
---|
1966 | }
|
---|
1967 | }
|
---|
1968 |
|
---|
1969 | // struct-declaration:
|
---|
1970 | // specifier-qualifier-list struct-declarator-list ;
|
---|
1971 | func (p *parser) structDeclaration() (r *StructDeclaration) {
|
---|
1972 | if p.rune() == ';' {
|
---|
1973 | if p.ctx.cfg.RejectEmptyStructDeclaration {
|
---|
1974 | p.err("expected struct-declaration")
|
---|
1975 | }
|
---|
1976 | return &StructDeclaration{Empty: true, Token: p.shift()}
|
---|
1977 | }
|
---|
1978 | sql := p.specifierQualifierList()
|
---|
1979 | r = &StructDeclaration{SpecifierQualifierList: sql}
|
---|
1980 | switch p.rune() {
|
---|
1981 | case ';':
|
---|
1982 | if p.ctx.cfg.RejectAnonymousFields {
|
---|
1983 | p.err("expected struct-declarator")
|
---|
1984 | }
|
---|
1985 | default:
|
---|
1986 | r.StructDeclaratorList = p.structDeclaratorList(r)
|
---|
1987 | }
|
---|
1988 | var t Token
|
---|
1989 | p.typedefNameEnabled = true
|
---|
1990 | switch p.rune() {
|
---|
1991 | case '}':
|
---|
1992 | if p.ctx.cfg.RejectMissingFinalStructFieldSemicolon {
|
---|
1993 | p.err0(false, "expected ;")
|
---|
1994 | }
|
---|
1995 | case ';':
|
---|
1996 | t = p.shift()
|
---|
1997 | default:
|
---|
1998 | p.err("expected ;")
|
---|
1999 | }
|
---|
2000 | r.Token = t
|
---|
2001 | return r
|
---|
2002 | }
|
---|
2003 |
|
---|
2004 | // specifier-qualifier-list:
|
---|
2005 | // type-specifier specifier-qualifier-list_opt
|
---|
2006 | // type-qualifier specifier-qualifier-list_opt
|
---|
2007 | // alignment-specifier-qualifier-list_opt
|
---|
2008 | func (p *parser) specifierQualifierList() (r *SpecifierQualifierList) {
|
---|
2009 | switch p.rune() {
|
---|
2010 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF:
|
---|
2011 | r = &SpecifierQualifierList{Case: SpecifierQualifierListTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
2012 | case CONST, RESTRICT, VOLATILE:
|
---|
2013 | r = &SpecifierQualifierList{Case: SpecifierQualifierListTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
2014 | case ALIGNAS:
|
---|
2015 | r = &SpecifierQualifierList{Case: SpecifierQualifierListAlignSpec, AlignmentSpecifier: p.alignmentSpecifier()}
|
---|
2016 | case ATOMIC:
|
---|
2017 | switch p.peek(false) {
|
---|
2018 | case '(':
|
---|
2019 | r = &SpecifierQualifierList{Case: SpecifierQualifierListTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
2020 | default:
|
---|
2021 | r = &SpecifierQualifierList{Case: SpecifierQualifierListTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
2022 | }
|
---|
2023 | case ATTRIBUTE:
|
---|
2024 | r = &SpecifierQualifierList{Case: SpecifierQualifierListAttribute, AttributeSpecifier: p.attributeSpecifier()}
|
---|
2025 | default:
|
---|
2026 | p.err("expected specifier-qualifier-list: %s", tokName(p.rune()))
|
---|
2027 | return nil
|
---|
2028 | }
|
---|
2029 | for prev := r; ; prev = prev.SpecifierQualifierList {
|
---|
2030 | switch p.rune() {
|
---|
2031 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF:
|
---|
2032 | prev.SpecifierQualifierList = &SpecifierQualifierList{Case: SpecifierQualifierListTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
2033 | case CONST, RESTRICT, VOLATILE:
|
---|
2034 | prev.SpecifierQualifierList = &SpecifierQualifierList{Case: SpecifierQualifierListTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
2035 | case ALIGNAS:
|
---|
2036 | prev.SpecifierQualifierList = &SpecifierQualifierList{Case: SpecifierQualifierListAlignSpec, AlignmentSpecifier: p.alignmentSpecifier()}
|
---|
2037 | case ATOMIC:
|
---|
2038 | switch p.peek(false) {
|
---|
2039 | case '(':
|
---|
2040 | prev.SpecifierQualifierList = &SpecifierQualifierList{Case: SpecifierQualifierListTypeSpec, TypeSpecifier: p.typeSpecifier()}
|
---|
2041 | default:
|
---|
2042 | prev.SpecifierQualifierList = &SpecifierQualifierList{Case: SpecifierQualifierListTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
2043 | }
|
---|
2044 | case ATTRIBUTE:
|
---|
2045 | prev.SpecifierQualifierList = &SpecifierQualifierList{Case: SpecifierQualifierListAttribute, AttributeSpecifier: p.attributeSpecifier()}
|
---|
2046 | default:
|
---|
2047 | return r
|
---|
2048 | }
|
---|
2049 | }
|
---|
2050 | }
|
---|
2051 |
|
---|
2052 | // struct-declarator-list:
|
---|
2053 | // struct-declarator
|
---|
2054 | // struct-declarator-list , struct-declarator
|
---|
2055 | func (p *parser) structDeclaratorList(decl *StructDeclaration) (r *StructDeclaratorList) {
|
---|
2056 | r = &StructDeclaratorList{StructDeclarator: p.structDeclarator(decl)}
|
---|
2057 | for prev := r; ; prev = prev.StructDeclaratorList {
|
---|
2058 | switch p.rune() {
|
---|
2059 | case ',':
|
---|
2060 | t := p.shift()
|
---|
2061 | prev.StructDeclaratorList = &StructDeclaratorList{Token: t, StructDeclarator: p.structDeclarator(decl)}
|
---|
2062 | default:
|
---|
2063 | return r
|
---|
2064 | }
|
---|
2065 | }
|
---|
2066 | }
|
---|
2067 |
|
---|
2068 | // struct-declarator:
|
---|
2069 | // declarator
|
---|
2070 | // declarator_opt : constant-expression attribute-specifier-list_opt
|
---|
2071 | func (p *parser) structDeclarator(decl *StructDeclaration) (r *StructDeclarator) {
|
---|
2072 | var d *Declarator
|
---|
2073 | if p.rune() != ':' {
|
---|
2074 | d = p.declarator(false, false, nil)
|
---|
2075 | }
|
---|
2076 |
|
---|
2077 | switch p.rune() {
|
---|
2078 | case ':':
|
---|
2079 | t := p.shift()
|
---|
2080 | r = &StructDeclarator{Case: StructDeclaratorBitField, Declarator: d, Token: t, ConstantExpression: p.constantExpression(), decl: decl}
|
---|
2081 | r.AttributeSpecifierList = p.attributeSpecifierListOpt()
|
---|
2082 | // if r.AttributeSpecifierList != nil {
|
---|
2083 | // trc("%v: ATTRS", r.AttributeSpecifierList.Position())
|
---|
2084 | // }
|
---|
2085 | default:
|
---|
2086 | r = &StructDeclarator{Case: StructDeclaratorDecl, Declarator: d, decl: decl}
|
---|
2087 | }
|
---|
2088 | if d != nil {
|
---|
2089 | p.declScope.declare(d.Name(), r)
|
---|
2090 | }
|
---|
2091 | return r
|
---|
2092 | }
|
---|
2093 |
|
---|
2094 | // [0], 6.7.2.2 Enumeration specifiers
|
---|
2095 | //
|
---|
2096 | // enum-specifier:
|
---|
2097 | // enum attribute-specifier-list_opt identifier_opt { enumerator-list }
|
---|
2098 | // enum attribute-specifier-list_opt identifier_opt { enumerator-list , }
|
---|
2099 | // enum attribute-specifier-list_opt identifier
|
---|
2100 | func (p *parser) enumSpecifier() *EnumSpecifier {
|
---|
2101 | if p.rune() != ENUM {
|
---|
2102 | p.err("expected enum")
|
---|
2103 | return nil
|
---|
2104 | }
|
---|
2105 |
|
---|
2106 | var t, t2, t3, t4, t5 Token
|
---|
2107 | p.typedefNameEnabled = false
|
---|
2108 | t = p.shift()
|
---|
2109 | attr := p.attributeSpecifierListOpt()
|
---|
2110 | // if attr != nil {
|
---|
2111 | // trc("%v: ATTRS", attr.Position())
|
---|
2112 | // }
|
---|
2113 | if p.rune() == IDENTIFIER {
|
---|
2114 | t2 = p.shift()
|
---|
2115 | if p.rune() != '{' {
|
---|
2116 | return &EnumSpecifier{Case: EnumSpecifierTag, AttributeSpecifierList: attr, Token: t, Token2: t2, lexicalScope: p.declScope}
|
---|
2117 | }
|
---|
2118 | }
|
---|
2119 |
|
---|
2120 | if p.rune() != '{' {
|
---|
2121 | p.err("expected identifier or {")
|
---|
2122 | return nil
|
---|
2123 | }
|
---|
2124 |
|
---|
2125 | p.typedefNameEnabled = false
|
---|
2126 | t3 = p.shift()
|
---|
2127 | list := p.enumeratorList()
|
---|
2128 | if p.rune() == ',' {
|
---|
2129 | t4 = p.shift()
|
---|
2130 | }
|
---|
2131 |
|
---|
2132 | switch p.rune() {
|
---|
2133 | case '}':
|
---|
2134 | t5 = p.shift()
|
---|
2135 | default:
|
---|
2136 | p.err("expected }")
|
---|
2137 | }
|
---|
2138 | r := &EnumSpecifier{Case: EnumSpecifierDef, AttributeSpecifierList: attr, Token: t, Token2: t2, Token3: t3, EnumeratorList: list, Token4: t4, Token5: t5, lexicalScope: p.declScope}
|
---|
2139 | if t2.Value != 0 {
|
---|
2140 | p.declScope.declare(t2.Value, r)
|
---|
2141 | }
|
---|
2142 | return r
|
---|
2143 | }
|
---|
2144 |
|
---|
2145 | // enumerator-list:
|
---|
2146 | // enumerator
|
---|
2147 | // enumerator-list , enumerator
|
---|
2148 | func (p *parser) enumeratorList() *EnumeratorList {
|
---|
2149 | r := &EnumeratorList{Enumerator: p.enumerator()}
|
---|
2150 | for prev := r; ; prev = prev.EnumeratorList {
|
---|
2151 | switch p.rune() {
|
---|
2152 | case ',':
|
---|
2153 | if p.peek(false) == '}' {
|
---|
2154 | return r
|
---|
2155 | }
|
---|
2156 |
|
---|
2157 | t := p.shift()
|
---|
2158 | prev.EnumeratorList = &EnumeratorList{Token: t, Enumerator: p.enumerator()}
|
---|
2159 | default:
|
---|
2160 | return r
|
---|
2161 | }
|
---|
2162 | }
|
---|
2163 | }
|
---|
2164 |
|
---|
2165 | // enumerator:
|
---|
2166 | // enumeration-constant attribute-specifier-list_opt
|
---|
2167 | // enumeration-constant attribute-specifier-list_opt = constant-expression
|
---|
2168 | func (p *parser) enumerator() (r *Enumerator) {
|
---|
2169 | if p.rune() != IDENTIFIER {
|
---|
2170 | p.err("expected enumeration-constant")
|
---|
2171 | return nil
|
---|
2172 | }
|
---|
2173 |
|
---|
2174 | t := p.shift()
|
---|
2175 | attr := p.attributeSpecifierListOpt()
|
---|
2176 | // if attr != nil {
|
---|
2177 | // trc("%v: ATTRS", attr.Position())
|
---|
2178 | // }
|
---|
2179 | if p.rune() != '=' {
|
---|
2180 | r = &Enumerator{Case: EnumeratorIdent, Token: t, AttributeSpecifierList: attr, lexicalScope: p.declScope}
|
---|
2181 | p.declScope.declare(t.Value, r)
|
---|
2182 | return r
|
---|
2183 | }
|
---|
2184 |
|
---|
2185 | t2 := p.shift()
|
---|
2186 | r = &Enumerator{Case: EnumeratorExpr, Token: t, AttributeSpecifierList: attr, Token2: t2, ConstantExpression: p.constantExpression(), lexicalScope: p.declScope}
|
---|
2187 | p.declScope.declare(t.Value, r)
|
---|
2188 | return r
|
---|
2189 | }
|
---|
2190 |
|
---|
2191 | // [2], 6.7.2.4 Atomic type specifiers
|
---|
2192 | //
|
---|
2193 | // atomic-type-specifier:
|
---|
2194 | // _Atomic ( type-name )
|
---|
2195 | func (p *parser) atomicTypeSpecifier() *AtomicTypeSpecifier {
|
---|
2196 | if p.rune() != ATOMIC {
|
---|
2197 | p.err("expected _Atomic")
|
---|
2198 | return nil
|
---|
2199 | }
|
---|
2200 |
|
---|
2201 | t := p.shift()
|
---|
2202 | var t2, t3 Token
|
---|
2203 | switch p.rune() {
|
---|
2204 | case '(':
|
---|
2205 | t2 = p.shift()
|
---|
2206 | default:
|
---|
2207 | p.err("expected (")
|
---|
2208 | }
|
---|
2209 | typ := p.typeName()
|
---|
2210 | switch p.rune() {
|
---|
2211 | case ')':
|
---|
2212 | t3 = p.shift()
|
---|
2213 | default:
|
---|
2214 | p.err("expected )")
|
---|
2215 | }
|
---|
2216 | return &AtomicTypeSpecifier{Token: t, Token2: t2, TypeName: typ, Token3: t3}
|
---|
2217 | }
|
---|
2218 |
|
---|
2219 | // [0], 6.7.3 Type qualifiers
|
---|
2220 | //
|
---|
2221 | // type-qualifier:
|
---|
2222 | // const
|
---|
2223 | // restrict
|
---|
2224 | // volatile
|
---|
2225 | // _Atomic
|
---|
2226 | func (p *parser) typeQualifier() *TypeQualifier {
|
---|
2227 | switch p.rune() {
|
---|
2228 | case CONST:
|
---|
2229 | return &TypeQualifier{Case: TypeQualifierConst, Token: p.shift()}
|
---|
2230 | case RESTRICT:
|
---|
2231 | return &TypeQualifier{Case: TypeQualifierRestrict, Token: p.shift()}
|
---|
2232 | case VOLATILE:
|
---|
2233 | return &TypeQualifier{Case: TypeQualifierVolatile, Token: p.shift()}
|
---|
2234 | case ATOMIC:
|
---|
2235 | return &TypeQualifier{Case: TypeQualifierAtomic, Token: p.shift()}
|
---|
2236 | default:
|
---|
2237 | p.err("expected type-qualifier")
|
---|
2238 | return nil
|
---|
2239 | }
|
---|
2240 | }
|
---|
2241 |
|
---|
2242 | // [0], 6.7.4 Function specifiers
|
---|
2243 | //
|
---|
2244 | // function-specifier:
|
---|
2245 | // inline
|
---|
2246 | // _Noreturn
|
---|
2247 | func (p *parser) functionSpecifier(inline *bool) *FunctionSpecifier {
|
---|
2248 | switch p.rune() {
|
---|
2249 | case INLINE:
|
---|
2250 | if inline != nil {
|
---|
2251 | *inline = true
|
---|
2252 | }
|
---|
2253 | return &FunctionSpecifier{Case: FunctionSpecifierInline, Token: p.shift()}
|
---|
2254 | case NORETURN:
|
---|
2255 | return &FunctionSpecifier{Case: FunctionSpecifierNoreturn, Token: p.shift()}
|
---|
2256 | default:
|
---|
2257 | p.err("expected function-specifier")
|
---|
2258 | return nil
|
---|
2259 | }
|
---|
2260 | }
|
---|
2261 |
|
---|
2262 | // [0], 6.7.5 Declarators
|
---|
2263 | //
|
---|
2264 | // declarator:
|
---|
2265 | // pointer_opt direct-declarator attribute-specifier-list_opt
|
---|
2266 | func (p *parser) declarator(declare, isTypedefName bool, ptr *Pointer) *Declarator {
|
---|
2267 | if ptr == nil && (p.rune() == '*' || p.rune() == '^') {
|
---|
2268 | ptr = p.pointer()
|
---|
2269 | }
|
---|
2270 | r := &Declarator{IsTypedefName: isTypedefName, Pointer: ptr, DirectDeclarator: p.directDeclarator(nil)}
|
---|
2271 | r.AttributeSpecifierList = p.attributeSpecifierListOpt()
|
---|
2272 | // if r.AttributeSpecifierList != nil {
|
---|
2273 | // trc("%v: ATTRS", r.AttributeSpecifierList.Position())
|
---|
2274 | // }
|
---|
2275 | if declare {
|
---|
2276 | p.declScope.declare(r.Name(), r)
|
---|
2277 | }
|
---|
2278 | return r
|
---|
2279 | }
|
---|
2280 |
|
---|
2281 | // [2], 6.7.5 Alignment specifier
|
---|
2282 | //
|
---|
2283 | // alignment-specifier:
|
---|
2284 | // _Alignas ( type-name )
|
---|
2285 | // _Alignas ( constant-expression )
|
---|
2286 | func (p *parser) alignmentSpecifier() *AlignmentSpecifier {
|
---|
2287 | if p.rune() != ALIGNAS {
|
---|
2288 | p.err("expected _Alignas")
|
---|
2289 | return nil
|
---|
2290 | }
|
---|
2291 |
|
---|
2292 | t := p.shift()
|
---|
2293 | var t2, t3 Token
|
---|
2294 | switch p.rune() {
|
---|
2295 | case '(':
|
---|
2296 | t2 = p.shift()
|
---|
2297 | default:
|
---|
2298 | p.err("expected (")
|
---|
2299 | }
|
---|
2300 | switch p.rune() {
|
---|
2301 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
2302 | ATTRIBUTE, CONST, RESTRICT, VOLATILE,
|
---|
2303 | ALIGNAS:
|
---|
2304 | typ := p.typeName()
|
---|
2305 | switch p.rune() {
|
---|
2306 | case ')':
|
---|
2307 | t3 = p.shift()
|
---|
2308 | default:
|
---|
2309 | p.err("expected )")
|
---|
2310 | }
|
---|
2311 | return &AlignmentSpecifier{Case: AlignmentSpecifierAlignasType, Token: t, Token2: t2, TypeName: typ, Token3: t3}
|
---|
2312 | default:
|
---|
2313 | e := p.constantExpression()
|
---|
2314 | switch p.rune() {
|
---|
2315 | case ')':
|
---|
2316 | t3 = p.shift()
|
---|
2317 | default:
|
---|
2318 | p.err("expected )")
|
---|
2319 | }
|
---|
2320 | return &AlignmentSpecifier{Case: AlignmentSpecifierAlignasExpr, Token: t, Token2: t2, ConstantExpression: e, Token3: t3}
|
---|
2321 | }
|
---|
2322 | }
|
---|
2323 |
|
---|
2324 | // direct-declarator:
|
---|
2325 | // identifier asm_opt
|
---|
2326 | // ( attribute-specifier-list_opt declarator )
|
---|
2327 | // direct-declarator [ type-qualifier-list_opt assignment-expression_opt ]
|
---|
2328 | // direct-declarator [ static type-qualifier-list_opt assignment-expression ]
|
---|
2329 | // direct-declarator [ type-qualifier-list static assignment-expression ]
|
---|
2330 | // direct-declarator [ type-qualifier-list_opt * ]
|
---|
2331 | // direct-declarator ( parameter-type-list )
|
---|
2332 | // direct-declarator ( identifier-list_opt )
|
---|
2333 | func (p *parser) directDeclarator(d *DirectDeclarator) (r *DirectDeclarator) {
|
---|
2334 | switch {
|
---|
2335 | case d != nil:
|
---|
2336 | r = d
|
---|
2337 | default:
|
---|
2338 | switch p.rune() {
|
---|
2339 | case IDENTIFIER:
|
---|
2340 | t := p.shift()
|
---|
2341 | var a *Asm
|
---|
2342 | if p.rune() == ASM {
|
---|
2343 | a = p.asm()
|
---|
2344 | }
|
---|
2345 | r = &DirectDeclarator{Case: DirectDeclaratorIdent, Token: t, Asm: a, lexicalScope: p.declScope}
|
---|
2346 | case '(':
|
---|
2347 | t := p.shift()
|
---|
2348 | attr := p.attributeSpecifierListOpt()
|
---|
2349 | // if attr != nil {
|
---|
2350 | // trc("%v: ATTRS", attr.Position())
|
---|
2351 | // }
|
---|
2352 | d := p.declarator(false, false, nil)
|
---|
2353 | var t2 Token
|
---|
2354 | switch p.rune() {
|
---|
2355 | case ')':
|
---|
2356 | t2 = p.shift()
|
---|
2357 | default:
|
---|
2358 | p.err("expected )")
|
---|
2359 | }
|
---|
2360 | r = &DirectDeclarator{Case: DirectDeclaratorDecl, Token: t, AttributeSpecifierList: attr, Declarator: d, Token2: t2, lexicalScope: p.declScope}
|
---|
2361 | default:
|
---|
2362 | p.err("expected direct-declarator")
|
---|
2363 | return nil
|
---|
2364 | }
|
---|
2365 | }
|
---|
2366 |
|
---|
2367 | var t, t2, t3 Token
|
---|
2368 | for {
|
---|
2369 | var e *AssignmentExpression
|
---|
2370 | switch p.rune() {
|
---|
2371 | case '[':
|
---|
2372 | t = p.shift()
|
---|
2373 | switch p.rune() {
|
---|
2374 | case ']':
|
---|
2375 | t2 = p.shift()
|
---|
2376 | r = &DirectDeclarator{Case: DirectDeclaratorArr, DirectDeclarator: r, Token: t, Token2: t2, lexicalScope: p.declScope}
|
---|
2377 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC: // type-qualifier
|
---|
2378 | list := p.typeQualifierList()
|
---|
2379 | switch p.rune() {
|
---|
2380 | case STATIC:
|
---|
2381 | t2 = p.shift()
|
---|
2382 | e = p.assignmentExpression()
|
---|
2383 | switch p.rune() {
|
---|
2384 | case ']':
|
---|
2385 | t3 = p.shift()
|
---|
2386 | default:
|
---|
2387 | p.err("expected ]")
|
---|
2388 | }
|
---|
2389 | r = &DirectDeclarator{Case: DirectDeclaratorArrStatic, DirectDeclarator: r, Token: t, TypeQualifiers: list, Token2: t2, AssignmentExpression: e, Token3: t3, lexicalScope: p.declScope}
|
---|
2390 | case ']':
|
---|
2391 | r = &DirectDeclarator{Case: DirectDeclaratorArr, DirectDeclarator: r, Token: t, TypeQualifiers: list, Token2: p.shift(), lexicalScope: p.declScope}
|
---|
2392 | case '*':
|
---|
2393 | switch p.peek(false) {
|
---|
2394 | case ']':
|
---|
2395 | t2 = p.shift()
|
---|
2396 | r = &DirectDeclarator{Case: DirectDeclaratorStar, DirectDeclarator: r, Token: t, TypeQualifiers: list, Token2: t2, Token3: p.shift(), lexicalScope: p.declScope}
|
---|
2397 | default:
|
---|
2398 | e = p.assignmentExpression()
|
---|
2399 | switch p.rune() {
|
---|
2400 | case ']':
|
---|
2401 | t2 = p.shift()
|
---|
2402 | default:
|
---|
2403 | p.err("expected ]")
|
---|
2404 | }
|
---|
2405 | r = &DirectDeclarator{Case: DirectDeclaratorArr, DirectDeclarator: r, Token: t, TypeQualifiers: list, AssignmentExpression: e, Token2: t2, lexicalScope: p.declScope}
|
---|
2406 | }
|
---|
2407 | default:
|
---|
2408 | e = p.assignmentExpression()
|
---|
2409 | switch p.rune() {
|
---|
2410 | case ']':
|
---|
2411 | t2 = p.shift()
|
---|
2412 | default:
|
---|
2413 | p.err("expected ]")
|
---|
2414 | }
|
---|
2415 | r = &DirectDeclarator{Case: DirectDeclaratorArr, DirectDeclarator: r, Token: t, TypeQualifiers: list, AssignmentExpression: e, Token2: t2, lexicalScope: p.declScope}
|
---|
2416 | }
|
---|
2417 | case STATIC:
|
---|
2418 | t2 := p.shift()
|
---|
2419 | var list *TypeQualifiers
|
---|
2420 | switch p.peek(false) {
|
---|
2421 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2422 | list = p.typeQualifierList()
|
---|
2423 | }
|
---|
2424 | e := p.assignmentExpression()
|
---|
2425 | switch p.rune() {
|
---|
2426 | case ']':
|
---|
2427 | t3 = p.shift()
|
---|
2428 | default:
|
---|
2429 | p.err("expected ]")
|
---|
2430 | }
|
---|
2431 | r = &DirectDeclarator{Case: DirectDeclaratorStaticArr, DirectDeclarator: r, Token: t, Token2: t2, TypeQualifiers: list, AssignmentExpression: e, Token3: t3, lexicalScope: p.declScope}
|
---|
2432 | case '*':
|
---|
2433 | if p.peek(false) == ']' {
|
---|
2434 | t2 = p.shift()
|
---|
2435 | r = &DirectDeclarator{Case: DirectDeclaratorStar, DirectDeclarator: r, Token: t, Token2: t2, Token3: p.shift(), lexicalScope: p.declScope}
|
---|
2436 | break
|
---|
2437 | }
|
---|
2438 |
|
---|
2439 | fallthrough
|
---|
2440 | default:
|
---|
2441 | e = p.assignmentExpression()
|
---|
2442 | switch p.rune() {
|
---|
2443 | case ']':
|
---|
2444 | t2 = p.shift()
|
---|
2445 | default:
|
---|
2446 | p.err("expected ]")
|
---|
2447 | }
|
---|
2448 | r = &DirectDeclarator{Case: DirectDeclaratorArr, DirectDeclarator: r, Token: t, AssignmentExpression: e, Token2: t2, lexicalScope: p.declScope}
|
---|
2449 | }
|
---|
2450 | case '(':
|
---|
2451 | p.openScope(false)
|
---|
2452 | p.typedefNameEnabled = true
|
---|
2453 | t = p.shift()
|
---|
2454 | paramScope := p.declScope
|
---|
2455 | switch p.rune() {
|
---|
2456 | case IDENTIFIER:
|
---|
2457 | list := p.identifierList()
|
---|
2458 | p.closeScope()
|
---|
2459 | p.typedefNameEnabled = true
|
---|
2460 | switch p.rune() {
|
---|
2461 | case ')':
|
---|
2462 | t2 = p.shift()
|
---|
2463 | default:
|
---|
2464 | p.err("expected )")
|
---|
2465 | }
|
---|
2466 | r = &DirectDeclarator{Case: DirectDeclaratorFuncIdent, DirectDeclarator: r, Token: t, IdentifierList: list, Token2: t2, paramScope: paramScope, lexicalScope: p.declScope}
|
---|
2467 | case ')':
|
---|
2468 | p.closeScope()
|
---|
2469 | p.typedefNameEnabled = true
|
---|
2470 | r = &DirectDeclarator{Case: DirectDeclaratorFuncIdent, DirectDeclarator: r, Token: t, Token2: p.shift(), paramScope: paramScope, lexicalScope: p.declScope}
|
---|
2471 | default:
|
---|
2472 | list := p.parameterTypeList()
|
---|
2473 | p.closeScope()
|
---|
2474 | p.typedefNameEnabled = true
|
---|
2475 | switch p.rune() {
|
---|
2476 | case ')':
|
---|
2477 | t2 = p.shift()
|
---|
2478 | default:
|
---|
2479 | p.err("expected )")
|
---|
2480 | }
|
---|
2481 | r = &DirectDeclarator{Case: DirectDeclaratorFuncParam, DirectDeclarator: r, Token: t, ParameterTypeList: list, Token2: t2, paramScope: paramScope, lexicalScope: p.declScope}
|
---|
2482 | }
|
---|
2483 | default:
|
---|
2484 | return r
|
---|
2485 | }
|
---|
2486 | }
|
---|
2487 | }
|
---|
2488 |
|
---|
2489 | // pointer:
|
---|
2490 | // * type-qualifier-list_opt
|
---|
2491 | // * type-qualifier-list_opt pointer
|
---|
2492 | // ^ type-qualifier-list_opt
|
---|
2493 | func (p *parser) pointer() (r *Pointer) {
|
---|
2494 | if p.rune() == '^' {
|
---|
2495 | t := p.shift()
|
---|
2496 | var list *TypeQualifiers
|
---|
2497 | switch p.rune() {
|
---|
2498 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2499 | list = p.typeQualifierList()
|
---|
2500 | }
|
---|
2501 |
|
---|
2502 | return &Pointer{Case: PointerBlock, Token: t, TypeQualifiers: list}
|
---|
2503 | }
|
---|
2504 |
|
---|
2505 | if p.rune() != '*' {
|
---|
2506 | p.err("expected * or ^")
|
---|
2507 | return nil
|
---|
2508 | }
|
---|
2509 |
|
---|
2510 | t := p.shift()
|
---|
2511 | var list *TypeQualifiers
|
---|
2512 | switch p.rune() {
|
---|
2513 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2514 | list = p.typeQualifierList()
|
---|
2515 | }
|
---|
2516 |
|
---|
2517 | switch p.rune() {
|
---|
2518 | case '*':
|
---|
2519 | return &Pointer{Case: PointerPtr, Token: t, TypeQualifiers: list, Pointer: p.pointer()}
|
---|
2520 | default:
|
---|
2521 | return &Pointer{Case: PointerTypeQual, Token: t, TypeQualifiers: list}
|
---|
2522 | }
|
---|
2523 | }
|
---|
2524 |
|
---|
2525 | // type-qualifier-list:
|
---|
2526 | // type-qualifier
|
---|
2527 | // attribute-specifier
|
---|
2528 | // type-qualifier-list type-qualifier
|
---|
2529 | // type-qualifier-list attribute-specifier
|
---|
2530 | func (p *parser) typeQualifierList() (r *TypeQualifiers) {
|
---|
2531 | switch p.rune() {
|
---|
2532 | case ATTRIBUTE:
|
---|
2533 | r = &TypeQualifiers{Case: TypeQualifiersAttribute, AttributeSpecifier: p.attributeSpecifier()}
|
---|
2534 | default:
|
---|
2535 | r = &TypeQualifiers{Case: TypeQualifiersTypeQual, TypeQualifier: p.typeQualifier()}
|
---|
2536 | }
|
---|
2537 | for prev := r; ; prev = prev.TypeQualifiers {
|
---|
2538 | switch p.rune() {
|
---|
2539 | case ATTRIBUTE:
|
---|
2540 | prev.TypeQualifiers = &TypeQualifiers{Case: TypeQualifiersAttribute, AttributeSpecifier: p.attributeSpecifier()}
|
---|
2541 | case CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2542 | prev.TypeQualifiers = &TypeQualifiers{TypeQualifier: p.typeQualifier()}
|
---|
2543 | default:
|
---|
2544 | return r
|
---|
2545 | }
|
---|
2546 | }
|
---|
2547 | }
|
---|
2548 |
|
---|
2549 | // parameter-type-list:
|
---|
2550 | // parameter-list
|
---|
2551 | // parameter-list , ...
|
---|
2552 | func (p *parser) parameterTypeList() *ParameterTypeList {
|
---|
2553 | list := p.parameterList()
|
---|
2554 | switch p.rune() {
|
---|
2555 | case ',':
|
---|
2556 | t := p.shift()
|
---|
2557 | var t2 Token
|
---|
2558 | switch p.rune() {
|
---|
2559 | case DDD:
|
---|
2560 | t2 = p.shift()
|
---|
2561 | default:
|
---|
2562 | p.err("expected ...")
|
---|
2563 | }
|
---|
2564 | return &ParameterTypeList{Case: ParameterTypeListVar, ParameterList: list, Token: t, Token2: t2}
|
---|
2565 | default:
|
---|
2566 | return &ParameterTypeList{Case: ParameterTypeListList, ParameterList: list}
|
---|
2567 | }
|
---|
2568 | }
|
---|
2569 |
|
---|
2570 | // parameter-list:
|
---|
2571 | // parameter-declaration
|
---|
2572 | // parameter-list , parameter-declaration
|
---|
2573 | func (p *parser) parameterList() (r *ParameterList) {
|
---|
2574 | r = &ParameterList{ParameterDeclaration: p.parameterDeclaration()}
|
---|
2575 | for prev := r; ; prev = prev.ParameterList {
|
---|
2576 | switch p.rune() {
|
---|
2577 | case ';':
|
---|
2578 | if p.ctx.cfg.RejectParamSemicolon {
|
---|
2579 | p.err0(false, "expected ,")
|
---|
2580 | }
|
---|
2581 | fallthrough
|
---|
2582 | case ',':
|
---|
2583 | if p.peek(false) == DDD {
|
---|
2584 | return r
|
---|
2585 | }
|
---|
2586 |
|
---|
2587 | p.typedefNameEnabled = true
|
---|
2588 | t := p.shift()
|
---|
2589 | prev.ParameterList = &ParameterList{Token: t, ParameterDeclaration: p.parameterDeclaration()}
|
---|
2590 | default:
|
---|
2591 | return r
|
---|
2592 | }
|
---|
2593 | }
|
---|
2594 | }
|
---|
2595 |
|
---|
2596 | // parameter-declaration:
|
---|
2597 | // declaration-specifiers declarator attribute-specifier-list_opt
|
---|
2598 | // declaration-specifiers abstract-declarator_opt
|
---|
2599 | func (p *parser) parameterDeclaration() *ParameterDeclaration {
|
---|
2600 | ds := p.declarationSpecifiers(nil, nil)
|
---|
2601 | switch p.rune() {
|
---|
2602 | case ',', ')':
|
---|
2603 | r := &ParameterDeclaration{Case: ParameterDeclarationAbstract, DeclarationSpecifiers: ds}
|
---|
2604 | return r
|
---|
2605 | default:
|
---|
2606 | switch x := p.declaratorOrAbstractDeclarator(ds.typedef()).(type) {
|
---|
2607 | case *AbstractDeclarator:
|
---|
2608 | return &ParameterDeclaration{Case: ParameterDeclarationAbstract, DeclarationSpecifiers: ds, AbstractDeclarator: x}
|
---|
2609 | case *Declarator:
|
---|
2610 | p.declScope.declare(x.Name(), x)
|
---|
2611 | attr := p.attributeSpecifierListOpt()
|
---|
2612 | // if attr != nil {
|
---|
2613 | // trc("%v: ATTRS", attr.Position())
|
---|
2614 | // }
|
---|
2615 | return &ParameterDeclaration{Case: ParameterDeclarationDecl, DeclarationSpecifiers: ds, Declarator: x, AttributeSpecifierList: attr}
|
---|
2616 | default:
|
---|
2617 | panic(internalError())
|
---|
2618 | }
|
---|
2619 | }
|
---|
2620 | }
|
---|
2621 |
|
---|
2622 | func (p *parser) declaratorOrAbstractDeclarator(isTypedefName bool) (r Node) {
|
---|
2623 | var ptr *Pointer
|
---|
2624 | switch p.rune() {
|
---|
2625 | case '*', '^':
|
---|
2626 | ptr = p.pointer()
|
---|
2627 | }
|
---|
2628 | switch p.rune() {
|
---|
2629 | case IDENTIFIER:
|
---|
2630 | return p.declarator(false, isTypedefName, ptr)
|
---|
2631 | case '[':
|
---|
2632 | return p.abstractDeclarator(ptr)
|
---|
2633 | case '(':
|
---|
2634 | switch p.peek(true) {
|
---|
2635 | case ')':
|
---|
2636 | t := p.shift()
|
---|
2637 | t2 := p.shift()
|
---|
2638 | return &AbstractDeclarator{
|
---|
2639 | Case: AbstractDeclaratorDecl,
|
---|
2640 | Pointer: ptr,
|
---|
2641 | DirectAbstractDeclarator: p.directAbstractDeclarator(
|
---|
2642 | &DirectAbstractDeclarator{
|
---|
2643 | Case: DirectAbstractDeclaratorFunc,
|
---|
2644 | Token: t,
|
---|
2645 | Token2: t2,
|
---|
2646 | },
|
---|
2647 | ),
|
---|
2648 | }
|
---|
2649 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL,
|
---|
2650 | VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
2651 | CONST, RESTRICT, VOLATILE,
|
---|
2652 | INLINE, NORETURN, ATTRIBUTE,
|
---|
2653 | ALIGNAS:
|
---|
2654 | p.openScope(false)
|
---|
2655 | paramScope := p.declScope
|
---|
2656 | p.typedefNameEnabled = true
|
---|
2657 | t := p.shift()
|
---|
2658 | list := p.parameterTypeList()
|
---|
2659 | p.closeScope()
|
---|
2660 | p.typedefNameEnabled = true
|
---|
2661 | var t2 Token
|
---|
2662 | switch p.rune() {
|
---|
2663 | case ')':
|
---|
2664 | t2 = p.shift()
|
---|
2665 | default:
|
---|
2666 | p.err("expected )")
|
---|
2667 | }
|
---|
2668 | return &AbstractDeclarator{
|
---|
2669 | Case: AbstractDeclaratorDecl,
|
---|
2670 | Pointer: ptr,
|
---|
2671 | DirectAbstractDeclarator: p.directAbstractDeclarator(
|
---|
2672 | &DirectAbstractDeclarator{
|
---|
2673 | Case: DirectAbstractDeclaratorFunc,
|
---|
2674 | Token: t,
|
---|
2675 | ParameterTypeList: list,
|
---|
2676 | Token2: t2,
|
---|
2677 | paramScope: paramScope,
|
---|
2678 | },
|
---|
2679 | ),
|
---|
2680 | }
|
---|
2681 | }
|
---|
2682 |
|
---|
2683 | t := p.shift()
|
---|
2684 | switch x := p.declaratorOrAbstractDeclarator(isTypedefName).(type) {
|
---|
2685 | case *AbstractDeclarator:
|
---|
2686 | var t2 Token
|
---|
2687 | switch p.rune() {
|
---|
2688 | case ')':
|
---|
2689 | t2 = p.shift()
|
---|
2690 | default:
|
---|
2691 | p.err("expected )")
|
---|
2692 | }
|
---|
2693 | return &AbstractDeclarator{
|
---|
2694 | Case: AbstractDeclaratorDecl,
|
---|
2695 | Pointer: ptr,
|
---|
2696 | DirectAbstractDeclarator: p.directAbstractDeclarator(
|
---|
2697 | &DirectAbstractDeclarator{
|
---|
2698 | Case: DirectAbstractDeclaratorDecl,
|
---|
2699 | Token: t,
|
---|
2700 | AbstractDeclarator: x,
|
---|
2701 | Token2: t2,
|
---|
2702 | },
|
---|
2703 | ),
|
---|
2704 | }
|
---|
2705 | case *Declarator:
|
---|
2706 | var t2 Token
|
---|
2707 | switch p.rune() {
|
---|
2708 | case ')':
|
---|
2709 | t2 = p.shift()
|
---|
2710 | default:
|
---|
2711 | p.err("expected )")
|
---|
2712 | }
|
---|
2713 | return &Declarator{
|
---|
2714 | Pointer: ptr,
|
---|
2715 | DirectDeclarator: p.directDeclarator(
|
---|
2716 | &DirectDeclarator{
|
---|
2717 | Case: DirectDeclaratorDecl,
|
---|
2718 | Token: t,
|
---|
2719 | Declarator: x,
|
---|
2720 | Token2: t2,
|
---|
2721 | },
|
---|
2722 | ),
|
---|
2723 | }
|
---|
2724 | default:
|
---|
2725 | panic(internalError())
|
---|
2726 | }
|
---|
2727 | case ')', ',':
|
---|
2728 | return p.abstractDeclarator(ptr)
|
---|
2729 | default:
|
---|
2730 | p.err("unexpected %s", p.tok.Value)
|
---|
2731 | return p.abstractDeclarator(ptr)
|
---|
2732 | }
|
---|
2733 | }
|
---|
2734 |
|
---|
2735 | // identifier-list:
|
---|
2736 | // identifier
|
---|
2737 | // identifier-list , identifier
|
---|
2738 | func (p *parser) identifierList() (r *IdentifierList) {
|
---|
2739 | switch p.rune() {
|
---|
2740 | case IDENTIFIER:
|
---|
2741 | r = &IdentifierList{Token: p.shift(), lexicalScope: p.declScope}
|
---|
2742 | default:
|
---|
2743 | p.err("expected identifier")
|
---|
2744 | return nil
|
---|
2745 | }
|
---|
2746 |
|
---|
2747 | for prev := r; p.rune() == ','; prev = prev.IdentifierList {
|
---|
2748 | t := p.shift()
|
---|
2749 | var t2 Token
|
---|
2750 | switch p.rune() {
|
---|
2751 | case IDENTIFIER:
|
---|
2752 | t2 = p.shift()
|
---|
2753 | default:
|
---|
2754 | p.err("expected identifier")
|
---|
2755 | }
|
---|
2756 | prev.IdentifierList = &IdentifierList{Token: t, Token2: t2, lexicalScope: p.declScope}
|
---|
2757 | }
|
---|
2758 | return r
|
---|
2759 | }
|
---|
2760 |
|
---|
2761 | // [0], 6.7.6 Type names
|
---|
2762 | //
|
---|
2763 | // type-name:
|
---|
2764 | // specifier-qualifier-list abstract-declarator_opt
|
---|
2765 | func (p *parser) typeName() *TypeName {
|
---|
2766 | p.typedefNameEnabled = true
|
---|
2767 | list := p.specifierQualifierList()
|
---|
2768 | switch p.rune() {
|
---|
2769 | case ')', ',':
|
---|
2770 | return &TypeName{SpecifierQualifierList: list}
|
---|
2771 | case '*', '(', '[':
|
---|
2772 | return &TypeName{SpecifierQualifierList: list, AbstractDeclarator: p.abstractDeclarator(nil)}
|
---|
2773 | default:
|
---|
2774 | p.err("expected ) or * or ( or [ or ,")
|
---|
2775 | return &TypeName{SpecifierQualifierList: list}
|
---|
2776 | }
|
---|
2777 | }
|
---|
2778 |
|
---|
2779 | // abstract-declarator:
|
---|
2780 | // pointer
|
---|
2781 | // pointer_opt direct-abstract-declarator
|
---|
2782 | func (p *parser) abstractDeclarator(ptr *Pointer) *AbstractDeclarator {
|
---|
2783 | if ptr == nil && (p.rune() == '*' || p.rune() == '^') {
|
---|
2784 | ptr = p.pointer()
|
---|
2785 | }
|
---|
2786 | switch p.rune() {
|
---|
2787 | case '[', '(':
|
---|
2788 | return &AbstractDeclarator{Case: AbstractDeclaratorDecl, Pointer: ptr, DirectAbstractDeclarator: p.directAbstractDeclarator(nil)}
|
---|
2789 | default:
|
---|
2790 | return &AbstractDeclarator{Case: AbstractDeclaratorPtr, Pointer: ptr}
|
---|
2791 | }
|
---|
2792 | }
|
---|
2793 |
|
---|
2794 | // direct-abstract-declarator:
|
---|
2795 | // ( abstract-declarator )
|
---|
2796 | // direct-abstract-declarator_opt [ type-qualifier-list_opt assignment-expression_opt ]
|
---|
2797 | // direct-abstract-declarator_opt [ static type-qualifier-list_opt assignment-expression ]
|
---|
2798 | // direct-abstract-declarator_opt [ type-qualifier-list static assignment-expression ]
|
---|
2799 | // direct-abstract-declarator_opt [ * ]
|
---|
2800 | // direct-abstract-declarator_opt ( parameter-type-list_opt )
|
---|
2801 | func (p *parser) directAbstractDeclarator(d *DirectAbstractDeclarator) (r *DirectAbstractDeclarator) {
|
---|
2802 | var t, t2, t3 Token
|
---|
2803 | switch {
|
---|
2804 | case d != nil:
|
---|
2805 | r = d
|
---|
2806 | default:
|
---|
2807 | switch p.rune() {
|
---|
2808 | case '[':
|
---|
2809 | t = p.shift()
|
---|
2810 | switch p.rune() {
|
---|
2811 | case '*':
|
---|
2812 | t2 = p.shift()
|
---|
2813 | switch p.rune() {
|
---|
2814 | case ']':
|
---|
2815 | t3 = p.shift()
|
---|
2816 | default:
|
---|
2817 | p.err("expected ]")
|
---|
2818 | }
|
---|
2819 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArrStar, Token: t, Token2: t2, Token3: t3}
|
---|
2820 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2821 | list := p.typeQualifierList()
|
---|
2822 | switch p.rune() {
|
---|
2823 | case STATIC:
|
---|
2824 | t2 = p.shift()
|
---|
2825 | e := p.assignmentExpression()
|
---|
2826 | switch p.rune() {
|
---|
2827 | case ']':
|
---|
2828 | t3 = p.shift()
|
---|
2829 | default:
|
---|
2830 | p.err("expected ]")
|
---|
2831 | }
|
---|
2832 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArrStatic, Token: t, TypeQualifiers: list, Token2: t2, AssignmentExpression: e, Token3: t3}
|
---|
2833 | default:
|
---|
2834 | e := p.assignmentExpression()
|
---|
2835 | switch p.rune() {
|
---|
2836 | case ']':
|
---|
2837 | t2 = p.shift()
|
---|
2838 | default:
|
---|
2839 | p.err("expected ]")
|
---|
2840 | }
|
---|
2841 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArr, Token: t, TypeQualifiers: list, AssignmentExpression: e, Token2: t2}
|
---|
2842 | }
|
---|
2843 | case STATIC:
|
---|
2844 | t2 = p.shift()
|
---|
2845 | var list *TypeQualifiers
|
---|
2846 | switch p.rune() {
|
---|
2847 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2848 | list = p.typeQualifierList()
|
---|
2849 | }
|
---|
2850 | e := p.assignmentExpression()
|
---|
2851 | switch p.rune() {
|
---|
2852 | case ']':
|
---|
2853 | t3 = p.shift()
|
---|
2854 | default:
|
---|
2855 | p.err("expected ]")
|
---|
2856 | }
|
---|
2857 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorStaticArr, Token: t, Token2: t2, TypeQualifiers: list, AssignmentExpression: e, Token3: t3}
|
---|
2858 | case ']':
|
---|
2859 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArr, Token: t, Token2: p.shift()}
|
---|
2860 | default:
|
---|
2861 | e := p.assignmentExpression()
|
---|
2862 | switch p.rune() {
|
---|
2863 | case ']':
|
---|
2864 | t2 = p.shift()
|
---|
2865 | default:
|
---|
2866 | p.err("expected ]")
|
---|
2867 | }
|
---|
2868 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArr, Token: t, AssignmentExpression: e, Token2: t2}
|
---|
2869 | }
|
---|
2870 | case '(':
|
---|
2871 | switch p.peek(true) {
|
---|
2872 | case ')':
|
---|
2873 | t := p.shift()
|
---|
2874 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorFunc, Token: t, Token2: p.shift()}
|
---|
2875 | case VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
2876 | ATTRIBUTE, CONST, RESTRICT, VOLATILE,
|
---|
2877 | ALIGNAS:
|
---|
2878 | p.openScope(false)
|
---|
2879 | paramScope := p.declScope
|
---|
2880 | p.typedefNameEnabled = true
|
---|
2881 | t = p.shift()
|
---|
2882 | list := p.parameterTypeList()
|
---|
2883 | p.closeScope()
|
---|
2884 | p.typedefNameEnabled = true
|
---|
2885 | switch p.rune() {
|
---|
2886 | case ')':
|
---|
2887 | t2 = p.shift()
|
---|
2888 | default:
|
---|
2889 | p.err("expected )")
|
---|
2890 | }
|
---|
2891 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorFunc, Token: t, ParameterTypeList: list, Token2: t2, paramScope: paramScope}
|
---|
2892 | default:
|
---|
2893 | p.openScope(false)
|
---|
2894 | paramScope := p.declScope
|
---|
2895 | p.typedefNameEnabled = true
|
---|
2896 | t = p.shift()
|
---|
2897 | d := p.abstractDeclarator(nil)
|
---|
2898 | p.closeScope()
|
---|
2899 | p.typedefNameEnabled = true
|
---|
2900 | switch p.rune() {
|
---|
2901 | case ')':
|
---|
2902 | t2 = p.shift()
|
---|
2903 | default:
|
---|
2904 | p.err("expected )")
|
---|
2905 | }
|
---|
2906 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorDecl, Token: t, AbstractDeclarator: d, Token2: t2, paramScope: paramScope}
|
---|
2907 | }
|
---|
2908 | default:
|
---|
2909 | panic(internalError())
|
---|
2910 | }
|
---|
2911 | }
|
---|
2912 |
|
---|
2913 | for {
|
---|
2914 | switch p.rune() {
|
---|
2915 | case '(':
|
---|
2916 | if p.peek(false) == ')' {
|
---|
2917 | t = p.shift()
|
---|
2918 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorFunc, DirectAbstractDeclarator: r, Token: t, Token2: p.shift()}
|
---|
2919 | break
|
---|
2920 | }
|
---|
2921 |
|
---|
2922 | p.openScope(false)
|
---|
2923 | p.typedefNameEnabled = true
|
---|
2924 | t = p.shift()
|
---|
2925 | paramScope := p.declScope
|
---|
2926 | list := p.parameterTypeList()
|
---|
2927 | p.closeScope()
|
---|
2928 | p.typedefNameEnabled = true
|
---|
2929 | switch p.rune() {
|
---|
2930 | case ')':
|
---|
2931 | t2 = p.shift()
|
---|
2932 | default:
|
---|
2933 | p.err("expected )")
|
---|
2934 | }
|
---|
2935 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorFunc, DirectAbstractDeclarator: r, Token: t, ParameterTypeList: list, Token2: t2, paramScope: paramScope}
|
---|
2936 | case '[':
|
---|
2937 | t = p.shift()
|
---|
2938 | switch p.rune() {
|
---|
2939 | case '*':
|
---|
2940 | t2 = p.shift()
|
---|
2941 | switch p.rune() {
|
---|
2942 | case ']':
|
---|
2943 | t3 = p.shift()
|
---|
2944 | default:
|
---|
2945 | p.err("expected ]")
|
---|
2946 | }
|
---|
2947 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArrStar, DirectAbstractDeclarator: r, Token: t, Token2: t2, Token3: t3}
|
---|
2948 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2949 | list := p.typeQualifierList()
|
---|
2950 | switch p.rune() {
|
---|
2951 | case STATIC:
|
---|
2952 | t2 = p.shift()
|
---|
2953 | e := p.assignmentExpression()
|
---|
2954 | switch p.rune() {
|
---|
2955 | case ']':
|
---|
2956 | t3 = p.shift()
|
---|
2957 | default:
|
---|
2958 | p.err("expected ]")
|
---|
2959 | }
|
---|
2960 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArrStatic, DirectAbstractDeclarator: r, Token: t, TypeQualifiers: list, Token2: t2, AssignmentExpression: e, Token3: t3}
|
---|
2961 | default:
|
---|
2962 | e := p.assignmentExpression()
|
---|
2963 | switch p.rune() {
|
---|
2964 | case ']':
|
---|
2965 | t2 = p.shift()
|
---|
2966 | default:
|
---|
2967 | p.err("expected ]")
|
---|
2968 | }
|
---|
2969 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArr, DirectAbstractDeclarator: r, Token: t, TypeQualifiers: list, AssignmentExpression: e, Token2: t2}
|
---|
2970 | }
|
---|
2971 | case STATIC:
|
---|
2972 | t2 = p.shift()
|
---|
2973 | var list *TypeQualifiers
|
---|
2974 | switch p.rune() {
|
---|
2975 | case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC:
|
---|
2976 | list = p.typeQualifierList()
|
---|
2977 | }
|
---|
2978 | e := p.assignmentExpression()
|
---|
2979 | switch p.rune() {
|
---|
2980 | case ']':
|
---|
2981 | t3 = p.shift()
|
---|
2982 | default:
|
---|
2983 | p.err("expected ]")
|
---|
2984 | }
|
---|
2985 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorStaticArr, DirectAbstractDeclarator: r, Token: t, Token2: t2, TypeQualifiers: list, AssignmentExpression: e, Token3: t3}
|
---|
2986 | case ']':
|
---|
2987 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArr, DirectAbstractDeclarator: r, Token: t, Token2: p.shift()}
|
---|
2988 | default:
|
---|
2989 | e := p.assignmentExpression()
|
---|
2990 | switch p.rune() {
|
---|
2991 | case ']':
|
---|
2992 | t2 = p.shift()
|
---|
2993 | default:
|
---|
2994 | p.err("expected ]")
|
---|
2995 | }
|
---|
2996 | r = &DirectAbstractDeclarator{Case: DirectAbstractDeclaratorArr, DirectAbstractDeclarator: r, Token: t, AssignmentExpression: e, Token2: t2}
|
---|
2997 | }
|
---|
2998 | default:
|
---|
2999 | return r
|
---|
3000 | }
|
---|
3001 | }
|
---|
3002 | }
|
---|
3003 |
|
---|
3004 | // [0], 6.7.8 Initialization
|
---|
3005 | //
|
---|
3006 | // initializer:
|
---|
3007 | // assignment-expression
|
---|
3008 | // { initializer-list }
|
---|
3009 | // { initializer-list , }
|
---|
3010 | func (p *parser) initializer(parent *Initializer) *Initializer {
|
---|
3011 | switch p.rune() {
|
---|
3012 | case '{':
|
---|
3013 | t := p.shift()
|
---|
3014 | if p.peek(false) == '}' {
|
---|
3015 | if p.ctx.cfg.RejectEmptyInitializerList {
|
---|
3016 | p.err("expected initializer-list")
|
---|
3017 | }
|
---|
3018 | return &Initializer{Case: InitializerInitList, Token: t, Token3: p.shift()}
|
---|
3019 | }
|
---|
3020 |
|
---|
3021 | r := &Initializer{Case: InitializerInitList, Token: t, parent: parent}
|
---|
3022 | r.InitializerList = p.initializerList(r)
|
---|
3023 | if p.rune() == ',' {
|
---|
3024 | r.Token2 = p.shift()
|
---|
3025 | }
|
---|
3026 | switch p.rune() {
|
---|
3027 | case '}':
|
---|
3028 | r.Token3 = p.shift()
|
---|
3029 | default:
|
---|
3030 | p.err("expected }")
|
---|
3031 | }
|
---|
3032 | return r
|
---|
3033 | default:
|
---|
3034 | return &Initializer{Case: InitializerExpr, AssignmentExpression: p.assignmentExpression(), parent: parent}
|
---|
3035 | }
|
---|
3036 | }
|
---|
3037 |
|
---|
3038 | // initializer-list:
|
---|
3039 | // designation_opt initializer
|
---|
3040 | // initializer-list , designation_opt initializer
|
---|
3041 | func (p *parser) initializerList(parent *Initializer) (r *InitializerList) {
|
---|
3042 | var d *Designation
|
---|
3043 | switch p.rune() {
|
---|
3044 | case '[', '.':
|
---|
3045 | d = p.designation()
|
---|
3046 | case IDENTIFIER:
|
---|
3047 | if p.peek(false) == ':' {
|
---|
3048 | d = p.designation()
|
---|
3049 | }
|
---|
3050 | }
|
---|
3051 | r = &InitializerList{Designation: d, Initializer: p.initializer(parent)}
|
---|
3052 | for prev := r; ; prev = prev.InitializerList {
|
---|
3053 | switch p.rune() {
|
---|
3054 | case ',':
|
---|
3055 | t := p.tok
|
---|
3056 | prev.Initializer.trailingComma = &t
|
---|
3057 | if p.peek(false) == '}' {
|
---|
3058 | return r
|
---|
3059 | }
|
---|
3060 |
|
---|
3061 | t = p.shift()
|
---|
3062 | d = nil
|
---|
3063 | switch p.rune() {
|
---|
3064 | case '[', '.':
|
---|
3065 | d = p.designation()
|
---|
3066 | case IDENTIFIER:
|
---|
3067 | if p.peek(false) == ':' {
|
---|
3068 | d = p.designation()
|
---|
3069 | }
|
---|
3070 | }
|
---|
3071 | prev.InitializerList = &InitializerList{Token: t, Designation: d, Initializer: p.initializer(parent)}
|
---|
3072 | default:
|
---|
3073 | return r
|
---|
3074 | }
|
---|
3075 | }
|
---|
3076 | }
|
---|
3077 |
|
---|
3078 | // designation:
|
---|
3079 | // designator-list =
|
---|
3080 | func (p *parser) designation() *Designation {
|
---|
3081 | var t Token
|
---|
3082 | list, colon := p.designatorList()
|
---|
3083 | if !colon {
|
---|
3084 | switch p.rune() {
|
---|
3085 | case '=':
|
---|
3086 | t = p.shift()
|
---|
3087 | default:
|
---|
3088 | p.err("expected =")
|
---|
3089 | }
|
---|
3090 | }
|
---|
3091 | return &Designation{DesignatorList: list, Token: t}
|
---|
3092 | }
|
---|
3093 |
|
---|
3094 | // designator-list:
|
---|
3095 | // designator
|
---|
3096 | // designator-list designator
|
---|
3097 | func (p *parser) designatorList() (r *DesignatorList, colon bool) {
|
---|
3098 | d, isCol := p.designator(true)
|
---|
3099 | if isCol {
|
---|
3100 | return &DesignatorList{Designator: d}, true
|
---|
3101 | }
|
---|
3102 |
|
---|
3103 | r = &DesignatorList{Designator: d}
|
---|
3104 | for prev := r; ; prev = prev.DesignatorList {
|
---|
3105 | switch p.rune() {
|
---|
3106 | case '[', '.':
|
---|
3107 | d, _ = p.designator(false)
|
---|
3108 | prev.DesignatorList = &DesignatorList{Designator: d}
|
---|
3109 | default:
|
---|
3110 | return r, false
|
---|
3111 | }
|
---|
3112 | }
|
---|
3113 | }
|
---|
3114 |
|
---|
3115 | // designator:
|
---|
3116 | // [ constant-expression ]
|
---|
3117 | // . identifier
|
---|
3118 | // identifier :
|
---|
3119 | func (p *parser) designator(acceptCol bool) (*Designator, bool) {
|
---|
3120 | var t, t2 Token
|
---|
3121 | switch p.rune() {
|
---|
3122 | case '[':
|
---|
3123 | t = p.shift()
|
---|
3124 | e := p.constantExpression()
|
---|
3125 | switch p.rune() {
|
---|
3126 | case ']':
|
---|
3127 | t2 = p.shift()
|
---|
3128 | default:
|
---|
3129 | p.err("expected ]")
|
---|
3130 | }
|
---|
3131 | return &Designator{Case: DesignatorIndex, Token: t, ConstantExpression: e, Token2: t2, lexicalScope: p.declScope}, false
|
---|
3132 | case '.':
|
---|
3133 | t = p.shift()
|
---|
3134 | switch p.rune() {
|
---|
3135 | case IDENTIFIER:
|
---|
3136 | t2 = p.shift()
|
---|
3137 | default:
|
---|
3138 | p.err("expected identifier")
|
---|
3139 | }
|
---|
3140 | return &Designator{Case: DesignatorField, Token: t, Token2: t2, lexicalScope: p.declScope}, false
|
---|
3141 | case IDENTIFIER:
|
---|
3142 | if acceptCol && p.peek(false) == ':' {
|
---|
3143 | t = p.shift()
|
---|
3144 | return &Designator{Case: DesignatorField2, Token: t, Token2: p.shift(), lexicalScope: p.declScope}, true
|
---|
3145 | }
|
---|
3146 |
|
---|
3147 | p.err("expected designator")
|
---|
3148 | return nil, false
|
---|
3149 | default:
|
---|
3150 | p.err("expected [ or .")
|
---|
3151 | return nil, false
|
---|
3152 | }
|
---|
3153 | }
|
---|
3154 |
|
---|
3155 | // [0], 6.8 Statements and blocks
|
---|
3156 | //
|
---|
3157 | // statement:
|
---|
3158 | // labeled-statement
|
---|
3159 | // compound-statement
|
---|
3160 | // expression-statement
|
---|
3161 | // selection-statement
|
---|
3162 | // iteration-statement
|
---|
3163 | // jump-statement
|
---|
3164 | // asm-statement
|
---|
3165 | func (p *parser) statement() (r *Statement) {
|
---|
3166 | var r0 *Statement
|
---|
3167 | var prevLS, ls *LabeledStatement
|
---|
3168 |
|
---|
3169 | defer func() {
|
---|
3170 | if ls != nil {
|
---|
3171 | ls.Statement = r
|
---|
3172 | r = r0
|
---|
3173 | }
|
---|
3174 | }()
|
---|
3175 |
|
---|
3176 | for {
|
---|
3177 | switch p.rune() {
|
---|
3178 | case IDENTIFIER:
|
---|
3179 | switch {
|
---|
3180 | case p.peek(false) == ':':
|
---|
3181 | ls = p.labeledStatement()
|
---|
3182 | default:
|
---|
3183 | return &Statement{Case: StatementExpr, ExpressionStatement: p.expressionStatement()}
|
---|
3184 | }
|
---|
3185 | case '{':
|
---|
3186 | return &Statement{Case: StatementCompound, CompoundStatement: p.compoundStatement(nil, nil)}
|
---|
3187 | case IF, SWITCH:
|
---|
3188 | return &Statement{Case: StatementSelection, SelectionStatement: p.selectionStatement()}
|
---|
3189 | case WHILE, DO, FOR:
|
---|
3190 | return &Statement{Case: StatementIteration, IterationStatement: p.iterationStatement()}
|
---|
3191 | case GOTO, BREAK, CONTINUE, RETURN:
|
---|
3192 | return &Statement{Case: StatementJump, JumpStatement: p.jumpStatement()}
|
---|
3193 | case CASE, DEFAULT:
|
---|
3194 | ls = p.labeledStatement()
|
---|
3195 | case ASM:
|
---|
3196 | return &Statement{Case: StatementAsm, AsmStatement: p.asmStatement()}
|
---|
3197 | default:
|
---|
3198 | return &Statement{Case: StatementExpr, ExpressionStatement: p.expressionStatement()}
|
---|
3199 | }
|
---|
3200 |
|
---|
3201 | switch {
|
---|
3202 | case r0 == nil:
|
---|
3203 | r0 = &Statement{Case: StatementLabeled, LabeledStatement: ls}
|
---|
3204 | default:
|
---|
3205 | prevLS.Statement = &Statement{Case: StatementLabeled, LabeledStatement: ls}
|
---|
3206 | }
|
---|
3207 | prevLS = ls
|
---|
3208 | }
|
---|
3209 | }
|
---|
3210 |
|
---|
3211 | // [0], 6.8.1 Labeled statements
|
---|
3212 | //
|
---|
3213 | // labeled-statement:
|
---|
3214 | // identifier : statement
|
---|
3215 | // case constant-expression : statement
|
---|
3216 | // case constant-expression ... constant-expression : statement
|
---|
3217 | // default : statement
|
---|
3218 | func (p *parser) labeledStatement() (r *LabeledStatement) {
|
---|
3219 | defer func() {
|
---|
3220 | if r != nil {
|
---|
3221 | p.block.labeledStmts = append(p.block.labeledStmts, r)
|
---|
3222 | }
|
---|
3223 | }()
|
---|
3224 |
|
---|
3225 | var t, t2, t3 Token
|
---|
3226 | switch p.rune() {
|
---|
3227 | case IDENTIFIER:
|
---|
3228 | t = p.shift()
|
---|
3229 | switch p.rune() {
|
---|
3230 | case ':':
|
---|
3231 | t2 = p.shift()
|
---|
3232 | default:
|
---|
3233 | p.err("expected :")
|
---|
3234 | return nil
|
---|
3235 | }
|
---|
3236 |
|
---|
3237 | attr := p.attributeSpecifierListOpt()
|
---|
3238 | // if attr != nil {
|
---|
3239 | // trc("%v: ATTRS", attr.Position())
|
---|
3240 | // }
|
---|
3241 | p.block.hasLabel()
|
---|
3242 | r = &LabeledStatement{
|
---|
3243 | Case: LabeledStatementLabel, Token: t, Token2: t2, AttributeSpecifierList: attr,
|
---|
3244 | lexicalScope: p.declScope, block: p.block,
|
---|
3245 | }
|
---|
3246 | p.declScope.declare(t.Value, r)
|
---|
3247 | return r
|
---|
3248 | case CASE:
|
---|
3249 | if p.switches == 0 {
|
---|
3250 | p.err("case label not within a switch statement")
|
---|
3251 | }
|
---|
3252 | t = p.shift()
|
---|
3253 | e := p.constantExpression()
|
---|
3254 | switch p.rune() {
|
---|
3255 | case DDD:
|
---|
3256 | if p.ctx.cfg.RejectCaseRange {
|
---|
3257 | p.err0(false, "expected :")
|
---|
3258 | }
|
---|
3259 | t2 = p.shift()
|
---|
3260 | e2 := p.constantExpression()
|
---|
3261 | switch p.rune() {
|
---|
3262 | case ':':
|
---|
3263 | t3 = p.shift()
|
---|
3264 | default:
|
---|
3265 | p.err("expected :")
|
---|
3266 | }
|
---|
3267 | return &LabeledStatement{
|
---|
3268 | Case: LabeledStatementRange, Token: t, ConstantExpression: e,
|
---|
3269 | Token2: t2, ConstantExpression2: e2, Token3: t3,
|
---|
3270 | lexicalScope: p.declScope, block: p.block,
|
---|
3271 | }
|
---|
3272 | case ':':
|
---|
3273 | t2 = p.shift()
|
---|
3274 | default:
|
---|
3275 | p.err("expected :")
|
---|
3276 | }
|
---|
3277 | return &LabeledStatement{
|
---|
3278 | Case: LabeledStatementCaseLabel, Token: t, ConstantExpression: e,
|
---|
3279 | Token2: t2, lexicalScope: p.declScope, block: p.block,
|
---|
3280 | }
|
---|
3281 | case DEFAULT:
|
---|
3282 | if p.switches == 0 {
|
---|
3283 | p.err("'deafult' label not within a switch statement")
|
---|
3284 | }
|
---|
3285 | t = p.shift()
|
---|
3286 | switch p.rune() {
|
---|
3287 | case ':':
|
---|
3288 | t2 = p.shift()
|
---|
3289 | default:
|
---|
3290 | p.err("expected :")
|
---|
3291 | }
|
---|
3292 | return &LabeledStatement{
|
---|
3293 | Case: LabeledStatementDefault, Token: t, Token2: t2,
|
---|
3294 | lexicalScope: p.declScope, block: p.block,
|
---|
3295 | }
|
---|
3296 | default:
|
---|
3297 | p.err("expected labeled-statement")
|
---|
3298 | return &LabeledStatement{}
|
---|
3299 | }
|
---|
3300 | }
|
---|
3301 |
|
---|
3302 | // [0], 6.8.2 Compound statement
|
---|
3303 | //
|
---|
3304 | // compound-statement:
|
---|
3305 | // { block-item-list_opt }
|
---|
3306 | func (p *parser) compoundStatement(s Scope, inject []Token) (r *CompoundStatement) {
|
---|
3307 | if p.rune() != '{' {
|
---|
3308 | p.err("expected {")
|
---|
3309 | return nil
|
---|
3310 | }
|
---|
3311 |
|
---|
3312 | r = &CompoundStatement{parent: p.block}
|
---|
3313 | if fn := p.currFn; fn != nil {
|
---|
3314 | fn.compoundStatements = append(fn.compoundStatements, r)
|
---|
3315 | }
|
---|
3316 | sv := p.block
|
---|
3317 | if sv != nil {
|
---|
3318 | sv.children = append(sv.children, r)
|
---|
3319 | }
|
---|
3320 | p.block = r
|
---|
3321 | switch {
|
---|
3322 | case s != nil:
|
---|
3323 | p.declScope = s
|
---|
3324 | p.resolveScope = s
|
---|
3325 | p.scopes++
|
---|
3326 | // var a []string
|
---|
3327 | // for s := p.declScope; s != nil; s = s.Parent() {
|
---|
3328 | // a = append(a, fmt.Sprintf("%p", s))
|
---|
3329 | // }
|
---|
3330 | // dbg("using func scope %p: %v", s, strings.Join(a, " "))
|
---|
3331 | default:
|
---|
3332 | p.openScope(false)
|
---|
3333 | }
|
---|
3334 | s = p.declScope
|
---|
3335 | p.typedefNameEnabled = true
|
---|
3336 | t := p.shift()
|
---|
3337 | if len(inject) != 0 {
|
---|
3338 | p.unget(inject...)
|
---|
3339 | }
|
---|
3340 | list := p.blockItemList()
|
---|
3341 | var t2 Token
|
---|
3342 | p.closeScope()
|
---|
3343 | p.typedefNameEnabled = true
|
---|
3344 | switch p.rune() {
|
---|
3345 | case '}':
|
---|
3346 | t2 = p.shift()
|
---|
3347 | default:
|
---|
3348 | p.err("expected }")
|
---|
3349 | }
|
---|
3350 | r.Token = t
|
---|
3351 | r.BlockItemList = list
|
---|
3352 | r.Token2 = t2
|
---|
3353 | r.scope = s
|
---|
3354 | p.block = sv
|
---|
3355 | return r
|
---|
3356 | }
|
---|
3357 |
|
---|
3358 | // block-item-list:
|
---|
3359 | // block-item
|
---|
3360 | // block-item-list block-item
|
---|
3361 | func (p *parser) blockItemList() (r *BlockItemList) {
|
---|
3362 | var prev *BlockItemList
|
---|
3363 | for p.rune() != '}' && p.rune() > 0 {
|
---|
3364 | n := &BlockItemList{BlockItem: p.blockItem()}
|
---|
3365 | if r == nil {
|
---|
3366 | r = n
|
---|
3367 | prev = r
|
---|
3368 | continue
|
---|
3369 | }
|
---|
3370 |
|
---|
3371 | prev.BlockItemList = n
|
---|
3372 | prev = n
|
---|
3373 | }
|
---|
3374 | return r
|
---|
3375 | }
|
---|
3376 |
|
---|
3377 | // block-item:
|
---|
3378 | // declaration
|
---|
3379 | // statement
|
---|
3380 | // label-declaration
|
---|
3381 | // declaration-specifiers declarator compound-statement
|
---|
3382 | func (p *parser) blockItem() *BlockItem {
|
---|
3383 | switch p.rune() {
|
---|
3384 | case
|
---|
3385 | TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL,
|
---|
3386 | VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
3387 | CONST, RESTRICT, VOLATILE,
|
---|
3388 | ALIGNAS,
|
---|
3389 | INLINE, NORETURN, ATTRIBUTE:
|
---|
3390 | ds := p.declarationSpecifiers(nil, nil)
|
---|
3391 | switch p.rune() {
|
---|
3392 | case ';':
|
---|
3393 | r := &BlockItem{Case: BlockItemDecl, Declaration: p.declaration(ds, nil)}
|
---|
3394 | p.typedefNameEnabled = true
|
---|
3395 | return r
|
---|
3396 | }
|
---|
3397 |
|
---|
3398 | d := p.declarator(true, ds.typedef(), nil)
|
---|
3399 | switch p.rune() {
|
---|
3400 | case '{':
|
---|
3401 | if p.ctx.cfg.RejectNestedFunctionDefinitions {
|
---|
3402 | p.err0(false, "nested functions not allowed")
|
---|
3403 | }
|
---|
3404 | r := &BlockItem{Case: BlockItemFuncDef, DeclarationSpecifiers: ds, Declarator: d, CompoundStatement: p.compoundStatement(d.ParamScope(), p.fn(d.Name()))}
|
---|
3405 | p.typedefNameEnabled = true
|
---|
3406 | return r
|
---|
3407 | default:
|
---|
3408 | r := &BlockItem{Case: BlockItemDecl, Declaration: p.declaration(ds, d)}
|
---|
3409 | return r
|
---|
3410 | }
|
---|
3411 | case LABEL:
|
---|
3412 | p.block.hasLabel()
|
---|
3413 | return &BlockItem{Case: BlockItemLabel, LabelDeclaration: p.labelDeclaration()}
|
---|
3414 | case PRAGMASTDC:
|
---|
3415 | return &BlockItem{Case: BlockItemPragma, PragmaSTDC: p.pragmaSTDC()}
|
---|
3416 | default:
|
---|
3417 | return &BlockItem{Case: BlockItemStmt, Statement: p.statement()}
|
---|
3418 | }
|
---|
3419 | }
|
---|
3420 |
|
---|
3421 | // label-declaration
|
---|
3422 | // __label__ identifier-list ;
|
---|
3423 | func (p *parser) labelDeclaration() *LabelDeclaration {
|
---|
3424 | if p.rune() != LABEL {
|
---|
3425 | p.err("expected __label__")
|
---|
3426 | return nil
|
---|
3427 | }
|
---|
3428 |
|
---|
3429 | t := p.shift()
|
---|
3430 | list := p.identifierList()
|
---|
3431 | p.typedefNameEnabled = true
|
---|
3432 | var t2 Token
|
---|
3433 | switch p.rune() {
|
---|
3434 | case ';':
|
---|
3435 | t2 = p.shift()
|
---|
3436 | default:
|
---|
3437 | p.err("expected ;")
|
---|
3438 | }
|
---|
3439 | return &LabelDeclaration{Token: t, IdentifierList: list, Token2: t2}
|
---|
3440 | }
|
---|
3441 |
|
---|
3442 | // [0], 6.8.3 Expression and null statements
|
---|
3443 | //
|
---|
3444 | // expression-statement:
|
---|
3445 | // expression_opt attribute-specifier-list_opt;
|
---|
3446 | func (p *parser) expressionStatement() *ExpressionStatement {
|
---|
3447 | switch p.rune() {
|
---|
3448 | case '}':
|
---|
3449 | p.typedefNameEnabled = true
|
---|
3450 | return &ExpressionStatement{}
|
---|
3451 | case ';':
|
---|
3452 | p.typedefNameEnabled = true
|
---|
3453 | return &ExpressionStatement{Token: p.shift()}
|
---|
3454 | case ATTRIBUTE:
|
---|
3455 | p.typedefNameEnabled = true
|
---|
3456 | attr := p.attributeSpecifierList()
|
---|
3457 | // if attr != nil {
|
---|
3458 | // trc("%v: ATTRS", attr.Position())
|
---|
3459 | // }
|
---|
3460 | var t Token
|
---|
3461 | switch p.rune() {
|
---|
3462 | case ';':
|
---|
3463 | t = p.shift()
|
---|
3464 | default:
|
---|
3465 | p.err("expected ;")
|
---|
3466 | }
|
---|
3467 | return &ExpressionStatement{AttributeSpecifierList: attr, Token: t}
|
---|
3468 | }
|
---|
3469 |
|
---|
3470 | e := p.expression()
|
---|
3471 | var t Token
|
---|
3472 | p.typedefNameEnabled = true
|
---|
3473 | attr := p.attributeSpecifierListOpt()
|
---|
3474 | // if attr != nil {
|
---|
3475 | // trc("%v: ATTRS", attr.Position())
|
---|
3476 | // }
|
---|
3477 | switch p.rune() {
|
---|
3478 | case ';':
|
---|
3479 | t = p.shift()
|
---|
3480 | default:
|
---|
3481 | p.err("expected ;")
|
---|
3482 | }
|
---|
3483 | return &ExpressionStatement{Expression: e, AttributeSpecifierList: attr, Token: t}
|
---|
3484 | }
|
---|
3485 |
|
---|
3486 | // [0], 6.8.4 Selection statements
|
---|
3487 | //
|
---|
3488 | // selection-statement:
|
---|
3489 | // if ( expression ) statement
|
---|
3490 | // if ( expression ) statement else statement
|
---|
3491 | // switch ( expression ) statement
|
---|
3492 | func (p *parser) selectionStatement() *SelectionStatement {
|
---|
3493 | var t, t2, t3, t4 Token
|
---|
3494 | switch p.rune() {
|
---|
3495 | case IF:
|
---|
3496 | p.openScope(false)
|
---|
3497 | t = p.shift()
|
---|
3498 | switch p.rune() {
|
---|
3499 | case '(':
|
---|
3500 | t2 = p.shift()
|
---|
3501 | default:
|
---|
3502 | p.err("expected (")
|
---|
3503 | }
|
---|
3504 | e := p.expression()
|
---|
3505 | switch p.rune() {
|
---|
3506 | case ')':
|
---|
3507 | t3 = p.shift()
|
---|
3508 | default:
|
---|
3509 | p.err("expected )")
|
---|
3510 | }
|
---|
3511 | p.openScope(false)
|
---|
3512 | s := p.statement()
|
---|
3513 | if p.peek(false) != ELSE {
|
---|
3514 | r := &SelectionStatement{Case: SelectionStatementIf, Token: t, Token2: t2, Expression: e, Token3: t3, Statement: s}
|
---|
3515 | p.closeScope()
|
---|
3516 | p.closeScope()
|
---|
3517 | return r
|
---|
3518 | }
|
---|
3519 |
|
---|
3520 | p.closeScope()
|
---|
3521 | p.openScope(false)
|
---|
3522 | t4 = p.shift()
|
---|
3523 | r := &SelectionStatement{Case: SelectionStatementIfElse, Token: t, Token2: t2, Expression: e, Token3: t3, Statement: s, Token4: t4, Statement2: p.statement()}
|
---|
3524 | p.closeScope()
|
---|
3525 | p.closeScope()
|
---|
3526 | return r
|
---|
3527 | case SWITCH:
|
---|
3528 | p.switches++
|
---|
3529 | p.openScope(false)
|
---|
3530 | t = p.shift()
|
---|
3531 | switch p.rune() {
|
---|
3532 | case '(':
|
---|
3533 | t2 = p.shift()
|
---|
3534 | default:
|
---|
3535 | p.err("expected (")
|
---|
3536 | }
|
---|
3537 | e := p.expression()
|
---|
3538 | switch p.rune() {
|
---|
3539 | case ')':
|
---|
3540 | t3 = p.shift()
|
---|
3541 | default:
|
---|
3542 | p.err("expected )")
|
---|
3543 | }
|
---|
3544 | p.openScope(false)
|
---|
3545 | s := p.statement()
|
---|
3546 | p.closeScope()
|
---|
3547 | p.closeScope()
|
---|
3548 | p.switches--
|
---|
3549 | return &SelectionStatement{Case: SelectionStatementSwitch, Token: t, Token2: t2, Expression: e, Token3: t3, Statement: s}
|
---|
3550 | default:
|
---|
3551 | p.err("expected selection-statement")
|
---|
3552 | return nil
|
---|
3553 | }
|
---|
3554 | }
|
---|
3555 |
|
---|
3556 | // [0], 6.8.5 Iteration statements
|
---|
3557 | //
|
---|
3558 | // iteration-statement:
|
---|
3559 | // while ( expression ) statement
|
---|
3560 | // do statement while ( expression ) ;
|
---|
3561 | // for ( expression_opt ; expression_opt ; expression_opt ) statement
|
---|
3562 | // for ( declaration expression_opt ; expression_opt ) statement
|
---|
3563 | func (p *parser) iterationStatement() (r *IterationStatement) {
|
---|
3564 | var t, t2, t3, t4, t5 Token
|
---|
3565 | var e, e2, e3 *Expression
|
---|
3566 | switch p.rune() {
|
---|
3567 | case WHILE:
|
---|
3568 | p.openScope(false)
|
---|
3569 | t = p.shift()
|
---|
3570 | if p.rune() != '(' {
|
---|
3571 | p.err("expected (")
|
---|
3572 | p.closeScope()
|
---|
3573 | return nil
|
---|
3574 | }
|
---|
3575 |
|
---|
3576 | t2 = p.shift()
|
---|
3577 | e = p.expression()
|
---|
3578 | switch p.rune() {
|
---|
3579 | case ')':
|
---|
3580 | t3 = p.shift()
|
---|
3581 | default:
|
---|
3582 | p.err("expected )")
|
---|
3583 | }
|
---|
3584 | p.openScope(false)
|
---|
3585 | r = &IterationStatement{Case: IterationStatementWhile, Token: t, Token2: t2, Expression: e, Token3: t3, Statement: p.statement()}
|
---|
3586 | p.closeScope()
|
---|
3587 | p.closeScope()
|
---|
3588 | return r
|
---|
3589 | case DO:
|
---|
3590 | t := p.shift()
|
---|
3591 | p.openScope(false)
|
---|
3592 | p.openScope(false)
|
---|
3593 | s := p.statement()
|
---|
3594 | p.closeScope()
|
---|
3595 | switch p.rune() {
|
---|
3596 | case WHILE:
|
---|
3597 | t2 = p.shift()
|
---|
3598 | default:
|
---|
3599 | p.err("expected while")
|
---|
3600 | p.closeScope()
|
---|
3601 | return nil
|
---|
3602 | }
|
---|
3603 |
|
---|
3604 | if p.rune() != '(' {
|
---|
3605 | p.err("expected (")
|
---|
3606 | p.closeScope()
|
---|
3607 | return nil
|
---|
3608 | }
|
---|
3609 |
|
---|
3610 | t3 = p.shift()
|
---|
3611 | e = p.expression()
|
---|
3612 | switch p.rune() {
|
---|
3613 | case ')':
|
---|
3614 | t4 = p.shift()
|
---|
3615 | default:
|
---|
3616 | p.err("expected )")
|
---|
3617 | }
|
---|
3618 | p.typedefNameEnabled = true
|
---|
3619 | switch p.rune() {
|
---|
3620 | case ';':
|
---|
3621 | t5 = p.shift()
|
---|
3622 | default:
|
---|
3623 | p.err("expected ;")
|
---|
3624 | }
|
---|
3625 | r = &IterationStatement{Case: IterationStatementDo, Token: t, Statement: s, Token2: t2, Token3: t3, Expression: e, Token4: t4, Token5: t5}
|
---|
3626 | p.closeScope()
|
---|
3627 | return r
|
---|
3628 | case FOR:
|
---|
3629 | p.openScope(false)
|
---|
3630 | t = p.shift()
|
---|
3631 | if p.rune() != '(' {
|
---|
3632 | p.err("expected (")
|
---|
3633 | p.closeScope()
|
---|
3634 | return nil
|
---|
3635 | }
|
---|
3636 |
|
---|
3637 | t2 = p.shift()
|
---|
3638 | var d *Declaration
|
---|
3639 | switch p.rune() {
|
---|
3640 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL,
|
---|
3641 | VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
3642 | CONST, RESTRICT, VOLATILE,
|
---|
3643 | ALIGNAS,
|
---|
3644 | INLINE, NORETURN, ATTRIBUTE:
|
---|
3645 | d = p.declaration(nil, nil)
|
---|
3646 | if p.rune() != ';' {
|
---|
3647 | e = p.expression()
|
---|
3648 | }
|
---|
3649 | switch p.rune() {
|
---|
3650 | case ';':
|
---|
3651 | t3 = p.shift()
|
---|
3652 | default:
|
---|
3653 | p.err("expected ;")
|
---|
3654 | }
|
---|
3655 | if p.rune() != ')' {
|
---|
3656 | e2 = p.expression()
|
---|
3657 | }
|
---|
3658 | switch p.rune() {
|
---|
3659 | case ')':
|
---|
3660 | t4 = p.shift()
|
---|
3661 | default:
|
---|
3662 | p.err("expected )")
|
---|
3663 | }
|
---|
3664 | p.openScope(false)
|
---|
3665 | r = &IterationStatement{Case: IterationStatementForDecl, Token: t, Token2: t2, Declaration: d, Expression: e, Token3: t3, Expression2: e2, Token4: t4, Statement: p.statement()}
|
---|
3666 | p.closeScope()
|
---|
3667 | p.closeScope()
|
---|
3668 | return r
|
---|
3669 | default:
|
---|
3670 | if p.rune() != ';' {
|
---|
3671 | e = p.expression()
|
---|
3672 | }
|
---|
3673 | switch p.rune() {
|
---|
3674 | case ';':
|
---|
3675 | t3 = p.shift()
|
---|
3676 | default:
|
---|
3677 | p.err("expected ;")
|
---|
3678 | }
|
---|
3679 | if p.rune() != ';' {
|
---|
3680 | e2 = p.expression()
|
---|
3681 | }
|
---|
3682 | switch p.rune() {
|
---|
3683 | case ';':
|
---|
3684 | t4 = p.shift()
|
---|
3685 | default:
|
---|
3686 | p.err("expected ;")
|
---|
3687 | }
|
---|
3688 | if p.rune() != ')' {
|
---|
3689 | e3 = p.expression()
|
---|
3690 | }
|
---|
3691 | switch p.rune() {
|
---|
3692 | case ')':
|
---|
3693 | t5 = p.shift()
|
---|
3694 | default:
|
---|
3695 | p.err("expected )")
|
---|
3696 | }
|
---|
3697 | p.openScope(false)
|
---|
3698 | r = &IterationStatement{Case: IterationStatementFor, Token: t, Token2: t2, Expression: e, Token3: t3, Expression2: e2, Token4: t4, Expression3: e3, Token5: t5, Statement: p.statement()}
|
---|
3699 | p.closeScope()
|
---|
3700 | p.closeScope()
|
---|
3701 | return r
|
---|
3702 | }
|
---|
3703 | default:
|
---|
3704 | p.err("expected iteration-statement")
|
---|
3705 | return nil
|
---|
3706 | }
|
---|
3707 | }
|
---|
3708 |
|
---|
3709 | // [0], 6.8.6 Jump statements
|
---|
3710 | //
|
---|
3711 | // jump-statement:
|
---|
3712 | // goto identifier ;
|
---|
3713 | // goto * expression ;
|
---|
3714 | // continue ;
|
---|
3715 | // break ;
|
---|
3716 | // return expression_opt ;
|
---|
3717 | func (p *parser) jumpStatement() *JumpStatement {
|
---|
3718 | var t, t2, t3 Token
|
---|
3719 | var kind JumpStatementCase
|
---|
3720 | switch p.rune() {
|
---|
3721 | case GOTO:
|
---|
3722 | p.typedefNameEnabled = false
|
---|
3723 | t = p.shift()
|
---|
3724 | switch p.rune() {
|
---|
3725 | case IDENTIFIER:
|
---|
3726 | t2 = p.shift()
|
---|
3727 | case '*':
|
---|
3728 | t2 = p.shift()
|
---|
3729 | p.typedefNameEnabled = true
|
---|
3730 | e := p.expression()
|
---|
3731 | switch p.rune() {
|
---|
3732 | case ';':
|
---|
3733 | t3 = p.shift()
|
---|
3734 | default:
|
---|
3735 | p.err("expected ;")
|
---|
3736 | }
|
---|
3737 | return &JumpStatement{Case: JumpStatementGotoExpr, Token: t, Token2: t2, Expression: e, Token3: t3, lexicalScope: p.declScope}
|
---|
3738 | default:
|
---|
3739 | p.err("expected identifier or *")
|
---|
3740 | }
|
---|
3741 | p.typedefNameEnabled = true
|
---|
3742 | switch p.rune() {
|
---|
3743 | case ';':
|
---|
3744 | t3 = p.shift()
|
---|
3745 | default:
|
---|
3746 | p.err("expected ;")
|
---|
3747 | }
|
---|
3748 | return &JumpStatement{Case: JumpStatementGoto, Token: t, Token2: t2, Token3: t3, lexicalScope: p.declScope}
|
---|
3749 | case CONTINUE:
|
---|
3750 | kind = JumpStatementContinue
|
---|
3751 | case BREAK:
|
---|
3752 | kind = JumpStatementBreak
|
---|
3753 | case RETURN:
|
---|
3754 | t = p.shift()
|
---|
3755 | var e *Expression
|
---|
3756 | if p.rune() != ';' {
|
---|
3757 | e = p.expression()
|
---|
3758 | }
|
---|
3759 | p.typedefNameEnabled = true
|
---|
3760 | switch p.rune() {
|
---|
3761 | case ';':
|
---|
3762 | t2 = p.shift()
|
---|
3763 | default:
|
---|
3764 | p.err("expected ;")
|
---|
3765 | }
|
---|
3766 | return &JumpStatement{Case: JumpStatementReturn, Token: t, Expression: e, Token2: t2, lexicalScope: p.declScope}
|
---|
3767 | default:
|
---|
3768 | p.err("expected jump-statement")
|
---|
3769 | return nil
|
---|
3770 | }
|
---|
3771 |
|
---|
3772 | t = p.shift()
|
---|
3773 | p.typedefNameEnabled = true
|
---|
3774 | switch p.rune() {
|
---|
3775 | case ';':
|
---|
3776 | t2 = p.shift()
|
---|
3777 | default:
|
---|
3778 | p.err("expected ;")
|
---|
3779 | }
|
---|
3780 | return &JumpStatement{Case: kind, Token: t, Token2: t2, lexicalScope: p.declScope}
|
---|
3781 | }
|
---|
3782 |
|
---|
3783 | // [0], 6.9 External definitions
|
---|
3784 | //
|
---|
3785 | // translation-unit:
|
---|
3786 | // external-declaration
|
---|
3787 | // translation-unit external-declaration
|
---|
3788 | func (p *parser) translationUnit() (r *TranslationUnit) {
|
---|
3789 | p.typedefNameEnabled = true
|
---|
3790 | var prev *TranslationUnit
|
---|
3791 | for p.rune() >= 0 {
|
---|
3792 | ed := p.externalDeclaration()
|
---|
3793 | if ed == nil {
|
---|
3794 | continue
|
---|
3795 | }
|
---|
3796 |
|
---|
3797 | t := &TranslationUnit{ExternalDeclaration: ed}
|
---|
3798 | switch {
|
---|
3799 | case r == nil:
|
---|
3800 | r = t
|
---|
3801 | default:
|
---|
3802 | prev.TranslationUnit = t
|
---|
3803 | }
|
---|
3804 | prev = t
|
---|
3805 | }
|
---|
3806 | if r != nil {
|
---|
3807 | return r
|
---|
3808 | }
|
---|
3809 |
|
---|
3810 | return &TranslationUnit{}
|
---|
3811 | }
|
---|
3812 |
|
---|
3813 | // external-declaration:
|
---|
3814 | // function-definition
|
---|
3815 | // declaration
|
---|
3816 | // asm-function-definition
|
---|
3817 | // ;
|
---|
3818 | func (p *parser) externalDeclaration() *ExternalDeclaration {
|
---|
3819 | var ds *DeclarationSpecifiers
|
---|
3820 | var inline, extern bool
|
---|
3821 | if p.ctx.cfg.SharedFunctionDefinitions != nil {
|
---|
3822 | p.rune()
|
---|
3823 | p.hash.Reset()
|
---|
3824 | p.key = sharedFunctionDefinitionKey{pos: dict.sid(p.tok.Position().String())}
|
---|
3825 | p.hashTok()
|
---|
3826 | }
|
---|
3827 | switch p.rune() {
|
---|
3828 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL,
|
---|
3829 | VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
3830 | CONST, RESTRICT, VOLATILE,
|
---|
3831 | INLINE, NORETURN, ATTRIBUTE,
|
---|
3832 | ALIGNAS:
|
---|
3833 | ds = p.declarationSpecifiers(&extern, &inline)
|
---|
3834 | case ';':
|
---|
3835 | if p.ctx.cfg.RejectEmptyDeclarations {
|
---|
3836 | p.err("expected external-declaration")
|
---|
3837 | return nil
|
---|
3838 | }
|
---|
3839 |
|
---|
3840 | return &ExternalDeclaration{Case: ExternalDeclarationEmpty, Token: p.shift()}
|
---|
3841 | case ASM:
|
---|
3842 | return &ExternalDeclaration{Case: ExternalDeclarationAsmStmt, AsmStatement: p.asmStatement()}
|
---|
3843 | case PRAGMASTDC:
|
---|
3844 | return &ExternalDeclaration{Case: ExternalDeclarationPragma, PragmaSTDC: p.pragmaSTDC()}
|
---|
3845 | default:
|
---|
3846 | if p.ctx.cfg.RejectMissingDeclarationSpecifiers {
|
---|
3847 | p.err("expected declaration-specifiers")
|
---|
3848 | }
|
---|
3849 | }
|
---|
3850 | if p.rune() == ';' {
|
---|
3851 | return &ExternalDeclaration{Case: ExternalDeclarationDecl, Declaration: p.declaration(ds, nil)}
|
---|
3852 | }
|
---|
3853 |
|
---|
3854 | p.rune()
|
---|
3855 | d := p.declarator(false, ds.typedef(), nil)
|
---|
3856 | p.declScope.declare(d.Name(), d)
|
---|
3857 | switch p.rune() {
|
---|
3858 | case ',', ';', '=', ATTRIBUTE:
|
---|
3859 | if ds == nil {
|
---|
3860 | ds = noDeclSpecs
|
---|
3861 | }
|
---|
3862 | r := &ExternalDeclaration{Case: ExternalDeclarationDecl, Declaration: p.declaration(ds, d)}
|
---|
3863 | return r
|
---|
3864 | case ASM:
|
---|
3865 | return &ExternalDeclaration{Case: ExternalDeclarationAsm, AsmFunctionDefinition: p.asmFunctionDefinition(ds, d)}
|
---|
3866 | default:
|
---|
3867 | fd := p.functionDefinition(ds, d)
|
---|
3868 | if sfd := p.ctx.cfg.SharedFunctionDefinitions; sfd != nil {
|
---|
3869 | p.key.nm = d.Name()
|
---|
3870 | p.key.hash = p.hash.Sum64()
|
---|
3871 | if ex := sfd.m[p.key]; ex != nil {
|
---|
3872 | sfd.M[ex] = struct{}{}
|
---|
3873 | d := ex.Declarator
|
---|
3874 | p.declScope.declare(d.Name(), d)
|
---|
3875 | r := &ExternalDeclaration{Case: ExternalDeclarationFuncDef, FunctionDefinition: ex}
|
---|
3876 | return r
|
---|
3877 | }
|
---|
3878 |
|
---|
3879 | sfd.m[p.key] = fd
|
---|
3880 | }
|
---|
3881 |
|
---|
3882 | r := &ExternalDeclaration{Case: ExternalDeclarationFuncDef, FunctionDefinition: fd}
|
---|
3883 | return r
|
---|
3884 | }
|
---|
3885 | }
|
---|
3886 |
|
---|
3887 | func (p *parser) pragmaSTDC() *PragmaSTDC {
|
---|
3888 | if p.rune() != PRAGMASTDC {
|
---|
3889 | p.err("expected __pragma_stdc")
|
---|
3890 | }
|
---|
3891 |
|
---|
3892 | t := p.shift() // _Pragma
|
---|
3893 | t2 := p.shift() // STDC
|
---|
3894 | t3 := p.shift() // FOO
|
---|
3895 | t4 := p.shift() // Bar
|
---|
3896 | return &PragmaSTDC{Token: t, Token2: t2, Token3: t3, Token4: t4}
|
---|
3897 | }
|
---|
3898 |
|
---|
3899 | // [0], 6.9.1 Function definitions
|
---|
3900 | //
|
---|
3901 | // function-definition:
|
---|
3902 | // declaration-specifiers declarator declaration-list_opt compound-statement
|
---|
3903 | func (p *parser) functionDefinition(ds *DeclarationSpecifiers, d *Declarator) (r *FunctionDefinition) {
|
---|
3904 | var list *DeclarationList
|
---|
3905 | s := d.ParamScope()
|
---|
3906 | switch {
|
---|
3907 | case p.rune() != '{': // As in: int f(i) int i; { return i; }
|
---|
3908 | list = p.declarationList(s)
|
---|
3909 | case d.DirectDeclarator != nil && d.DirectDeclarator.Case == DirectDeclaratorFuncIdent: // As in: int f(i) { return i; }
|
---|
3910 | d.DirectDeclarator.idListNoDeclList = true
|
---|
3911 | for n := d.DirectDeclarator.IdentifierList; n != nil; n = n.IdentifierList {
|
---|
3912 | tok := n.Token2
|
---|
3913 | if tok.Value == 0 {
|
---|
3914 | tok = n.Token
|
---|
3915 | }
|
---|
3916 | d := &Declarator{
|
---|
3917 | IsParameter: true,
|
---|
3918 | DirectDeclarator: &DirectDeclarator{
|
---|
3919 | Case: DirectDeclaratorIdent,
|
---|
3920 | Token: tok,
|
---|
3921 | },
|
---|
3922 | }
|
---|
3923 | s.declare(tok.Value, d)
|
---|
3924 | if p.ctx.cfg.RejectMissingDeclarationSpecifiers {
|
---|
3925 | p.ctx.errNode(&tok, "expected declaration-specifiers")
|
---|
3926 | }
|
---|
3927 | }
|
---|
3928 | }
|
---|
3929 | p.block = nil
|
---|
3930 | r = &FunctionDefinition{DeclarationSpecifiers: ds, Declarator: d, DeclarationList: list}
|
---|
3931 | sv := p.currFn
|
---|
3932 | p.currFn = r
|
---|
3933 | r.CompoundStatement = p.compoundStatement(d.ParamScope(), p.fn(d.Name()))
|
---|
3934 | p.currFn = sv
|
---|
3935 | return r
|
---|
3936 | }
|
---|
3937 |
|
---|
3938 | func (p *parser) fn(nm StringID) (r []Token) {
|
---|
3939 | if p.ctx.cfg.PreprocessOnly {
|
---|
3940 | return nil
|
---|
3941 | }
|
---|
3942 |
|
---|
3943 | pos := p.tok.Position()
|
---|
3944 | toks := []Token{
|
---|
3945 | {Rune: STATIC, Value: idStatic, Src: idStatic},
|
---|
3946 | {Rune: CONST, Value: idConst, Src: idConst},
|
---|
3947 | {Rune: CHAR, Value: idChar, Src: idChar},
|
---|
3948 | {Rune: IDENTIFIER, Value: idFunc, Src: idFunc},
|
---|
3949 | {Rune: '[', Value: idLBracket, Src: idLBracket},
|
---|
3950 | {Rune: ']', Value: idRBracket, Src: idRBracket},
|
---|
3951 | {Rune: '=', Value: idEq, Src: idEq},
|
---|
3952 | {Rune: STRINGLITERAL, Value: nm, Src: nm},
|
---|
3953 | {Rune: ';', Value: idSemicolon, Src: idSemicolon},
|
---|
3954 | }
|
---|
3955 | if p.ctx.cfg.InjectTracingCode {
|
---|
3956 | id := dict.sid(fmt.Sprintf("%s:%s\n", pos, nm.String()))
|
---|
3957 | toks = append(toks, []Token{
|
---|
3958 | {Rune: IDENTIFIER, Value: idFprintf, Src: idFprintf},
|
---|
3959 | {Rune: '(', Value: idLParen, Src: idLParen},
|
---|
3960 | {Rune: IDENTIFIER, Value: idStderr, Src: idStderr},
|
---|
3961 | {Rune: ',', Value: idComma, Src: idComma},
|
---|
3962 | {Rune: STRINGLITERAL, Value: id, Src: id},
|
---|
3963 | {Rune: ')', Value: idRParen, Src: idRParen},
|
---|
3964 | {Rune: ';', Value: idSemicolon, Src: idSemicolon},
|
---|
3965 | {Rune: IDENTIFIER, Value: idFFlush, Src: idFFlush},
|
---|
3966 | {Rune: '(', Value: idLParen, Src: idLParen},
|
---|
3967 | {Rune: IDENTIFIER, Value: idStderr, Src: idStderr},
|
---|
3968 | {Rune: ')', Value: idRParen, Src: idRParen},
|
---|
3969 | {Rune: ';', Value: idSemicolon, Src: idSemicolon},
|
---|
3970 | }...)
|
---|
3971 | }
|
---|
3972 | for _, v := range toks {
|
---|
3973 | v.file = p.tok.file
|
---|
3974 | v.pos = p.tok.pos
|
---|
3975 | v.seq = p.tok.seq
|
---|
3976 | r = append(r, v)
|
---|
3977 | }
|
---|
3978 | return r
|
---|
3979 | }
|
---|
3980 |
|
---|
3981 | // declaration-list:
|
---|
3982 | // declaration
|
---|
3983 | // declaration-list declaration
|
---|
3984 | func (p *parser) declarationList(s Scope) (r *DeclarationList) {
|
---|
3985 | p.declScope = s
|
---|
3986 | p.resolveScope = s
|
---|
3987 | switch ch := p.rune(); ch {
|
---|
3988 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL,
|
---|
3989 | VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
3990 | CONST, RESTRICT, VOLATILE,
|
---|
3991 | ALIGNAS,
|
---|
3992 | INLINE, NORETURN, ATTRIBUTE:
|
---|
3993 | r = &DeclarationList{Declaration: p.declaration(nil, nil)}
|
---|
3994 | default:
|
---|
3995 | p.err("expected declaration: %s", tokName(ch))
|
---|
3996 | return nil
|
---|
3997 | }
|
---|
3998 |
|
---|
3999 | for prev := r; ; prev = prev.DeclarationList {
|
---|
4000 | switch p.rune() {
|
---|
4001 | case TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, THREADLOCAL,
|
---|
4002 | VOID, CHAR, SHORT, INT, INT8, INT16, INT32, INT64, INT128, LONG, FLOAT, FLOAT16, FLOAT80, FLOAT32, FLOAT32X, FLOAT64, FLOAT64X, FLOAT128, DECIMAL32, DECIMAL64, DECIMAL128, FRACT, SAT, ACCUM, DOUBLE, SIGNED, UNSIGNED, BOOL, COMPLEX, STRUCT, UNION, ENUM, TYPEDEFNAME, TYPEOF, ATOMIC,
|
---|
4003 | CONST, RESTRICT, VOLATILE,
|
---|
4004 | ALIGNAS,
|
---|
4005 | INLINE, NORETURN, ATTRIBUTE:
|
---|
4006 | prev.DeclarationList = &DeclarationList{Declaration: p.declaration(nil, nil)}
|
---|
4007 | default:
|
---|
4008 | return r
|
---|
4009 | }
|
---|
4010 | }
|
---|
4011 | }
|
---|
4012 |
|
---|
4013 | // ----------------------------------------------------------------- Extensions
|
---|
4014 |
|
---|
4015 | // asm-function-definition:
|
---|
4016 | // declaration-specifiers declarator asm-statement
|
---|
4017 | func (p *parser) asmFunctionDefinition(ds *DeclarationSpecifiers, d *Declarator) *AsmFunctionDefinition {
|
---|
4018 | return &AsmFunctionDefinition{DeclarationSpecifiers: ds, Declarator: d, AsmStatement: p.asmStatement()}
|
---|
4019 | }
|
---|
4020 |
|
---|
4021 | // asm-statement:
|
---|
4022 | // asm attribute-specifier-list_opt ;
|
---|
4023 | func (p *parser) asmStatement() *AsmStatement {
|
---|
4024 | a := p.asm()
|
---|
4025 | attr := p.attributeSpecifierListOpt()
|
---|
4026 | // if attr != nil {
|
---|
4027 | // trc("%v: ATTRS", attr.Position())
|
---|
4028 | // }
|
---|
4029 | var t Token
|
---|
4030 | switch p.rune() {
|
---|
4031 | case ';':
|
---|
4032 | p.typedefNameEnabled = true
|
---|
4033 | t = p.shift()
|
---|
4034 | default:
|
---|
4035 | p.err("expected ';'")
|
---|
4036 | }
|
---|
4037 |
|
---|
4038 | return &AsmStatement{Asm: a, AttributeSpecifierList: attr, Token: t}
|
---|
4039 | }
|
---|
4040 |
|
---|
4041 | // asm:
|
---|
4042 | // asm asm-qualifier-list_opt ( string-literal asm-arg-list_opt )
|
---|
4043 | func (p *parser) asm() *Asm {
|
---|
4044 | var t, t2, t3, t4 Token
|
---|
4045 | switch p.rune() {
|
---|
4046 | case ASM:
|
---|
4047 | t = p.shift()
|
---|
4048 | default:
|
---|
4049 | p.err("expected asm")
|
---|
4050 | }
|
---|
4051 |
|
---|
4052 | var qlist *AsmQualifierList
|
---|
4053 | switch p.rune() {
|
---|
4054 | case VOLATILE, INLINE, GOTO:
|
---|
4055 | qlist = p.asmQualifierList()
|
---|
4056 | }
|
---|
4057 |
|
---|
4058 | switch p.rune() {
|
---|
4059 | case '(':
|
---|
4060 | t2 = p.shift()
|
---|
4061 | default:
|
---|
4062 | p.err("expected (")
|
---|
4063 | }
|
---|
4064 |
|
---|
4065 | switch p.rune() {
|
---|
4066 | case STRINGLITERAL:
|
---|
4067 | t3 = p.shift()
|
---|
4068 | default:
|
---|
4069 | p.err("expected string-literal")
|
---|
4070 | }
|
---|
4071 |
|
---|
4072 | var argList *AsmArgList
|
---|
4073 | switch p.rune() {
|
---|
4074 | case ':':
|
---|
4075 | argList = p.asmArgList()
|
---|
4076 | }
|
---|
4077 |
|
---|
4078 | switch p.rune() {
|
---|
4079 | case ')':
|
---|
4080 | t4 = p.shift()
|
---|
4081 | default:
|
---|
4082 | p.err("expected )")
|
---|
4083 | }
|
---|
4084 |
|
---|
4085 | return &Asm{Token: t, AsmQualifierList: qlist, Token2: t2, Token3: t3, AsmArgList: argList, Token4: t4}
|
---|
4086 | }
|
---|
4087 |
|
---|
4088 | // asm-qualifier-list:
|
---|
4089 | // asm-qualifier
|
---|
4090 | // asm-qualifier-list asm-qualifier
|
---|
4091 | func (p *parser) asmQualifierList() (r *AsmQualifierList) {
|
---|
4092 | switch p.rune() {
|
---|
4093 | case VOLATILE, INLINE, GOTO:
|
---|
4094 | r = &AsmQualifierList{AsmQualifier: p.asmQualifier()}
|
---|
4095 | default:
|
---|
4096 | p.err("expected asm-qualifier-list")
|
---|
4097 | return nil
|
---|
4098 | }
|
---|
4099 |
|
---|
4100 | for prev := r; ; prev = prev.AsmQualifierList {
|
---|
4101 | switch p.rune() {
|
---|
4102 | case VOLATILE, INLINE, GOTO:
|
---|
4103 | prev.AsmQualifierList = &AsmQualifierList{AsmQualifier: p.asmQualifier()}
|
---|
4104 | default:
|
---|
4105 | return r
|
---|
4106 | }
|
---|
4107 | }
|
---|
4108 | }
|
---|
4109 |
|
---|
4110 | // asm-qualifier:
|
---|
4111 | // volatile
|
---|
4112 | // inline
|
---|
4113 | // goto"
|
---|
4114 | func (p *parser) asmQualifier() *AsmQualifier {
|
---|
4115 | switch p.rune() {
|
---|
4116 | case VOLATILE:
|
---|
4117 | return &AsmQualifier{Case: AsmQualifierVolatile, Token: p.shift()}
|
---|
4118 | case INLINE:
|
---|
4119 | return &AsmQualifier{Case: AsmQualifierInline, Token: p.shift()}
|
---|
4120 | case GOTO:
|
---|
4121 | return &AsmQualifier{Case: AsmQualifierGoto, Token: p.shift()}
|
---|
4122 | default:
|
---|
4123 | p.err("expected asm-qualifier")
|
---|
4124 | return nil
|
---|
4125 | }
|
---|
4126 | }
|
---|
4127 |
|
---|
4128 | // asm-arg-list:
|
---|
4129 | // : ExpressionListOpt
|
---|
4130 | // asm-arg-list : expression-list_opt
|
---|
4131 | func (p *parser) asmArgList() (r *AsmArgList) {
|
---|
4132 | if p.rune() != ':' {
|
---|
4133 | p.err("expected :")
|
---|
4134 | return nil
|
---|
4135 | }
|
---|
4136 |
|
---|
4137 | t := p.shift()
|
---|
4138 | var list *AsmExpressionList
|
---|
4139 | switch p.rune() {
|
---|
4140 | case ':', ')':
|
---|
4141 | default:
|
---|
4142 | list = p.asmExpressionList()
|
---|
4143 | }
|
---|
4144 | r = &AsmArgList{Token: t, AsmExpressionList: list}
|
---|
4145 | for prev := r; p.rune() == ':'; prev = prev.AsmArgList {
|
---|
4146 | t := p.shift()
|
---|
4147 | switch p.rune() {
|
---|
4148 | case ':', ')':
|
---|
4149 | default:
|
---|
4150 | list = p.asmExpressionList()
|
---|
4151 | }
|
---|
4152 | prev.AsmArgList = &AsmArgList{Token: t, AsmExpressionList: list}
|
---|
4153 | }
|
---|
4154 | return r
|
---|
4155 | }
|
---|
4156 |
|
---|
4157 | // asm-expression-list:
|
---|
4158 | // asm-index_opt assignment-expression
|
---|
4159 | // asm-expression-list , asm-index_opt assignment-expression
|
---|
4160 | func (p *parser) asmExpressionList() (r *AsmExpressionList) {
|
---|
4161 | var x *AsmIndex
|
---|
4162 | if p.rune() == '[' {
|
---|
4163 | x = p.asmIndex()
|
---|
4164 | }
|
---|
4165 |
|
---|
4166 | r = &AsmExpressionList{AsmIndex: x, AssignmentExpression: p.assignmentExpression()}
|
---|
4167 | for prev := r; p.rune() == ','; prev = prev.AsmExpressionList {
|
---|
4168 | t := p.shift()
|
---|
4169 | if p.rune() == '[' {
|
---|
4170 | x = p.asmIndex()
|
---|
4171 | }
|
---|
4172 | prev.AsmExpressionList = &AsmExpressionList{Token: t, AsmIndex: x, AssignmentExpression: p.assignmentExpression()}
|
---|
4173 | }
|
---|
4174 | return r
|
---|
4175 | }
|
---|
4176 |
|
---|
4177 | // asm-index:
|
---|
4178 | // [ expression ]
|
---|
4179 | func (p *parser) asmIndex() *AsmIndex {
|
---|
4180 | if p.rune() != '[' {
|
---|
4181 | p.err("expected [")
|
---|
4182 | return nil
|
---|
4183 | }
|
---|
4184 |
|
---|
4185 | t := p.shift()
|
---|
4186 | e := p.expression()
|
---|
4187 | var t2 Token
|
---|
4188 | switch p.rune() {
|
---|
4189 | case ']':
|
---|
4190 | t2 = p.shift()
|
---|
4191 | default:
|
---|
4192 | p.err("expected ]")
|
---|
4193 | }
|
---|
4194 | return &AsmIndex{Token: t, Expression: e, Token2: t2}
|
---|
4195 | }
|
---|
4196 |
|
---|
4197 | // attribute-specifier-list:
|
---|
4198 | // attribute-specifier
|
---|
4199 | // attribute-specifier-list attribute-specifier
|
---|
4200 | func (p *parser) attributeSpecifierList() (r *AttributeSpecifierList) {
|
---|
4201 | if p.rune() != ATTRIBUTE {
|
---|
4202 | p.err("expected __attribute__")
|
---|
4203 | return nil
|
---|
4204 | }
|
---|
4205 |
|
---|
4206 | r = &AttributeSpecifierList{AttributeSpecifier: p.attributeSpecifier()}
|
---|
4207 | for prev := r; p.rune() == ATTRIBUTE; prev = r.AttributeSpecifierList {
|
---|
4208 | prev.AttributeSpecifierList = &AttributeSpecifierList{AttributeSpecifier: p.attributeSpecifier()}
|
---|
4209 | }
|
---|
4210 | return r
|
---|
4211 | }
|
---|
4212 |
|
---|
4213 | // attribute-specifier:
|
---|
4214 | // __attribute__ (( attribute-value-list_opt ))
|
---|
4215 | func (p *parser) attributeSpecifier() (r *AttributeSpecifier) {
|
---|
4216 | if p.rune() != ATTRIBUTE {
|
---|
4217 | p.err("expected __attribute__")
|
---|
4218 | return nil
|
---|
4219 | }
|
---|
4220 |
|
---|
4221 | en := p.typedefNameEnabled
|
---|
4222 | t := p.shift()
|
---|
4223 | var t2, t3, t4, t5 Token
|
---|
4224 | p.ignoreKeywords = true
|
---|
4225 | switch p.rune() {
|
---|
4226 | case '(':
|
---|
4227 | t2 = p.shift()
|
---|
4228 | default:
|
---|
4229 | p.err("expected (")
|
---|
4230 | }
|
---|
4231 | switch p.rune() {
|
---|
4232 | case '(':
|
---|
4233 | t3 = p.shift()
|
---|
4234 | default:
|
---|
4235 | p.err("expected (")
|
---|
4236 | }
|
---|
4237 | var list *AttributeValueList
|
---|
4238 | if p.rune() != ')' {
|
---|
4239 | list = p.attributeValueList()
|
---|
4240 | }
|
---|
4241 | p.ignoreKeywords = false
|
---|
4242 | p.typedefNameEnabled = en
|
---|
4243 | switch p.rune() {
|
---|
4244 | case ')':
|
---|
4245 | t4 = p.shift()
|
---|
4246 | default:
|
---|
4247 | p.err("expected )")
|
---|
4248 | }
|
---|
4249 | switch p.rune() {
|
---|
4250 | case ')':
|
---|
4251 | t5 = p.shift()
|
---|
4252 | default:
|
---|
4253 | p.err("expected )")
|
---|
4254 | }
|
---|
4255 | return &AttributeSpecifier{Token: t, Token2: t2, Token3: t3, AttributeValueList: list, Token4: t4, Token5: t5}
|
---|
4256 | }
|
---|
4257 |
|
---|
4258 | // attribute-value-list:
|
---|
4259 | // attribute-value
|
---|
4260 | // attribute-value-list , attribute-value
|
---|
4261 | func (p *parser) attributeValueList() (r *AttributeValueList) {
|
---|
4262 | r = &AttributeValueList{AttributeValue: p.attributeValue()}
|
---|
4263 | for prev := r; p.rune() == ','; prev = prev.AttributeValueList {
|
---|
4264 | t := p.shift()
|
---|
4265 | prev.AttributeValueList = &AttributeValueList{Token: t, AttributeValue: p.attributeValue()}
|
---|
4266 | }
|
---|
4267 | return r
|
---|
4268 | }
|
---|
4269 |
|
---|
4270 | // attribute-value:
|
---|
4271 | // identifier
|
---|
4272 | // identifier ( expression-list_opt )
|
---|
4273 | func (p *parser) attributeValue() *AttributeValue {
|
---|
4274 | if p.rune() != IDENTIFIER {
|
---|
4275 | p.err("expected identifier")
|
---|
4276 | return nil
|
---|
4277 | }
|
---|
4278 |
|
---|
4279 | t := p.shift()
|
---|
4280 | if p.rune() != '(' {
|
---|
4281 | return &AttributeValue{Case: AttributeValueIdent, Token: t, lexicalScope: p.declScope}
|
---|
4282 | }
|
---|
4283 |
|
---|
4284 | p.ignoreKeywords = false
|
---|
4285 | t2 := p.shift()
|
---|
4286 | var list *ExpressionList
|
---|
4287 | if p.rune() != ')' {
|
---|
4288 | list = p.expressionList()
|
---|
4289 | }
|
---|
4290 | p.ignoreKeywords = true
|
---|
4291 | var t3 Token
|
---|
4292 | switch p.rune() {
|
---|
4293 | case ')':
|
---|
4294 | t3 = p.shift()
|
---|
4295 | default:
|
---|
4296 | p.err("expected )")
|
---|
4297 | }
|
---|
4298 | return &AttributeValue{Case: AttributeValueExpr, Token: t, Token2: t2, ExpressionList: list, Token3: t3, lexicalScope: p.declScope}
|
---|
4299 | }
|
---|
4300 |
|
---|
4301 | // expression-list:
|
---|
4302 | // assignment-expression
|
---|
4303 | // expression-list , assignment-expression
|
---|
4304 | func (p *parser) expressionList() (r *ExpressionList) {
|
---|
4305 | r = &ExpressionList{AssignmentExpression: p.assignmentExpression()}
|
---|
4306 | for prev := r; p.rune() == ','; prev = prev.ExpressionList {
|
---|
4307 | t := p.shift()
|
---|
4308 | prev.ExpressionList = &ExpressionList{Token: t, AssignmentExpression: p.assignmentExpression()}
|
---|
4309 | }
|
---|
4310 | return r
|
---|
4311 | }
|
---|