/*
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

This file contains the Yacc grammar for GLSL ES.
Based on ANSI C Yacc grammar:
http://www.lysator.liu.se/c/ANSI-C-grammar-y.html

IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
*/

%{
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// This file is auto-generated by generate_parser.sh. DO NOT EDIT!

// Ignore errors in auto-generated code.
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wswitch-enum"
#elif defined(_MSC_VER)
#pragma warning(disable: 4065)
#pragma warning(disable: 4189)
#pragma warning(disable: 4505)
#pragma warning(disable: 4701)
#endif

#include "compiler/SymbolTable.h"
#include "compiler/ParseHelper.h"
#include "GLSLANG/ShaderLang.h"

#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1

#define YYLEX_PARAM context->scanner
%}

%expect 1 /* One shift reduce conflict because of if | else */
%pure-parser
%parse-param {TParseContext* context}

%union {
    struct {
        TSourceLoc line;
        union {
            TString *string;
            float f;
            int i;
            bool b;
        };
        TSymbol* symbol;
    } lex;
    struct {
        TSourceLoc line;
        TOperator op;
        union {
            TIntermNode* intermNode;
            TIntermNodePair nodePair;
            TIntermTyped* intermTypedNode;
            TIntermAggregate* intermAggregate;
        };
        union {
            TPublicType type;
            TPrecision precision;
            TQualifier qualifier;
            TFunction* function;
            TParameter param;
            TTypeLine typeLine;
            TTypeList* typeList;
        };
    } interm;
}

%{
extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
extern void yyerror(TParseContext* context, const char* reason);

#define FRAG_VERT_ONLY(S, L) {  \
    if (context->shaderType != SH_FRAGMENT_SHADER &&  \
        context->shaderType != SH_VERTEX_SHADER) {  \
        context->error(L, " supported in vertex/fragment shaders only ", S);  \
        context->recover();  \
    }  \
}

#define VERTEX_ONLY(S, L) {  \
    if (context->shaderType != SH_VERTEX_SHADER) {  \
        context->error(L, " supported in vertex shaders only ", S);  \
        context->recover();  \
    }  \
}

#define FRAG_ONLY(S, L) {  \
    if (context->shaderType != SH_FRAGMENT_SHADER) {  \
        context->error(L, " supported in fragment shaders only ", S);  \
        context->recover();  \
    }  \
}
%}

%token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
%token <lex> STRUCT VOID_TYPE WHILE
%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT

%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
%token <lex> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token <lex> SUB_ASSIGN

%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION

%type <lex> identifier
%type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression
%type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
%type <interm.intermTypedNode> relational_expression equality_expression
%type <interm.intermTypedNode> conditional_expression constant_expression
%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
%type <interm.intermTypedNode> function_call initializer condition conditionopt

%type <interm.intermNode> translation_unit function_definition
%type <interm.intermNode> statement simple_statement
%type <interm.intermAggregate>  statement_list compound_statement
%type <interm.intermNode> declaration_statement selection_statement expression_statement
%type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
%type <interm.nodePair> selection_rest_statement for_rest_statement
%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
%type <interm> single_declaration init_declarator_list

%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
%type <interm.qualifier> parameter_qualifier

%type <interm.precision> precision_qualifier
%type <interm.type> type_qualifier fully_specified_type type_specifier
%type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
%type <interm> function_call_or_method

%start translation_unit
%%

identifier
    : IDENTIFIER
    | TYPE_NAME

variable_identifier
    : IDENTIFIER {
        // The symbol table search was done in the lexical phase
        const TSymbol* symbol = $1.symbol;
        const TVariable* variable;
        if (symbol == 0) {
            context->error($1.line, "undeclared identifier", $1.string->c_str());
            context->recover();
            TType type(EbtFloat, EbpUndefined);
            TVariable* fakeVariable = new TVariable($1.string, type);
            context->symbolTable.insert(*fakeVariable);
            variable = fakeVariable;
        } else {
            // This identifier can only be a variable type symbol
            if (! symbol->isVariable()) {
                context->error($1.line, "variable expected", $1.string->c_str());
                context->recover();
            }
            variable = static_cast<const TVariable*>(symbol);
        }

        // don't delete $1.string, it's used by error recovery, and the pool
        // pop will reclaim the memory

        if (variable->getType().getQualifier() == EvqConst ) {
            ConstantUnion* constArray = variable->getConstPointer();
            TType t(variable->getType());
            $$ = context->intermediate.addConstantUnion(constArray, t, $1.line);
        } else
            $$ = context->intermediate.addSymbol(variable->getUniqueId(),
                                                     variable->getName(),
                                                     variable->getType(), $1.line);
    }
    ;

primary_expression
    : variable_identifier {
        $$ = $1;
    }
    | INTCONSTANT {
        //
        // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
        // check for overflow for constants
        //
        if (abs($1.i) >= (1 << 16)) {
            context->error($1.line, " integer constant overflow", "");
            context->recover();
        }
        ConstantUnion *unionArray = new ConstantUnion[1];
        unionArray->setIConst($1.i);
        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
    }
    | FLOATCONSTANT {
        ConstantUnion *unionArray = new ConstantUnion[1];
        unionArray->setFConst($1.f);
        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
    }
    | BOOLCONSTANT {
        ConstantUnion *unionArray = new ConstantUnion[1];
        unionArray->setBConst($1.b);
        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line);
    }
    | LEFT_PAREN expression RIGHT_PAREN {
        $$ = $2;
    }
    ;

