glslparser.cpp 44.2 KB
Newer Older
1

2
#line 424 "./glsl.g"
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

33
#include "glslparser.h"
34
#include "glslengine.h"
35
#include <iostream>
36
#include <cstdio>
37
#include <cassert>
Roberto Raggi's avatar
Roberto Raggi committed
38
#include <QtCore/QDebug>
39
40
41

using namespace GLSL;

42
Parser::Parser(Engine *engine, const char *source, unsigned size, int variant)
Roberto Raggi's avatar
Roberto Raggi committed
43
    : _engine(engine), _tos(-1), _index(0), yyloc(-1), yytoken(-1), yyrecovering(0), _recovered(false)
44
45
46
47
48
{
    _tokens.reserve(1024);

    _stateStack.resize(128);
    _locationStack.resize(128);
49
    _symStack.resize(128);
50
51
52
53
54
55
56

    _tokens.push_back(Token()); // invalid token

    std::stack<int> parenStack;
    std::stack<int> bracketStack;
    std::stack<int> braceStack;

57
    Lexer lexer(engine, source, size);
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    lexer.setVariant(variant);
    Token tk;
    do {
        lexer.yylex(&tk);

        switch (tk.kind) {
        case T_LEFT_PAREN:
            parenStack.push(_tokens.size());
            break;
        case T_LEFT_BRACKET:
            bracketStack.push(_tokens.size());
            break;
        case T_LEFT_BRACE:
            braceStack.push(_tokens.size());
            break;

        case T_RIGHT_PAREN:
            if (! parenStack.empty()) {
                _tokens[parenStack.top()].matchingBrace = _tokens.size();
                parenStack.pop();
            }
            break;
        case T_RIGHT_BRACKET:
            if (! bracketStack.empty()) {
                _tokens[bracketStack.top()].matchingBrace = _tokens.size();
                bracketStack.pop();
            }
            break;
        case T_RIGHT_BRACE:
            if (! braceStack.empty()) {
                _tokens[braceStack.top()].matchingBrace = _tokens.size();
                braceStack.pop();
            }
            break;
        default:
            break;
        }

        _tokens.push_back(tk);
    } while (tk.isNot(EOF_SYMBOL));

99
    _index = 0;
100
101
102
103
104
105
}

Parser::~Parser()
{
}

