/*
//
// 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;
            TType* field;
            TTypeList* structure;
        };
    } 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.field> struct_declarator
%type <interm> 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]->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]);
                            // 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], $3.line);
                        $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
                        $$->setType(*(*fields)[i]);
                    }
                } 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(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.structure, *$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.structure, TString(""));
        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
        $$.userDef = structure;
        context->exitStructDeclaration();
    }
    ;

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

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

        if (context->voidErrorCheck($1.line, (*$2.structure)[0]->getFieldName(), $1)) {
            context->recover();
        }
        for (unsigned int i = 0; i < $$.structure->size(); ++i) {
            //
            // Careful not to replace already known aspects of type, like array-ness
            //
            TType* type = (*$$.structure)[i];
            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 {
        $$.structure = NewPoolTTypeList();
        $$.structure->push_back($1);
    }
    | struct_declarator_list COMMA struct_declarator {
        $$.structure->push_back($3);
    }
    ;

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

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

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

        int size;
        if (context->arraySizeErrorCheck($2.line, $3, size))
            context->recover();
        $$->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);
}