postfix_expression
    : primary_expression {
        $$ = $1;
    }
    | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
        if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
            if ($1->getAsSymbolNode())
                context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str());
            else
                context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression");
            context->recover();
        }
        if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
            if ($1->isArray()) { // constant folding for arrays
                $$ = context->addConstArrayNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
            } else if ($1->isVector()) {  // constant folding for vectors
                TVectorFields fields;
                fields.num = 1;
                fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
                $$ = context->addConstVectorNode(fields, $1, $2.line);
            } else if ($1->isMatrix()) { // constant folding for matrices
                $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
            }
        } else {
            if ($3->getQualifier() == EvqConst) {
                if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getIConst(0) && !$1->isArray() ) {
                    std::stringstream extraInfoStream;
                    extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
                    std::string extraInfo = extraInfoStream.str();
                    context->error($2.line, "", "[", extraInfo.c_str());
                    context->recover();
                } else {
                    if ($1->isArray()) {
                        if ($1->getType().getArraySize() == 0) {
                            if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getIConst(0)) {
                                if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, $2.line))
                                    context->recover();
                            } else {
                                if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
                                    context->recover();
                            }
                        } else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) {
                            std::stringstream extraInfoStream;
                            extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
                            std::string extraInfo = extraInfoStream.str();
                            context->error($2.line, "", "[", extraInfo.c_str());
                            context->recover();
                        }
                    }
                    $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
                }
            } else {
                if ($1->isArray() && $1->getType().getArraySize() == 0) {
                    context->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
                    context->recover();
                }

                $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
            }
        }
        if ($$ == 0) {
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setFConst(0.0f);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
        } else if ($1->isArray()) {
            if ($1->getType().getStruct())
                $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
            else
                $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));

            if ($1->getType().getQualifier() == EvqConst)
                $$->getTypePointer()->setQualifier(EvqConst);
        } else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
            $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, $1->getNominalSize()));
        else if ($1->isMatrix())
            $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize()));
        else if ($1->isVector() && $1->getType().getQualifier() == EvqConst)
            $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst));
        else if ($1->isVector())
            $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary));
        else
            $$->setType($1->getType());
    }
    | function_call {
        $$ = $1;
    }
    | postfix_expression DOT identifier {
        if ($1->isArray()) {
            context->error($3.line, "cannot apply dot operator to an array", ".");
            context->recover();
        }

        if ($1->isVector()) {
            TVectorFields fields;
            if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
                fields.num = 1;
                fields.offsets[0] = 0;
                context->recover();
            }

            if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
                $$ = context->addConstVectorNode(fields, $1, $3.line);
                if ($$ == 0) {
                    context->recover();
                    $$ = $1;
                }
                else
                    $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size()));
            } else {
                TString vectorString = *$3.string;
                TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line);
                $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
                $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
            }
        } else if ($1->isMatrix()) {
            TMatrixFields fields;
            if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
                fields.wholeRow = false;
                fields.wholeCol = false;
                fields.row = 0;
                fields.col = 0;
                context->recover();
            }

            if (fields.wholeRow || fields.wholeCol) {
                context->error($2.line, " non-scalar fields not implemented yet", ".");
                context->recover();
                ConstantUnion *unionArray = new ConstantUnion[1];
                unionArray->setIConst(0);
                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
                $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
            } else {
                ConstantUnion *unionArray = new ConstantUnion[1];
                unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
                $$->setType(TType($1->getBasicType(), $1->getPrecision()));
            }
        } else if ($1->getBasicType() == EbtStruct) {
            bool fieldFound = false;
            const TTypeList* fields = $1->getType().getStruct();
            if (fields == 0) {
                context->error($2.line, "structure has no fields", "Internal Error");
                context->recover();
                $$ = $1;
            } else {
                unsigned int i;
                for (i = 0; i < fields->size(); ++i) {
                    if ((*fields)[i].type->getFieldName() == *$3.string) {
                        fieldFound = true;
                        break;
                    }
                }
                if (fieldFound) {
                    if ($1->getType().getQualifier() == EvqConst) {
                        $$ = context->addConstStruct(*$3.string, $1, $2.line);
                        if ($$ == 0) {
                            context->recover();
                            $$ = $1;
                        }
                        else {
                            $$->setType(*(*fields)[i].type);
                            // change the qualifier of the return type, not of the structure field
                            // as the structure definition is shared between various structures.
                            $$->getTypePointer()->setQualifier(EvqConst);
                        }
                    } else {
                        ConstantUnion *unionArray = new ConstantUnion[1];
                        unionArray->setIConst(i);
                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
                        $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
                        $$->setType(*(*fields)[i].type);
                    }
                } else {
                    context->error($2.line, " no such field in structure", $3.string->c_str());
                    context->recover();
                    $$ = $1;
                }
            }
        } else {
            context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
            context->recover();
            $$ = $1;
        }
        // don't delete $3.string, it's from the pool
    }
    | postfix_expression INC_OP {
        if (context->lValueErrorCheck($2.line, "++", $1))
            context->recover();
        $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->unaryOpError($2.line, "++", $1->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    | postfix_expression DEC_OP {
        if (context->lValueErrorCheck($2.line, "--", $1))
            context->recover();
        $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->unaryOpError($2.line, "--", $1->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    ;

integer_expression
    : expression {
        if (context->integerErrorCheck($1, "[]"))
            context->recover();
        $$ = $1;
    }
    ;

function_call
    : function_call_or_method {
        TFunction* fnCall = $1.function;
        TOperator op = fnCall->getBuiltInOp();

        if (op != EOpNull)
        {
            //
            // Then this should be a constructor.
            // Don't go through the symbol table for constructors.
            // Their parameters will be verified algorithmically.
            //
            TType type(EbtVoid, EbpUndefined);  // use this to get the type back
            if (context->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
                $$ = 0;
            } else {
                //
                // It's a constructor, of type 'type'.
                //
                $$ = context->addConstructor($1.intermNode, &type, op, fnCall, $1.line);
            }

            if ($$ == 0) {
                context->recover();
                $$ = context->intermediate.setAggregateOperator(0, op, $1.line);
            }
            $$->setType(type);
        } else {
            //
            // Not a constructor.  Find it in the symbol table.
            //
            const TFunction* fnCandidate;
            bool builtIn;
            fnCandidate = context->findFunction($1.line, fnCall, &builtIn);
            if (fnCandidate) {
                //
                // A declared function.
                //
                if (builtIn && !fnCandidate->getExtension().empty() &&
                    context->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
                    context->recover();
                }
                op = fnCandidate->getBuiltInOp();
                if (builtIn && op != EOpNull) {
                    //
                    // A function call mapped to a built-in operation.
                    //
                    if (fnCandidate->getParamCount() == 1) {
                        //
                        // Treat it like a built-in unary operator.
                        //
                        $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable);
                        if ($$ == 0)  {
                            std::stringstream extraInfoStream;
                            extraInfoStream << "built in unary operator function.  Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
                            std::string extraInfo = extraInfoStream.str();
                            context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
                            YYERROR;
                        }
                    } else {
                        $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
                    }
                } else {
                    // This is a real function call

                    $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
                    $$->setType(fnCandidate->getReturnType());

                    // this is how we know whether the given function is a builtIn function or a user defined function
                    // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
                    // if builtIn == true, it's definitely a builtIn function with EOpNull
                    if (!builtIn)
                        $$->getAsAggregate()->setUserDefined();
                    $$->getAsAggregate()->setName(fnCandidate->getMangledName());

                    TQualifier qual;
                    for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
                        qual = fnCandidate->getParam(i).type->getQualifier();
                        if (qual == EvqOut || qual == EvqInOut) {
                            if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
                                context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
                                context->recover();
                            }
                        }
                    }
                }
                $$->setType(fnCandidate->getReturnType());
            } else {
                // error message was put out by PaFindFunction()
                // Put on a dummy node for error recovery
                ConstantUnion *unionArray = new ConstantUnion[1];
                unionArray->setFConst(0.0f);
                $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
                context->recover();
            }
        }
        delete fnCall;
    }
    ;

function_call_or_method
    : function_call_generic {
        $$ = $1;
    }
    | postfix_expression DOT function_call_generic {
        context->error($3.line, "methods are not supported", "");
        context->recover();
        $$ = $3;
    }
    ;

function_call_generic
    : function_call_header_with_parameters RIGHT_PAREN {
        $$ = $1;
        $$.line = $2.line;
    }
    | function_call_header_no_parameters RIGHT_PAREN {
        $$ = $1;
        $$.line = $2.line;
    }
    ;

function_call_header_no_parameters
    : function_call_header VOID_TYPE {
        $$.function = $1;
        $$.intermNode = 0;
    }
    | function_call_header {
        $$.function = $1;
        $$.intermNode = 0;
    }
    ;

function_call_header_with_parameters
    : function_call_header assignment_expression {
        TParameter param = { 0, new TType($2->getType()) };
        $1->addParameter(param);
        $$.function = $1;
        $$.intermNode = $2;
    }
    | function_call_header_with_parameters COMMA assignment_expression {
        TParameter param = { 0, new TType($3->getType()) };
        $1.function->addParameter(param);
        $$.function = $1.function;
        $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, $2.line);
    }
    ;