106
AST *Parser::parse(int startToken)
107
108
{
    int action = 0;
Roberto Raggi's avatar
Roberto Raggi committed
109
    yytoken = -1;
110
    yyloc = -1;
111
    void *yyval = 0; // value of the current token.
112

Roberto Raggi's avatar
Roberto Raggi committed
113
    _recovered = false;
114
    _tos = -1;
115
    _startToken.kind = startToken;
116
117

    do {
Roberto Raggi's avatar
Roberto Raggi committed
118
119
120
121
122
123
124
125
126
    again:
        if (unsigned(++_tos) == _stateStack.size()) {
            _stateStack.resize(_tos * 2);
            _locationStack.resize(_tos * 2);
            _symStack.resize(_tos * 2);
        }

        _stateStack[_tos] = action;

127
128
129
        if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) {
            yyloc = consumeToken();
            yytoken = tokenKind(yyloc);
Roberto Raggi's avatar
Roberto Raggi committed
130
131
            if (yyrecovering)
                --yyrecovering;
132
133
134
135
136
137
138
139
140
141
            if (yytoken == T_IDENTIFIER && t_action(action, T_TYPE_NAME) != 0) {
                const Token &la = tokenAt(_index);

                if (la.is(T_IDENTIFIER)) {
                    yytoken = T_TYPE_NAME;
                } else if (la.is(T_LEFT_BRACKET) && la.matchingBrace != 0 &&
                           tokenAt(la.matchingBrace + 1).is(T_IDENTIFIER)) {
                    yytoken = T_TYPE_NAME;
                }
            }
142
            yyval = _tokens.at(yyloc).ptr;
143
144
145
146
147
148
        }

        action = t_action(action, yytoken);
        if (action > 0) {
            if (action == ACCEPT_STATE) {
                --_tos;
149
                return _symStack[0].translation_unit;
150
            }
151
            _symStack[_tos].ptr = yyval;
152
153
154
155
156
157
            _locationStack[_tos] = yyloc;
            yytoken = -1;
        } else if (action < 0) {
            const int ruleno = -action - 1;
            const int N = rhs[ruleno];
            _tos -= N;
158
            reduce(ruleno);
159
            action = nt_action(_stateStack[_tos], lhs[ruleno] - TERMINAL_COUNT);
Roberto Raggi's avatar
Roberto Raggi committed
160
161
162
163
164
165
166
        } else if (action == 0) {
            const int line = _tokens[yyloc].line + 1;
            QString message = QLatin1String("Syntax error");
            if (yytoken != -1) {
                const QLatin1String s(spell[yytoken]);
                message = QString("Unexpected token `%1'").arg(s);
            }
167

Roberto Raggi's avatar
Roberto Raggi committed
168
169
170
171
172
173
174
175
            for (; _tos; --_tos) {
                const int state = _stateStack[_tos];

                static int tks[] = {
                    T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET,
                    T_SEMICOLON, T_COMMA, T_COLON,
                    T_NUMBER, T_TYPE_NAME, T_IDENTIFIER,
                    T_LEFT_BRACE, T_LEFT_PAREN, T_LEFT_BRACKET,
176
                    T_WHILE,
Roberto Raggi's avatar
Roberto Raggi committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
                    0
                };

                for (int *tptr = tks; *tptr; ++tptr) {
                    const int next = t_action(state, *tptr);
                    if (next > 0) {
                        if (! yyrecovering && ! _recovered) {
                            _recovered = true;
                            error(line, QString("Expected `%1'").arg(QLatin1String(spell[*tptr])));
                        }

                        yyrecovering = 3;
                        if (*tptr == T_IDENTIFIER)
                            yyval = (void *) _engine->identifier(QLatin1String("$identifier"));
                        else if (*tptr == T_NUMBER || *tptr == T_TYPE_NAME)
                            yyval = (void *) _engine->identifier(QLatin1String("$0"));
                        else
                            yyval = 0;

                        _symStack[_tos].ptr = yyval;
                        _locationStack[_tos] = yyloc;
                        yytoken = -1;

                        action = next;
                        goto again;
                    }
                }
            }
Roberto Raggi's avatar
Roberto Raggi committed
205

Roberto Raggi's avatar
Roberto Raggi committed
206
207
208
209
210
            if (! _recovered) {
                _recovered = true;
                error(line, message);
            }
        }
Roberto Raggi's avatar
Roberto Raggi committed
211

Roberto Raggi's avatar
Roberto Raggi committed
212
    } while (action);
213

214
    return 0;
215
}
216

217
#line 641 "./glsl.g"
218
219
220
221
222

