public void VisitNode(Nodes.Expression node) //left OP right
 {
     VisitChildren(node);
     //do type check by comparing op1 and op 2 for type
     if (node.left.symInfo.pType == node.right.symInfo.pType)                                 //ptypes match
     {
         if (node.left.symInfo.pType == Nodes.primType.CLASS)                                 //if both are classes
         {
             if (!node.left.symInfo.customTypeName.Equals(node.right.symInfo.customTypeName)) //if custom types not equal
             {
                 Console.WriteLine("TYPES {0} AND {1} NOT EQUAL! OPERATOR: {2} ", node.left.symInfo.customTypeName, node.right.symInfo.customTypeName, node.opType);
             }
         }
     }
     else
     {
         Console.WriteLine("TYPES {0} and {1} NOT EQUAL! OP type: {2}", node.left.symInfo.pType, node.right.symInfo.pType, node.opType);
     }
     //how to handle arrays?
     node.symInfo.pType = node.left.symInfo.pType;
     //this.symTable.enter(node.left.)
 }
        protected override void DoAction(int action)
        {
#pragma warning disable 162, 1522
            switch (action)
            {
            case 2: // CompilationUnit -> ClassDeclaration
            { CurrentSemanticValue = new Nodes.CompilationUnit(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 3: // ClassDeclaration -> Modifiers, CLASS, Identifier, ClassBody
            { CurrentSemanticValue = new Nodes.ClassDeclaration(ValueStack[ValueStack.Depth - 4], ValueStack[ValueStack.Depth - 2], ValueStack[ValueStack.Depth - 1]); }
            break;

            case 4: // Modifiers -> PUBLIC
            { CurrentSemanticValue = new Nodes.Modifiers(Nodes.modType.PUBLIC); }
            break;

            case 5: // Modifiers -> PRIVATE
            { CurrentSemanticValue = new Nodes.Modifiers(Nodes.modType.PRIVATE); }
            break;

            case 6: // Modifiers -> STATIC
            { CurrentSemanticValue = new Nodes.Modifiers(Nodes.modType.STATIC); }
            break;

            case 7: // Modifiers -> Modifiers, PUBLIC
            { CurrentSemanticValue = new Nodes.Modifiers(Nodes.modType.PUBLIC, ValueStack[ValueStack.Depth - 2]); }
            break;

            case 8: // Modifiers -> Modifiers, PRIVATE
            { CurrentSemanticValue = new Nodes.Modifiers(Nodes.modType.PRIVATE, ValueStack[ValueStack.Depth - 2]); }
            break;

            case 9: // Modifiers -> Modifiers, STATIC
            { CurrentSemanticValue = new Nodes.Modifiers(Nodes.modType.STATIC, ValueStack[ValueStack.Depth - 2]); }
            break;

            case 10: // ClassBody -> LBRACE, FieldDeclarations, RBRACE
            { CurrentSemanticValue = new Nodes.ClassBody(ValueStack[ValueStack.Depth - 2]); }
            break;

            case 11: // ClassBody -> LBRACE, RBRACE
            { CurrentSemanticValue = new Nodes.ClassBody(); }
            break;

            case 12: // FieldDeclarations -> FieldDeclaration
            { CurrentSemanticValue = new Nodes.FieldDecls(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 13: // FieldDeclarations -> FieldDeclarations, FieldDeclaration
            { ValueStack[ValueStack.Depth - 2].adoptChildren(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 14: // FieldDeclaration -> FieldVariableDeclaration, SEMICOLON
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 2]; }
            break;

            case 15: // FieldDeclaration -> MethodDeclaration
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 20: // FieldVariableDeclaration -> Modifiers, TypeSpecifier, FieldVariableDeclarators
            { CurrentSemanticValue = new Nodes.FieldVarDecl(ValueStack[ValueStack.Depth - 3], ValueStack[ValueStack.Depth - 2], ValueStack[ValueStack.Depth - 1]); }
            break;

            case 21: // TypeSpecifier -> TypeName
            { CurrentSemanticValue = new Nodes.TypeSpec(ValueStack[ValueStack.Depth - 1], false); }
            break;

            case 22: // TypeSpecifier -> ArraySpecifier
            { CurrentSemanticValue = new Nodes.TypeSpec(ValueStack[ValueStack.Depth - 1], true); }
            break;

            case 23: // TypeName -> PrimitiveType
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 24: // TypeName -> QualifiedName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 25: // ArraySpecifier -> TypeName, LBRACKET, RBRACKET
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 3]; }
            break;

            case 26: // PrimitiveType -> BOOLEAN
            { CurrentSemanticValue = new Nodes.Primitive(Nodes.primType.BOOLEAN); }
            break;

            case 27: // PrimitiveType -> INT
            { CurrentSemanticValue = new Nodes.Primitive(Nodes.primType.INT); }
            break;

            case 28: // PrimitiveType -> VOID
            { CurrentSemanticValue = new Nodes.Primitive(Nodes.primType.VOID); }
            break;

            case 29: // FieldVariableDeclarators -> FieldVariableDeclaratorName
            { CurrentSemanticValue = new Nodes.FieldVarDeclarators(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 30: // FieldVariableDeclarators -> FieldVariableDeclarators, COMMA,
                     //                             FieldVariableDeclaratorName
            { CurrentSemanticValue = new Nodes.FieldVarDeclarators(ValueStack[ValueStack.Depth - 1], ValueStack[ValueStack.Depth - 3]); }
            break;

            case 31: // MethodDeclaration -> Modifiers, TypeSpecifier, MethodDeclarator, MethodBody
            { CurrentSemanticValue = new Nodes.MethodDeclaration(ValueStack[ValueStack.Depth - 4], ValueStack[ValueStack.Depth - 3], ValueStack[ValueStack.Depth - 2], ValueStack[ValueStack.Depth - 1]); }
            break;

            case 32: // MethodDeclarator -> MethodDeclaratorName, LPAREN, ParameterList, RPAREN
            { CurrentSemanticValue = new Nodes.MethodDeclarator(ValueStack[ValueStack.Depth - 4], ValueStack[ValueStack.Depth - 2]); }
            break;

            case 33: // MethodDeclarator -> MethodDeclaratorName, LPAREN, RPAREN
            { CurrentSemanticValue = new Nodes.MethodDeclarator(ValueStack[ValueStack.Depth - 3]); }
            break;

            case 34: // ParameterList -> Parameter
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 35: // ParameterList -> ParameterList, COMMA, Parameter
            { ValueStack[ValueStack.Depth - 3].makeSibling(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 36: // Parameter -> TypeSpecifier, DeclaratorName
            { CurrentSemanticValue = new Nodes.Parameter(ValueStack[ValueStack.Depth - 2], ValueStack[ValueStack.Depth - 1]); }
            break;

            case 37: // QualifiedName -> Identifier
            { CurrentSemanticValue = new Nodes.QualName(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 38: // QualifiedName -> QualifiedName, PERIOD, Identifier
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 3]; ((Nodes.QualName)ValueStack[ValueStack.Depth - 3]).append(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 39: // DeclaratorName -> Identifier
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 40: // MethodDeclaratorName -> Identifier
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 41: // FieldVariableDeclaratorName -> Identifier
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 42: // LocalVariableDeclaratorName -> Identifier
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 43: // MethodBody -> Block
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 46: // Block -> LBRACE, LocalVariableDeclarationsAndStatements, RBRACE
            { CurrentSemanticValue = new Nodes.Locals_and_Stmts(ValueStack[ValueStack.Depth - 2]); }
            break;

            case 47: // Block -> LBRACE, RBRACE
            { CurrentSemanticValue = new Nodes.Empty(); }
            break;

            case 48: // LocalVariableDeclarationsAndStatements -> LocalVariableDeclarationOrStatement
            { CurrentSemanticValue = new Nodes.LocalFDOS(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 49: // LocalVariableDeclarationsAndStatements ->
                     //                                           LocalVariableDeclarationsAndStatements,
                     //                                           LocalVariableDeclarationOrStatement
            { ValueStack[ValueStack.Depth - 2].adoptChildren(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 50: // LocalVariableDeclarationOrStatement -> LocalVariableDeclarationStatement
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 51: // LocalVariableDeclarationOrStatement -> Statement
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 52: // LocalVariableDeclarationStatement -> TypeSpecifier, LocalVariableDeclarators,
                     //                                      SEMICOLON
            { CurrentSemanticValue = new Nodes.LocalVDS(ValueStack[ValueStack.Depth - 3], ValueStack[ValueStack.Depth - 2]); }
            break;

            case 54: // LocalVariableDeclarators -> LocalVariableDeclaratorName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 55: // LocalVariableDeclarators -> LocalVariableDeclarators, COMMA,
                     //                             LocalVariableDeclaratorName
            { ValueStack[ValueStack.Depth - 3].makeSibling(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 56: // Statement -> EmptyStatement
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 57: // Statement -> ExpressionStatement, SEMICOLON
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 2]; }
            break;

            case 58: // Statement -> SelectionStatement
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 59: // Statement -> IterationStatement
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 60: // Statement -> ReturnStatement
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 61: // Statement -> Block
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 62: // EmptyStatement -> SEMICOLON
            { CurrentSemanticValue = new Nodes.Empty(); }
            break;

            case 64: // SelectionStatement -> IF, LPAREN, Expression, RPAREN, Statement, ELSE,
                     //                       Statement
            { CurrentSemanticValue = new Nodes.IfNode(ValueStack[ValueStack.Depth - 5], ValueStack[ValueStack.Depth - 3], ValueStack[ValueStack.Depth - 1]); }
            break;

            case 65: // IterationStatement -> WHILE, LPAREN, Expression, RPAREN, Statement
            { CurrentSemanticValue = new Nodes.While(ValueStack[ValueStack.Depth - 3], ValueStack[ValueStack.Depth - 1]); }
            break;

            case 67: // ReturnStatement -> RETURN, SEMICOLON
            { CurrentSemanticValue = new Nodes.Empty(); }
            break;

            case 68: // ArgumentList -> Expression
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 69: // ArgumentList -> ArgumentList, COMMA, Expression
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 3].makeSibling(ValueStack[ValueStack.Depth - 1]); }
            break;

            case 70: // Expression -> QualifiedName, EQUALS, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "EQUALS", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 76: // Expression -> Expression, OP_EQ, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "OP_EQ", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 77: // Expression -> Expression, OP_NE, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "OP_NE", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 78: // Expression -> Expression, OP_GT, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "OP_GT", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 79: // Expression -> Expression, OP_LT, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "OP_LT", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 80: // Expression -> Expression, OP_LE, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "OP_LE", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 81: // Expression -> Expression, OP_GE, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "OP_GE", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 82: // Expression -> Expression, PLUSOP, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "PLUSOP", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 83: // Expression -> Expression, MINUSOP, Expression
            { CurrentSemanticValue = new Nodes.Expression(ValueStack[ValueStack.Depth - 3], "MINUSOP", ValueStack[ValueStack.Depth - 1]); }
            break;

            case 88: // Expression -> PrimaryExpression
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 89: // ArithmeticUnaryOperator -> PLUSOP
            { CurrentSemanticValue = new Nodes.Arith("PLUSOP"); }
            break;

            case 90: // ArithmeticUnaryOperator -> MINUSOP
            { CurrentSemanticValue = new Nodes.Arith("MINUSOP"); }
            break;

            case 91: // PrimaryExpression -> QualifiedName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 92: // PrimaryExpression -> NotJustName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 93: // NotJustName -> SpecialName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 94: // NotJustName -> ComplexPrimary
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 95: // ComplexPrimary -> LPAREN, Expression, RPAREN
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 3]; }
            break;

            case 96: // ComplexPrimary -> ComplexPrimaryNoParenthesis
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 97: // ComplexPrimaryNoParenthesis -> LITERAL
            { CurrentSemanticValue = new Nodes.Literal(yystringval); }
            break;

            case 98: // ComplexPrimaryNoParenthesis -> Number
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 99: // ComplexPrimaryNoParenthesis -> FieldAccess
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 100: // ComplexPrimaryNoParenthesis -> MethodCall
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 102: // MethodCall -> MethodReference, LPAREN, ArgumentList, RPAREN
            { CurrentSemanticValue = new Nodes.MethodCall(ValueStack[ValueStack.Depth - 4], ValueStack[ValueStack.Depth - 2]); }
            break;

            case 103: // MethodCall -> MethodReference, LPAREN, RPAREN
            { CurrentSemanticValue = new Nodes.MethodCall(ValueStack[ValueStack.Depth - 3]); }
            break;

            case 104: // MethodReference -> ComplexPrimaryNoParenthesis
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 105: // MethodReference -> QualifiedName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 106: // MethodReference -> SpecialName
            { CurrentSemanticValue = ValueStack[ValueStack.Depth - 1]; }
            break;

            case 107: // SpecialName -> THIS
            { CurrentSemanticValue = new Nodes.Special("THIS"); }
            break;

            case 108: // SpecialName -> NULL
            { CurrentSemanticValue = new Nodes.Special("NULL"); }
            break;

            case 109: // Identifier -> IDENTIFIER
            { CurrentSemanticValue = new Nodes.Identifier(yytext); }
            break;

            case 110: // Number -> INT_NUMBER
            { CurrentSemanticValue = new Nodes.Number(yytext); }
            break;
            }
#pragma warning restore 162, 1522
        }
 public void VisitNode(Nodes.Expression node)
 {
     Console.Write("<" + node.ClassName() + ">: ");
     Console.WriteLine(node.exType);
 }