function_call_header
    : function_identifier LEFT_PAREN {
        $$ = $1;
    }
    ;

// Grammar Note:  Constructors look like functions, but are recognized as types.

function_identifier
    : type_specifier_nonarray {
        //
        // Constructor
        //
        TOperator op = EOpNull;
        if ($1.userDef) {
            op = EOpConstructStruct;
        } else {
            switch ($1.type) {
            case EbtFloat:
                if ($1.matrix) {
                    switch($1.size) {
                    case 2:                                     op = EOpConstructMat2;  break;
                    case 3:                                     op = EOpConstructMat3;  break;
                    case 4:                                     op = EOpConstructMat4;  break;
                    }
                } else {
                    switch($1.size) {
                    case 1:                                     op = EOpConstructFloat; break;
                    case 2:                                     op = EOpConstructVec2;  break;
                    case 3:                                     op = EOpConstructVec3;  break;
                    case 4:                                     op = EOpConstructVec4;  break;
                    }
                }
                break;
            case EbtInt:
                switch($1.size) {
                case 1:                                         op = EOpConstructInt;   break;
                case 2:       FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break;
                case 3:       FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break;
                case 4:       FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break;
                }
                break;
            case EbtBool:
                switch($1.size) {
                case 1:                                         op = EOpConstructBool;  break;
                case 2:       FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break;
                case 3:       FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break;
                case 4:       FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
                }
                break;
            default: break;
            }
            if (op == EOpNull) {
                context->error($1.line, "cannot construct this type", getBasicString($1.type));
                context->recover();
                $1.type = EbtFloat;
                op = EOpConstructFloat;
            }
        }
        TString tempString;
        TType type($1);
        TFunction *function = new TFunction(&tempString, type, op);
        $$ = function;
    }
    | IDENTIFIER {
        if (context->reservedErrorCheck($1.line, *$1.string))
            context->recover();
        TType type(EbtVoid, EbpUndefined);
        TFunction *function = new TFunction($1.string, type);
        $$ = function;
    }
    ;

unary_expression
    : postfix_expression {
        $$ = $1;
    }
    | INC_OP unary_expression {
        if (context->lValueErrorCheck($1.line, "++", $2))
            context->recover();
        $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable);
        if ($$ == 0) {
            context->unaryOpError($1.line, "++", $2->getCompleteString());
            context->recover();
            $$ = $2;
        }
    }
    | DEC_OP unary_expression {
        if (context->lValueErrorCheck($1.line, "--", $2))
            context->recover();
        $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable);
        if ($$ == 0) {
            context->unaryOpError($1.line, "--", $2->getCompleteString());
            context->recover();
            $$ = $2;
        }
    }
    | unary_operator unary_expression {
        if ($1.op != EOpNull) {
            $$ = context->intermediate.addUnaryMath($1.op, $2, $1.line, context->symbolTable);
            if ($$ == 0) {
                const char* errorOp = "";
                switch($1.op) {
                case EOpNegative:   errorOp = "-"; break;
                case EOpLogicalNot: errorOp = "!"; break;
                default: break;
                }
                context->unaryOpError($1.line, errorOp, $2->getCompleteString());
                context->recover();
                $$ = $2;
            }
        } else
            $$ = $2;
    }
    ;
// Grammar Note:  No traditional style type casts.

unary_operator
    : PLUS  { $$.line = $1.line; $$.op = EOpNull; }
    | DASH  { $$.line = $1.line; $$.op = EOpNegative; }
    | BANG  { $$.line = $1.line; $$.op = EOpLogicalNot; }
    ;
// Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.