void Parser::reduce(int ruleno)
{
switch(ruleno) {

223
#line 650 "./glsl.g"
224
225

case 0: {
226
    ast(1) = makeAstNode<IdentifierExpressionAST>(string(1));
227
228
}   break;

229
#line 657 "./glsl.g"
230
231

case 1: {
232
    ast(1) = makeAstNode<LiteralExpressionAST>(string(1));
233
234
}   break;

235
#line 664 "./glsl.g"
236
237

case 2: {
238
    ast(1) = makeAstNode<LiteralExpressionAST>(_engine->identifier("true", 4));
239
240
}   break;

241
#line 671 "./glsl.g"
242
243

case 3: {
244
    ast(1) = makeAstNode<LiteralExpressionAST>(_engine->identifier("false", 5));
245
246
}   break;

247
#line 678 "./glsl.g"
248
249

case 4: {
250
    // nothing to do.
251
252
}   break;

253
#line 685 "./glsl.g"
254
255

case 5: {
256
    ast(1) = ast(2);
257
258
}   break;

259
#line 692 "./glsl.g"
260
261

case 6: {
262
    // nothing to do.
263
264
}   break;

265
#line 699 "./glsl.g"
266
267

case 7: {
268
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_ArrayAccess, expression(1), expression(3));
269
270
}   break;

271
#line 706 "./glsl.g"
272
273

case 8: {
274
    // nothing to do.
275
276
}   break;

277
#line 713 "./glsl.g"
278
279

case 9: {
280
    ast(1) = makeAstNode<MemberAccessExpressionAST>(expression(1), string(3));
281
282
}   break;

283
#line 720 "./glsl.g"
284
285

case 10: {
286
    ast(1) = makeAstNode<UnaryExpressionAST>(AST::Kind_PostIncrement, expression(1));
287
288
}   break;

289
#line 727 "./glsl.g"
290
291

case 11: {
292
    ast(1) = makeAstNode<UnaryExpressionAST>(AST::Kind_PostDecrement, expression(1));
293
294
}   break;

295
#line 734 "./glsl.g"
296
297

case 12: {
298
    // nothing to do.
299
300
}   break;

301
#line 741 "./glsl.g"
302
303

case 13: {
304
    // nothing to do.
305
306
}   break;

307
#line 748 "./glsl.g"
308
309

case 14: {
310
    ast(1) = makeAstNode<FunctionCallExpressionAST>
311
        (sym(1).function.id, sym(1).function.arguments);
312
313
}   break;

314
#line 756 "./glsl.g"
315
316

case 15: {
317
    ast(1) = makeAstNode<FunctionCallExpressionAST>
318
        (expression(1), sym(3).function.id, sym(3).function.arguments);
319
320
}   break;

321
#line 764 "./glsl.g"
322
323

case 16: {
324
    // nothing to do.
325
326
}   break;

327
#line 771 "./glsl.g"
328
329

case 17: {
330
    // nothing to do.
331
332
}   break;

333
#line 778 "./glsl.g"
334
335

case 18: {
336
337
    sym(1).function.id = sym(1).function_identifier;
    sym(1).function.arguments = 0;
338
339
}   break;

340
#line 786 "./glsl.g"
341
342

case 19: {
343
344
    sym(1).function.id = sym(1).function_identifier;
    sym(1).function.arguments = 0;
345
346
}   break;

347
#line 794 "./glsl.g"
348
349

case 20: {
350
351
    sym(1).function.id = sym(1).function_identifier;
    sym(1).function.arguments =
352
        makeAstNode< List<ExpressionAST *> >(expression(2));
353
354
}   break;

355
#line 803 "./glsl.g"
356
357

case 21: {
358
    sym(1).function.arguments =
359
        makeAstNode< List<ExpressionAST *> >
360
            (sym(1).function.arguments, expression(3));
361
362
}   break;

363
#line 812 "./glsl.g"
364
365

case 22: {
366
    // nothing to do.
367
368
}   break;

369
#line 819 "./glsl.g"
370
371

case 23: {
372
    ast(1) = makeAstNode<FunctionIdentifierAST>(type(1));
373
374
}   break;

375
#line 826 "./glsl.g"
376
377

case 24: {
378
    ast(1) = makeAstNode<FunctionIdentifierAST>(string(1));
379
380
}   break;

381
#line 833 "./glsl.g"
382
383

case 25: {
384
    // nothing to do.
385
386
}   break;

387
#line 840 "./glsl.g"
388
389

case 26: {
390
    ast(1) = makeAstNode<UnaryExpressionAST>(AST::Kind_PreIncrement, expression(2));
391
392
}   break;

393
#line 847 "./glsl.g"
394
395

case 27: {
396
    ast(1) = makeAstNode<UnaryExpressionAST>(AST::Kind_PreDecrement, expression(2));
397
398
}   break;

399
#line 854 "./glsl.g"
400
401

case 28: {
402
    ast(1) = makeAstNode<UnaryExpressionAST>(sym(1).kind, expression(2));
403
404
}   break;

405
#line 861 "./glsl.g"
406
407

case 29: {
408
    sym(1).kind = AST::Kind_UnaryPlus;
409
410
}   break;

411
#line 868 "./glsl.g"
412
413

case 30: {
414
    sym(1).kind = AST::Kind_UnaryMinus;
415
416
}   break;

417
#line 875 "./glsl.g"
418
419

case 31: {
420
    sym(1).kind = AST::Kind_LogicalNot;
421
422
}   break;

423
#line 882 "./glsl.g"
424
425

case 32: {
426
    sym(1).kind = AST::Kind_BitwiseNot;
427
428
}   break;

429
#line 889 "./glsl.g"
430
431

case 33: {
432
    // nothing to do.
433
434
}   break;

435
#line 896 "./glsl.g"
436
437

case 34: {
438
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Multiply, expression(1), expression(3));
439
440
}   break;

441
#line 903 "./glsl.g"
442
443

case 35: {
444
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Divide, expression(1), expression(3));
445
446
}   break;

447
#line 910 "./glsl.g"
448
449

case 36: {
450
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Modulus, expression(1), expression(3));
451
452
}   break;

453
#line 917 "./glsl.g"
454
455

case 37: {
456
    // nothing to do.
457
458
}   break;

459
#line 924 "./glsl.g"
460
461

case 38: {
462
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Plus, expression(1), expression(3));
463
464
}   break;

465
#line 931 "./glsl.g"
466
467

case 39: {
468
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Minus, expression(1), expression(3));
469
470
}   break;

471
#line 938 "./glsl.g"
472
473

case 40: {
474
    // nothing to do.
475
476
}   break;

477
#line 945 "./glsl.g"
478
479

case 41: {
480
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_ShiftLeft, expression(1), expression(3));
481
482
}   break;

483
#line 952 "./glsl.g"
484
485

case 42: {
486
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_ShiftRight, expression(1), expression(3));
487
488
}   break;

489
#line 959 "./glsl.g"
490
491

case 43: {
492
    // nothing to do.
493
494
}   break;

495
#line 966 "./glsl.g"
496
497

case 44: {
498
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_LessThan, expression(1), expression(3));
499
500
}   break;

501
#line 973 "./glsl.g"
502
503

case 45: {
504
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_GreaterThan, expression(1), expression(3));
505
506
}   break;

507
#line 980 "./glsl.g"
508
509

case 46: {
510
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_LessEqual, expression(1), expression(3));
511
512
}   break;

513
#line 987 "./glsl.g"
514
515

case 47: {
516
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_GreaterEqual, expression(1), expression(3));
517
518
}   break;

519
#line 994 "./glsl.g"
520
521

case 48: {
522
    // nothing to do.
523
524
}   break;

525
#line 1001 "./glsl.g"
526
527

case 49: {
528
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Equal, expression(1), expression(3));
529
530
}   break;

531
#line 1008 "./glsl.g"
532
533

case 50: {
534
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_NotEqual, expression(1), expression(3));
535
536
}   break;

537
#line 1015 "./glsl.g"
538
539

case 51: {
540
    // nothing to do.
541
542
}   break;

543
#line 1022 "./glsl.g"
544
545

case 52: {
546
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_BitwiseAnd, expression(1), expression(3));
547
548
}   break;

549
#line 1029 "./glsl.g"
550
551

case 53: {
552
    // nothing to do.
553
554
}   break;

555
#line 1036 "./glsl.g"
556
557

case 54: {
558
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_BitwiseXor, expression(1), expression(3));
559
560
}   break;

561
#line 1043 "./glsl.g"
562
563

case 55: {
564
    // nothing to do.
565
566
}   break;

567
#line 1050 "./glsl.g"
568
569

case 56: {
570
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_BitwiseOr, expression(1), expression(3));
571
572
}   break;

573
#line 1057 "./glsl.g"
574
575

case 57: {
576
    // nothing to do.
577
578
}   break;

579
#line 1064 "./glsl.g"
580
581

case 58: {
582
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_LogicalAnd, expression(1), expression(3));
583
584
}   break;

585
#line 1071 "./glsl.g"
586
587

case 59: {
588
    // nothing to do.
589
590
}   break;

591
#line 1078 "./glsl.g"
592
593

case 60: {
594
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_LogicalXor, expression(1), expression(3));
595
596
}   break;

597
#line 1085 "./glsl.g"
598
599

case 61: {
600
    // nothing to do.
601
602
}   break;

603
#line 1092 "./glsl.g"
604
605

case 62: {
606
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_LogicalOr, expression(1), expression(3));
607
608
}   break;