multiplicative_expression
    : unary_expression { $$ = $1; }
    | multiplicative_expression STAR unary_expression {
        FRAG_VERT_ONLY("*", $2.line);
        $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    | multiplicative_expression SLASH unary_expression {
        FRAG_VERT_ONLY("/", $2.line);
        $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    ;

additive_expression
    : multiplicative_expression { $$ = $1; }
    | additive_expression PLUS multiplicative_expression {
        $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    | additive_expression DASH multiplicative_expression {
        $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    ;

shift_expression
    : additive_expression { $$ = $1; }
    ;

relational_expression
    : shift_expression { $$ = $1; }
    | relational_expression LEFT_ANGLE shift_expression {
        $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    | relational_expression RIGHT_ANGLE shift_expression  {
        $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    | relational_expression LE_OP shift_expression  {
        $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    | relational_expression GE_OP shift_expression  {
        $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    ;

equality_expression
    : relational_expression { $$ = $1; }
    | equality_expression EQ_OP relational_expression  {
        $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    | equality_expression NE_OP relational_expression {
        $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    ;

and_expression
    : equality_expression { $$ = $1; }
    ;

exclusive_or_expression
    : and_expression { $$ = $1; }
    ;

inclusive_or_expression
    : exclusive_or_expression { $$ = $1; }
    ;

logical_and_expression
    : inclusive_or_expression { $$ = $1; }
    | logical_and_expression AND_OP inclusive_or_expression {
        $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    ;

logical_xor_expression
    : logical_and_expression { $$ = $1; }
    | logical_xor_expression XOR_OP logical_and_expression  {
        $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    ;

logical_or_expression
    : logical_xor_expression { $$ = $1; }
    | logical_or_expression OR_OP logical_xor_expression  {
        $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, context->symbolTable);
        if ($$ == 0) {
            context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            ConstantUnion *unionArray = new ConstantUnion[1];
            unionArray->setBConst(false);
            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
        }
    }
    ;

conditional_expression
    : logical_or_expression { $$ = $1; }
    | logical_or_expression QUESTION expression COLON assignment_expression {
       if (context->boolErrorCheck($2.line, $1))
            context->recover();

        $$ = context->intermediate.addSelection($1, $3, $5, $2.line);
        if ($3->getType() != $5->getType())
            $$ = 0;

        if ($$ == 0) {
            context->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
            context->recover();
            $$ = $5;
        }
    }
    ;

assignment_expression
    : conditional_expression { $$ = $1; }
    | unary_expression assignment_operator assignment_expression {
        if (context->lValueErrorCheck($2.line, "assign", $1))
            context->recover();
        $$ = context->intermediate.addAssign($2.op, $1, $3, $2.line);
        if ($$ == 0) {
            context->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            $$ = $1;
        }
    }
    ;

assignment_operator
    : EQUAL        {                                    $$.line = $1.line; $$.op = EOpAssign; }
    | MUL_ASSIGN   { FRAG_VERT_ONLY("*=", $1.line);     $$.line = $1.line; $$.op = EOpMulAssign; }
    | DIV_ASSIGN   { FRAG_VERT_ONLY("/=", $1.line);     $$.line = $1.line; $$.op = EOpDivAssign; }
    | ADD_ASSIGN   {                                    $$.line = $1.line; $$.op = EOpAddAssign; }
    | SUB_ASSIGN   {                                    $$.line = $1.line; $$.op = EOpSubAssign; }
    ;

expression
    : assignment_expression {
        $$ = $1;
    }
    | expression COMMA assignment_expression {
        $$ = context->intermediate.addComma($1, $3, $2.line);
        if ($$ == 0) {
            context->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
            context->recover();
            $$ = $3;
        }
    }
    ;

constant_expression
    : conditional_expression {
        if (context->constErrorCheck($1))
            context->recover();
        $$ = $1;
    }
    ;

declaration
    : function_prototype SEMICOLON   {
        TFunction &function = *($1.function);
        
        TIntermAggregate *prototype = new TIntermAggregate;
        prototype->setType(function.getReturnType());
        prototype->setName(function.getName());
        
        for (size_t i = 0; i < function.getParamCount(); i++)
        {
            const TParameter &param = function.getParam(i);
            if (param.name != 0)
            {
                TVariable *variable = new TVariable(param.name, *param.type);
                
                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line);
            }
            else
            {
                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
            }
        }
        
        prototype->setOp(EOpPrototype);
        $$ = prototype;

        context->symbolTable.pop();
    }
    | init_declarator_list SEMICOLON {
        if ($1.intermAggregate)
            $1.intermAggregate->setOp(EOpDeclaration);
        $$ = $1.intermAggregate;
    }
    | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
        if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
            context->error($1.line, "precision is not supported in fragment shader", "highp");
            context->recover();
        }
        if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
            context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type));
            context->recover();
        }
        $$ = 0;
    }
    ;

function_prototype
    : function_declarator RIGHT_PAREN  {
        //
        // Multiple declarations of the same function are allowed.
        //
        // If this is a definition, the definition production code will check for redefinitions
        // (we don't know at this point if it's a definition or not).
        //
        // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
        //
        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
        if (prevDec) {
            if (prevDec->getReturnType() != $1->getReturnType()) {
                context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
                context->recover();
            }
            for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
                if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
                    context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
                    context->recover();
                }
            }
        }

        //
        // If this is a redeclaration, it could also be a definition,
        // in which case, we want to use the variable names from this one, and not the one that's
        // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
        //
        $$.function = $1;
        $$.line = $2.line;

        // We're at the inner scope level of the function's arguments and body statement.
        // Add the function prototype to the surrounding scope instead.
        context->symbolTable.getOuterLevel()->insert(*$$.function);
    }
    ;

function_declarator
    : function_header {
        $$ = $1;
    }
    | function_header_with_parameters {
        $$ = $1;
    }
    ;


function_header_with_parameters
    : function_header parameter_declaration {
        // Add the parameter
        $$ = $1;
        if ($2.param.type->getBasicType() != EbtVoid)
            $1->addParameter($2.param);
        else
            delete $2.param.type;
    }
    | function_header_with_parameters COMMA parameter_declaration {
        //
        // Only first parameter of one-parameter functions can be void
        // The check for named parameters not being void is done in parameter_declarator
        //
        if ($3.param.type->getBasicType() == EbtVoid) {
            //
            // This parameter > first is void
            //
            context->error($2.line, "cannot be an argument type except for '(void)'", "void");
            context->recover();
            delete $3.param.type;
        } else {
            // Add the parameter
            $$ = $1;
            $1->addParameter($3.param);
        }
    }
    ;

function_header
    : fully_specified_type IDENTIFIER LEFT_PAREN {
        if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
            context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
            context->recover();
        }
        // make sure a sampler is not involved as well...
        if (context->structQualifierErrorCheck($2.line, $1))
            context->recover();

        // Add the function as a prototype after parsing it (we do not support recursion)
        TFunction *function;
        TType type($1);
        function = new TFunction($2.string, type);
        $$ = function;
        
        context->symbolTable.push();
    }
    ;

parameter_declarator
    // Type + name
    : type_specifier identifier {
        if ($1.type == EbtVoid) {
            context->error($2.line, "illegal use of type 'void'", $2.string->c_str());
            context->recover();
        }
        if (context->reservedErrorCheck($2.line, *$2.string))
            context->recover();
        TParameter param = {$2.string, new TType($1)};
        $$.line = $2.line;
        $$.param = param;
    }
    | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
        // Check that we can make an array out of this type
        if (context->arrayTypeErrorCheck($3.line, $1))
            context->recover();

        if (context->reservedErrorCheck($2.line, *$2.string))
            context->recover();

        int size;
        if (context->arraySizeErrorCheck($3.line, $4, size))
            context->recover();
        $1.setArray(true, size);

        TType* type = new TType($1);
        TParameter param = { $2.string, type };
        $$.line = $2.line;
        $$.param = param;
    }
    ;

parameter_declaration
    //
    // The only parameter qualifier a parameter can have are
    // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
    //

    //
    // Type + name
    //
    : type_qualifier parameter_qualifier parameter_declarator {
        $$ = $3;
        if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
            context->recover();
    }
    | parameter_qualifier parameter_declarator {
        $$ = $2;
        if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
            context->recover();
        if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
            context->recover();
    }
    //
    // Only type
    //
    | type_qualifier parameter_qualifier parameter_type_specifier {
        $$ = $3;
        if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
            context->recover();
    }
    | parameter_qualifier parameter_type_specifier {
        $$ = $2;
        if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
            context->recover();
        if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
            context->recover();
    }
    ;

parameter_qualifier
    : /* empty */ {
        $$ = EvqIn;
    }
    | IN_QUAL {
        $$ = EvqIn;
    }
    | OUT_QUAL {
        $$ = EvqOut;
    }
    | INOUT_QUAL {
        $$ = EvqInOut;
    }
    ;

parameter_type_specifier
    : type_specifier {
        TParameter param = { 0, new TType($1) };
        $$.param = param;
    }
    ;

init_declarator_list
    : single_declaration {
        $$ = $1;
    }
    | init_declarator_list COMMA identifier {
        if ($1.type.type == EbtInvariant && !$3.symbol)
        {
            context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str());
            context->recover();
        }

        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line);
        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line);
        
        if (context->structQualifierErrorCheck($3.line, $$.type))
            context->recover();

        if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type, false))
            context->recover();

        TVariable* variable = 0;
        if (context->nonInitErrorCheck($3.line, *$3.string, $$.type, variable))
            context->recover();
        if (symbol && variable)
            symbol->setId(variable->getUniqueId());
    }
    | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
        if (context->structQualifierErrorCheck($3.line, $1.type))
            context->recover();

        if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true))
            context->recover();

        $$ = $1;

        if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
            context->recover();
        else {
            $1.type.setArray(true);
            TVariable* variable;
            if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
                context->recover();
        }
    }
    | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
        if (context->structQualifierErrorCheck($3.line, $1.type))
            context->recover();

        if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true))
            context->recover();

        $$ = $1;

        if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
            context->recover();
        else {
            int size;
            if (context->arraySizeErrorCheck($4.line, $5, size))
                context->recover();
            $1.type.setArray(true, size);
            TVariable* variable = 0;
            if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
                context->recover();
            TType type = TType($1.type);
            type.setArraySize(size);
            $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, $3.line), $3.line);
        }
    }
    | init_declarator_list COMMA identifier EQUAL initializer {
        if (context->structQualifierErrorCheck($3.line, $1.type))
            context->recover();

        $$ = $1;

        TIntermNode* intermNode;
        if (!context->executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
            //
            // build the intermediate representation
            //
            if (intermNode)
        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, $4.line);
            else
                $$.intermAggregate = $1.intermAggregate;
        } else {
            context->recover();
            $$.intermAggregate = 0;
        }
    }
    ;

single_declaration
    : fully_specified_type {
        $$.type = $1;
        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
    }
    | fully_specified_type identifier {
        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
        
        if (context->structQualifierErrorCheck($2.line, $$.type))
            context->recover();

        if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type, false))
            context->recover();
            
            $$.type = $1;

        TVariable* variable = 0;
        if (context->nonInitErrorCheck($2.line, *$2.string, $$.type, variable))
            context->recover();
        if (variable && symbol)
            symbol->setId(variable->getUniqueId());
    }
    | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET {
        context->error($2.line, "unsized array declarations not supported", $2.string->c_str());
        context->recover();

        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
        $$.type = $1;
    }
    | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
        TType type = TType($1);
        int size;
        if (context->arraySizeErrorCheck($2.line, $4, size))
            context->recover();
        type.setArraySize(size);
        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, $2.line);
        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
        
        if (context->structQualifierErrorCheck($2.line, $1))
            context->recover();

        if (context->nonInitConstErrorCheck($2.line, *$2.string, $1, true))
            context->recover();

        $$.type = $1;

        if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
            context->recover();
        else {
            int size;
            if (context->arraySizeErrorCheck($3.line, $4, size))
                context->recover();

            $1.setArray(true, size);
            TVariable* variable = 0;
            if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
                context->recover();
            if (variable && symbol)
                symbol->setId(variable->getUniqueId());
        }
    }
    | fully_specified_type identifier EQUAL initializer {
        if (context->structQualifierErrorCheck($2.line, $1))
            context->recover();

        $$.type = $1;

        TIntermNode* intermNode;
        if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
        //
        // Build intermediate representation
        //
            if(intermNode)
                $$.intermAggregate = context->intermediate.makeAggregate(intermNode, $3.line);
            else
                $$.intermAggregate = 0;
        } else {
            context->recover();
            $$.intermAggregate = 0;
        }
    }
    | INVARIANT IDENTIFIER {
        VERTEX_ONLY("invariant declaration", $1.line);
        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
            context->recover();
        $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line);
        if (!$2.symbol)
        {
            context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str());
            context->recover();
            
            $$.intermAggregate = 0;
        }
        else
        {
            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), $2.line);
            $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
        }
    }