609
#line 1099 "./glsl.g"
610
611

case 63: {
612
    // nothing to do.
613
614
}   break;

615
#line 1106 "./glsl.g"
616
617

case 64: {
618
    ast(1) = makeAstNode<TernaryExpressionAST>(AST::Kind_Conditional, expression(1), expression(3), expression(5));
619
620
}   break;

621
#line 1113 "./glsl.g"
622
623

case 65: {
624
    // nothing to do.
625
626
}   break;

627
#line 1120 "./glsl.g"
628
629

case 66: {
630
    ast(1) = makeAstNode<AssignmentExpressionAST>(sym(2).kind, expression(1), expression(3));
631
632
}   break;

633
#line 1127 "./glsl.g"
634
635

case 67: {
636
    sym(1).kind = AST::Kind_Assign;
637
638
}   break;

639
#line 1134 "./glsl.g"
640
641

case 68: {
642
    sym(1).kind = AST::Kind_AssignMultiply;
643
644
}   break;

645
#line 1141 "./glsl.g"
646
647

case 69: {
648
    sym(1).kind = AST::Kind_AssignDivide;
649
650
}   break;

651
#line 1148 "./glsl.g"
652
653

case 70: {
654
    sym(1).kind = AST::Kind_AssignModulus;
655
656
}   break;

657
#line 1155 "./glsl.g"
658
659

case 71: {
660
    sym(1).kind = AST::Kind_AssignPlus;
661
662
}   break;

663
#line 1162 "./glsl.g"
664
665

case 72: {
666
    sym(1).kind = AST::Kind_AssignMinus;
667
668
}   break;

669
#line 1169 "./glsl.g"
670
671

case 73: {
672
    sym(1).kind = AST::Kind_AssignShiftLeft;
673
674
}   break;

675
#line 1176 "./glsl.g"
676
677

case 74: {
678
    sym(1).kind = AST::Kind_AssignShiftRight;
679
680
}   break;

681
#line 1183 "./glsl.g"
682
683

case 75: {
684
    sym(1).kind = AST::Kind_AssignAnd;
685
686
}   break;

687
#line 1190 "./glsl.g"
688
689

case 76: {
690
    sym(1).kind = AST::Kind_AssignXor;
691
692
}   break;

693
#line 1197 "./glsl.g"
694
695

case 77: {
696
    sym(1).kind = AST::Kind_AssignOr;
697
698
}   break;

699
#line 1204 "./glsl.g"
700
701

case 78: {
702
    // nothing to do.
703
704
}   break;

705
#line 1211 "./glsl.g"
706
707

case 79: {
708
    ast(1) = makeAstNode<BinaryExpressionAST>(AST::Kind_Comma, expression(1), expression(3));
709
710
}   break;

711
#line 1218 "./glsl.g"
712
713

case 80: {
714
    // nothing to do.
715
716
}   break;

717
#line 1225 "./glsl.g"
718
719

case 81: {
720
    // nothing to do.
721
722
}   break;

723
#line 1232 "./glsl.g"
724
725

case 82: {
726
    ast(1) = makeAstNode<InitDeclarationAST>(sym(1).declaration_list);
727
728
}   break;

729
#line 1239 "./glsl.g"
730
731

case 83: {
732
    ast(1) = makeAstNode<PrecisionDeclarationAST>(sym(2).precision, type(3));
733
734
}   break;

735
#line 1246 "./glsl.g"
736
737

case 84: {
738
    if (sym(1).type_qualifier.qualifier != QualifiedTypeAST::Struct) {
739
740
        // TODO: issue an error if the qualifier is not "struct".
    }
741
742
    TypeAST *type = makeAstNode<StructTypeAST>(string(2), sym(4).field_list);
    ast(1) = makeAstNode<TypeDeclarationAST>(type);
743
744
}   break;

745
#line 1257 "./glsl.g"
746
747