//
// Place holder for the pack/unpack languages.
//
//    | buffer_specifier {
//        $$.intermAggregate = 0;
//    }
    ;

// Grammar Note:  No 'enum', or 'typedef'.

//
// Place holder for the pack/unpack languages.
//
//%type <interm> buffer_declaration
//%type <interm.type> buffer_specifier input_or_output buffer_declaration_list
//buffer_specifier
//    : input_or_output LEFT_BRACE buffer_declaration_list RIGHT_BRACE {
//    }
//    ;
//
//input_or_output
//    : INPUT {
//        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "input"))
//            context->recover();
//        UNPACK_ONLY("input", $1.line);
//        $$.qualifier = EvqInput;
//    }
//    | OUTPUT {
//        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "output"))
//            context->recover();
//        PACK_ONLY("output", $1.line);
//        $$.qualifier = EvqOutput;
//    }
//    ;

//
// Place holder for the pack/unpack languages.
//
//buffer_declaration_list
//    : buffer_declaration {
//    }
//    | buffer_declaration_list buffer_declaration {
//    }
//    ;

//
// Input/output semantics:
//   float must be 16 or 32 bits
//   float alignment restrictions?
//   check for only one input and only one output
//   sum of bitfields has to be multiple of 32
//

//
// Place holder for the pack/unpack languages.
//
//buffer_declaration
//    : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
//        if (context->reservedErrorCheck($2.line, *$2.string, context))
//            context->recover();
//        $$.variable = new TVariable($2.string, $1);
//        if (! context->symbolTable.insert(*$$.variable)) {
//            context->error($2.line, "redefinition", $$.variable->getName().c_str());
//            context->recover();
//            // don't have to delete $$.variable, the pool pop will take care of it
//        }
//    }
//    ;

fully_specified_type
    : type_specifier {
        $$ = $1;

        if ($1.array) {
            context->error($1.line, "not supported", "first-class array");
            context->recover();
            $1.setArray(false);
        }
    }
    | type_qualifier type_specifier  {
        if ($2.array) {
            context->error($2.line, "not supported", "first-class array");
            context->recover();
            $2.setArray(false);
        }

        if ($1.qualifier == EvqAttribute &&
            ($2.type == EbtBool || $2.type == EbtInt)) {
            context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier));
            context->recover();
        }
        if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
            ($2.type == EbtBool || $2.type == EbtInt)) {
            context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier));
            context->recover();
        }
        $$ = $2;
        $$.qualifier = $1.qualifier;
    }
    ;

type_qualifier
    : CONST_QUAL {
        $$.setBasic(EbtVoid, EvqConst, $1.line);
    }
    | ATTRIBUTE {
        VERTEX_ONLY("attribute", $1.line);
        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute"))
            context->recover();
        $$.setBasic(EbtVoid, EvqAttribute, $1.line);
    }
    | VARYING {
        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying"))
            context->recover();
        if (context->shaderType == SH_VERTEX_SHADER)
            $$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
        else
            $$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
    }
    | INVARIANT VARYING {
        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
            context->recover();
        if (context->shaderType == SH_VERTEX_SHADER)
            $$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line);
        else
            $$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
    }
    | UNIFORM {
        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform"))
            context->recover();
        $$.setBasic(EbtVoid, EvqUniform, $1.line);
    }
    ;

type_specifier
    : type_specifier_no_prec {
        $$ = $1;

        if ($$.precision == EbpUndefined) {
            $$.precision = context->symbolTable.getDefaultPrecision($1.type);
            if (context->precisionErrorCheck($1.line, $$.precision, $1.type)) {
                context->recover();
            }
        }
    }
    | precision_qualifier type_specifier_no_prec {
        $$ = $2;
        $$.precision = $1;
    }
    ;

precision_qualifier
    : HIGH_PRECISION {
        $$ = EbpHigh;
    }
    | MEDIUM_PRECISION {
        $$ = EbpMedium;
    }
    | LOW_PRECISION  {
        $$ = EbpLow;
    }
    ;

type_specifier_no_prec
    : type_specifier_nonarray {
        $$ = $1;
    }
    | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
        $$ = $1;

        if (context->arrayTypeErrorCheck($2.line, $1))
            context->recover();
        else {
            int size;
            if (context->arraySizeErrorCheck($2.line, $3, size))
                context->recover();
            $$.setArray(true, size);
        }
    }
    ;

type_specifier_nonarray
    : VOID_TYPE {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtVoid, qual, $1.line);
    }
    | FLOAT_TYPE {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
    }
    | INT_TYPE {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtInt, qual, $1.line);
    }
    | BOOL_TYPE {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtBool, qual, $1.line);
    }
//    | UNSIGNED INT_TYPE {
//        PACK_UNPACK_ONLY("unsigned", $1.line);
//        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
//        $$.setBasic(EbtInt, qual, $1.line);
//    }
    | VEC2 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
        $$.setAggregate(2);
    }
    | VEC3 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
        $$.setAggregate(3);
    }
    | VEC4 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
        $$.setAggregate(4);
    }
    | BVEC2 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtBool, qual, $1.line);
        $$.setAggregate(2);
    }
    | BVEC3 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtBool, qual, $1.line);
        $$.setAggregate(3);
    }
    | BVEC4 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtBool, qual, $1.line);
        $$.setAggregate(4);
    }
    | IVEC2 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtInt, qual, $1.line);
        $$.setAggregate(2);
    }
    | IVEC3 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtInt, qual, $1.line);
        $$.setAggregate(3);
    }
    | IVEC4 {
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtInt, qual, $1.line);
        $$.setAggregate(4);
    }
    | MATRIX2 {
        FRAG_VERT_ONLY("mat2", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
        $$.setAggregate(2, true);
    }
    | MATRIX3 {
        FRAG_VERT_ONLY("mat3", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
        $$.setAggregate(3, true);
    }
    | MATRIX4 {
        FRAG_VERT_ONLY("mat4", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtFloat, qual, $1.line);
        $$.setAggregate(4, true);
    }
    | SAMPLER2D {
        FRAG_VERT_ONLY("sampler2D", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtSampler2D, qual, $1.line);
    }
    | SAMPLERCUBE {
        FRAG_VERT_ONLY("samplerCube", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtSamplerCube, qual, $1.line);
    }
    | SAMPLER_EXTERNAL_OES {
        if (!context->supportsExtension("GL_OES_EGL_image_external")) {
            context->error($1.line, "unsupported type", "samplerExternalOES");
            context->recover();
        }
        FRAG_VERT_ONLY("samplerExternalOES", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtSamplerExternalOES, qual, $1.line);
    }
    | SAMPLER2DRECT {
        if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
            context->error($1.line, "unsupported type", "sampler2DRect");
            context->recover();
        }
        FRAG_VERT_ONLY("sampler2DRect", $1.line);
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtSampler2DRect, qual, $1.line);
    }
    | struct_specifier {
        FRAG_VERT_ONLY("struct", $1.line);
        $$ = $1;
        $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
    }
    | TYPE_NAME {
        //
        // This is for user defined type names.  The lexical phase looked up the
        // type.
        //
        TType& structure = static_cast<TVariable*>($1.symbol)->getType();
        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
        $$.setBasic(EbtStruct, qual, $1.line);
        $$.userDef = &structure;
    }
    ;