case 85: {
748
    if ((sym(1).type_qualifier.qualifier & QualifiedTypeAST::Struct) == 0) {
749
750
        // TODO: issue an error if the qualifier does not contain "struct".
    }
751
752
753
754
755
    TypeAST *type = makeAstNode<StructTypeAST>(string(2), sym(4).field_list);
    TypeAST *qualtype = type;
    if (sym(1).type_qualifier.qualifier != QualifiedTypeAST::Struct) {
        qualtype = makeAstNode<QualifiedTypeAST>
            (sym(1).type_qualifier.qualifier & ~QualifiedTypeAST::Struct, qualtype,
756
757
             sym(1).type_qualifier.layout_list);
    }
758
759
760
    ast(1) = makeAstNode<TypeAndVariableDeclarationAST>
        (makeAstNode<TypeDeclarationAST>(type),
         makeAstNode<VariableDeclarationAST>(qualtype, string(6)));
761
762
}   break;

763
#line 1276 "./glsl.g"
764
765

case 86: {
766
    if ((sym(1).type_qualifier.qualifier & QualifiedTypeAST::Struct) == 0) {
767
768
        // TODO: issue an error if the qualifier does not contain "struct".
    }
769
770
771
772
773
    TypeAST *type = makeAstNode<StructTypeAST>(string(2), sym(4).field_list);
    TypeAST *qualtype = type;
    if (sym(1).type_qualifier.qualifier != QualifiedTypeAST::Struct) {
        qualtype = makeAstNode<QualifiedTypeAST>
            (sym(1).type_qualifier.qualifier & ~QualifiedTypeAST::Struct, qualtype,
774
775
             sym(1).type_qualifier.layout_list);
    }
776
777
778
779
    ast(1) = makeAstNode<TypeAndVariableDeclarationAST>
        (makeAstNode<TypeDeclarationAST>(type),
         makeAstNode<VariableDeclarationAST>
            (makeAstNode<ArrayTypeAST>(qualtype), string(6)));
780
781
}   break;

782
#line 1296 "./glsl.g"
783
784

case 87: {
785
    if ((sym(1).type_qualifier.qualifier & QualifiedTypeAST::Struct) == 0) {
786
787
        // TODO: issue an error if the qualifier does not contain "struct".
    }
788
789
790
791
792
    TypeAST *type = makeAstNode<StructTypeAST>(string(2), sym(4).field_list);
    TypeAST *qualtype = type;
    if (sym(1).type_qualifier.qualifier != QualifiedTypeAST::Struct) {
        qualtype = makeAstNode<QualifiedTypeAST>
            (sym(1).type_qualifier.qualifier & ~QualifiedTypeAST::Struct, qualtype,
793
794
             sym(1).type_qualifier.layout_list);
    }
795
796
797
798
    ast(1) = makeAstNode<TypeAndVariableDeclarationAST>
        (makeAstNode<TypeDeclarationAST>(type),
         makeAstNode<VariableDeclarationAST>
            (makeAstNode<ArrayTypeAST>(qualtype, expression(8)), string(6)));
799
800
}   break;

801
#line 1316 "./glsl.g"
802
803

case 88: {
804
805
    TypeAST *type = makeAstNode<QualifiedTypeAST>
        (sym(1).type_qualifier.qualifier, (TypeAST *)0,
806
         sym(1).type_qualifier.layout_list);
807
    ast(1) = makeAstNode<TypeDeclarationAST>(type);
808
809
}   break;

810
#line 1326 "./glsl.g"
811
812

case 89: {
813
    function(1)->finishParams();
814
815
}   break;

816
#line 1333 "./glsl.g"
817
818

case 90: {
819
    // nothing to do.
820
821
}   break;

822
#line 1340 "./glsl.g"
823
824

case 91: {
825
    // nothing to do.
826
827
}   break;

828
#line 1347 "./glsl.g"
829
830

case 92: {
831
    function(1)->params = makeAstNode< List<ParameterDeclarationAST *> >
832
        (sym(2).param_declaration);
833
834
}   break;

835
#line 1355 "./glsl.g"
836
837

case 93: {
838
    function(1)->params = makeAstNode< List<ParameterDeclarationAST *> >
839
        (function(1)->params, sym(3).param_declaration);
840
841
}   break;

842
#line 1363 "./glsl.g"
843
844

case 94: {
845
    function(1) = makeAstNode<FunctionDeclarationAST>(type(1), string(2));