struct_specifier
    : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
        if (context->reservedErrorCheck($2.line, *$2.string))
            context->recover();

        TType* structure = new TType($5, *$2.string);
        TVariable* userTypeDef = new TVariable($2.string, *structure, true);
        if (! context->symbolTable.insert(*userTypeDef)) {
            context->error($2.line, "redefinition", $2.string->c_str(), "struct");
            context->recover();
        }
        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
        $$.userDef = structure;
        context->exitStructDeclaration();
    }
    | STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
        TType* structure = new TType($4, TString(""));
        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
        $$.userDef = structure;
        context->exitStructDeclaration();
    }
    ;

struct_declaration_list
    : struct_declaration {
        $$ = $1;
    }
    | struct_declaration_list struct_declaration {
        $$ = $1;
        for (unsigned int i = 0; i < $2->size(); ++i) {
            for (unsigned int j = 0; j < $$->size(); ++j) {
                if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
                    context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
                    context->recover();
                }
            }
            $$->push_back((*$2)[i]);
        }
    }
    ;

struct_declaration
    : type_specifier struct_declarator_list SEMICOLON {
        $$ = $2;

        if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
            context->recover();
        }
        for (unsigned int i = 0; i < $$->size(); ++i) {
            //
            // Careful not to replace already known aspects of type, like array-ness
            //
            TType* type = (*$$)[i].type;
            type->setBasicType($1.type);
            type->setNominalSize($1.size);
            type->setMatrix($1.matrix);
            type->setPrecision($1.precision);

            // don't allow arrays of arrays
            if (type->isArray()) {
                if (context->arrayTypeErrorCheck($1.line, $1))
                    context->recover();
            }
            if ($1.array)
                type->setArraySize($1.arraySize);
            if ($1.userDef) {
                type->setStruct($1.userDef->getStruct());
                type->setTypeName($1.userDef->getTypeName());
            }

            if (context->structNestingErrorCheck($1.line, *type)) {
                context->recover();
            }
        }
    }
    ;

struct_declarator_list
    : struct_declarator {
        $$ = NewPoolTTypeList();
        $$->push_back($1);
    }
    | struct_declarator_list COMMA struct_declarator {
        $$->push_back($3);
    }
    ;

struct_declarator
    : identifier {
        if (context->reservedErrorCheck($1.line, *$1.string))
            context->recover();

        $$.type = new TType(EbtVoid, EbpUndefined);
        $$.line = $1.line;
        $$.type->setFieldName(*$1.string);
    }
    | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
        if (context->reservedErrorCheck($1.line, *$1.string))
            context->recover();

        $$.type = new TType(EbtVoid, EbpUndefined);
        $$.line = $1.line;
        $$.type->setFieldName(*$1.string);

        int size;
        if (context->arraySizeErrorCheck($2.line, $3, size))
            context->recover();
        $$.type->setArraySize(size);
    }
    ;

initializer
    : assignment_expression { $$ = $1; }
    ;

declaration_statement
    : declaration { $$ = $1; }
    ;

statement
    : compound_statement  { $$ = $1; }
    | simple_statement    { $$ = $1; }
    ;

// Grammar Note:  No labeled statements; 'goto' is not supported.

simple_statement
    : declaration_statement { $$ = $1; }
    | expression_statement  { $$ = $1; }
    | selection_statement   { $$ = $1; }
    | iteration_statement   { $$ = $1; }
    | jump_statement        { $$ = $1; }
    ;

compound_statement
    : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
    | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
        if ($3 != 0) {
            $3->setOp(EOpSequence);
            $3->setEndLine($5.line);
        }
        $$ = $3;
    }
    ;

statement_no_new_scope
    : compound_statement_no_new_scope { $$ = $1; }
    | simple_statement                { $$ = $1; }
    ;

statement_with_scope
    : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
    | { context->symbolTable.push(); } simple_statement                { context->symbolTable.pop(); $$ = $2; }
    ;

compound_statement_no_new_scope
    // Statement that doesn't create a new scope, for selection_statement, iteration_statement
    : LEFT_BRACE RIGHT_BRACE {
        $$ = 0;
    }
    | LEFT_BRACE statement_list RIGHT_BRACE {
        if ($2) {
            $2->setOp(EOpSequence);
            $2->setEndLine($3.line);
        }
        $$ = $2;
    }
    ;

statement_list
    : statement {
        $$ = context->intermediate.makeAggregate($1, 0);
    }
    | statement_list statement {
        $$ = context->intermediate.growAggregate($1, $2, 0);
    }
    ;

expression_statement
    : SEMICOLON  { $$ = 0; }
    | expression SEMICOLON  { $$ = static_cast<TIntermNode*>($1); }
    ;

selection_statement
    : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
        if (context->boolErrorCheck($1.line, $3))
            context->recover();
        $$ = context->intermediate.addSelection($3, $5, $1.line);
    }
    ;

selection_rest_statement
    : statement_with_scope ELSE statement_with_scope {
        $$.node1 = $1;
        $$.node2 = $3;
    }
    | statement_with_scope {
        $$.node1 = $1;
        $$.node2 = 0;
    }
    ;

// Grammar Note:  No 'switch'.  Switch statements not supported.

condition
    // In 1996 c++ draft, conditions can include single declarations
    : expression {
        $$ = $1;
        if (context->boolErrorCheck($1->getLine(), $1))
            context->recover();
    }
    | fully_specified_type identifier EQUAL initializer {
        TIntermNode* intermNode;
        if (context->structQualifierErrorCheck($2.line, $1))
            context->recover();
        if (context->boolErrorCheck($2.line, $1))
            context->recover();

        if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
            $$ = $4;
        else {
            context->recover();
            $$ = 0;
        }
    }
    ;

iteration_statement
    : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
        context->symbolTable.pop();
        $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
        --context->loopNestingLevel;
    }
    | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
        if (context->boolErrorCheck($8.line, $6))
            context->recover();

        $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line);
        --context->loopNestingLevel;
    }
    | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
        context->symbolTable.pop();
        $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, $1.line);
        --context->loopNestingLevel;
    }
    ;

for_init_statement
    : expression_statement {
        $$ = $1;
    }
    | declaration_statement {
        $$ = $1;
    }
    ;

conditionopt
    : condition {
        $$ = $1;
    }
    | /* May be null */ {
        $$ = 0;
    }
    ;

for_rest_statement
    : conditionopt SEMICOLON {
        $$.node1 = $1;
        $$.node2 = 0;
    }
    | conditionopt SEMICOLON expression  {
        $$.node1 = $1;
        $$.node2 = $3;
    }
    ;

jump_statement
    : CONTINUE SEMICOLON {
        if (context->loopNestingLevel <= 0) {
            context->error($1.line, "continue statement only allowed in loops", "");
            context->recover();
        }
        $$ = context->intermediate.addBranch(EOpContinue, $1.line);
    }
    | BREAK SEMICOLON {
        if (context->loopNestingLevel <= 0) {
            context->error($1.line, "break statement only allowed in loops", "");
            context->recover();
        }
        $$ = context->intermediate.addBranch(EOpBreak, $1.line);
    }
    | RETURN SEMICOLON {
        $$ = context->intermediate.addBranch(EOpReturn, $1.line);
        if (context->currentFunctionType->getBasicType() != EbtVoid) {
            context->error($1.line, "non-void function must return a value", "return");
            context->recover();
        }
    }
    | RETURN expression SEMICOLON {
        $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line);
        context->functionReturnsValue = true;
        if (context->currentFunctionType->getBasicType() == EbtVoid) {
            context->error($1.line, "void function cannot return a value", "return");
            context->recover();
        } else if (*(context->currentFunctionType) != $2->getType()) {
            context->error($1.line, "function return is not matching type:", "return");
            context->recover();
        }
    }
    | DISCARD SEMICOLON {
        FRAG_ONLY("discard", $1.line);
        $$ = context->intermediate.addBranch(EOpKill, $1.line);
    }
    ;

// Grammar Note:  No 'goto'.  Gotos are not supported.

translation_unit
    : external_declaration {
        $$ = $1;
        context->treeRoot = $$;
    }
    | translation_unit external_declaration {
        $$ = context->intermediate.growAggregate($1, $2, 0);
        context->treeRoot = $$;
    }
    ;

external_declaration
    : function_definition {
        $$ = $1;
    }
    | declaration {
        $$ = $1;
    }
    ;

function_definition
    : function_prototype {
        TFunction* function = $1.function;
        
        const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName());
        
        if (builtIn)
        {
            context->error($1.line, "built-in functions cannot be redefined", function->getName().c_str());
            context->recover();
        }
        
        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
        //
        // Note:  'prevDec' could be 'function' if this is the first time we've seen function
        // as it would have just been put in the symbol table.  Otherwise, we're looking up
        // an earlier occurance.
        //
        if (prevDec->isDefined()) {
            //
            // Then this function already has a body.
            //
            context->error($1.line, "function already has a body", function->getName().c_str());
            context->recover();
        }
        prevDec->setDefined();

        //
        // Raise error message if main function takes any parameters or return anything other than void
        //
        if (function->getName() == "main") {
            if (function->getParamCount() > 0) {
                context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str());
                context->recover();
            }
            if (function->getReturnType().getBasicType() != EbtVoid) {
                context->error($1.line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
                context->recover();
            }
        }

        //
        // Remember the return type for later checking for RETURN statements.
        //
        context->currentFunctionType = &(prevDec->getReturnType());
        context->functionReturnsValue = false;

        //
        // Insert parameters into the symbol table.
        // If the parameter has no name, it's not an error, just don't insert it
        // (could be used for unused args).
        //
        // Also, accumulate the list of parameters into the HIL, so lower level code
        // knows where to find parameters.
        //
        TIntermAggregate* paramNodes = new TIntermAggregate;
        for (size_t i = 0; i < function->getParamCount(); i++) {
            const TParameter& param = function->getParam(i);
            if (param.name != 0) {
                TVariable *variable = new TVariable(param.name, *param.type);
                //
                // Insert the parameters with name in the symbol table.
                //
                if (! context->symbolTable.insert(*variable)) {
                    context->error($1.line, "redefinition", variable->getName().c_str());
                    context->recover();
                    delete variable;
                }

                //
                // Add the parameter to the HIL
                //
                paramNodes = context->intermediate.growAggregate(
                                               paramNodes,
                                               context->intermediate.addSymbol(variable->getUniqueId(),
                                                                       variable->getName(),
                                                                       variable->getType(), $1.line),
                                               $1.line);
            } else {
                paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
            }
        }
        context->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
        $1.intermAggregate = paramNodes;
        context->loopNestingLevel = 0;
    }
    compound_statement_no_new_scope {
        //?? Check that all paths return a value if return type != void ?
        //   May be best done as post process phase on intermediate code
        if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
            context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
            context->recover();
        }
        
        $$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0);
        context->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
        $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
        $$->getAsAggregate()->setType($1.function->getReturnType());

        // store the pragma information for debug and optimize and other vendor specific
        // information. This information can be queried from the parse tree
        $$->getAsAggregate()->setOptimize(context->pragma().optimize);
        $$->getAsAggregate()->setDebug(context->pragma().debug);

        if ($3 && $3->getAsAggregate())
            $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());

        context->symbolTable.pop();
    }
    ;

%%

int glslang_parse(TParseContext* context) {
    return yyparse(context);
}
