private PPNode parsePreprocessorDirective() throws FeatureNotSupportedException {
        PPNode result = null;
        int startLine = lineCount;
        inPPDirective = true;
        advance(); // over hash
        IdentifierExpression ie = parseIdentifierOrKeyword();
        String ppKind = ie.Identifier[0];
        byte id = PreprocessorID.Empty;
        if (preprocessor.containsKey(ppKind)) {
            id = preprocessor.get(ppKind);
        } else {
            ReportError("Preprocessor directive must be valid identifier, rather than \"" + ppKind + "\".");
        }
        switch (id) {
            case PreprocessorID.Define:
                // conditional-symbol pp-newline
                IdentifierExpression def = parseIdentifierOrKeyword();
                if (!ppDefs.containsKey(def.Identifier[0])) {
                    ppDefs.put(def.Identifier[0], PreprocessorID.Empty);
                }
                result = new PPDefineNode(def);
                break;
            case PreprocessorID.Undef:
                // conditional-symbol pp-newline
                IdentifierExpression undef = parseIdentifierOrKeyword();
                if (ppDefs.containsKey(undef.Identifier[0])) {
                    ppDefs.remove(undef.Identifier[0]);
                }
                result = new PPDefineNode(undef);
                break;
            case PreprocessorID.If:
                // pp-expression pp-newline conditional-section(opt)
                if (curtok.id == TokenID.LParen) {
                    advance();
                }
                int startCount = lineCount;
                ppCondition = false;
                // todo: account for true, false, ||, &&, ==, !=, !
                IdentifierExpression ifexpr = parseIdentifierOrKeyword();
                if (ppDefs.containsKey(ifexpr.Identifier[0])) {
                    ppCondition = true;
                }
                //result = new PPIfNode(ParseExpressionToNewline());
                if (curtok.id == TokenID.RParen) {
                    advance();
                }
                if (ppCondition == false) {
                    // skip this block
                    SkipToElseOrEndIf();
                }
                break;
            case PreprocessorID.Elif:
                // pp-expression pp-newline conditional-section(opt)
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Else:
                // pp-newline conditional-section(opt)
                if (ppCondition == true) {
                    // skip this block
                    SkipToElseOrEndIf();
                }
                break;
            case PreprocessorID.Endif:
                // pp-newline
                result = new PPEndIfNode();
                ppCondition = false;
                break;
            case PreprocessorID.Line:
                // line-indicator pp-newline
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Error:
                // pp-message
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Warning:
                // pp-message
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Region:
                // pp-message
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Endregion:
                // pp-message
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Pragma:
                // pp-message
                SkipToEOL(startLine);
                break;
            default:
                break;
        }
        inPPDirective = false;
        return result;
    }
private PPNode parsePreprocessorDirective() throws FeatureNotSupportedException {
        PPNode result = null;
        int startLine = lineCount;
        inPPDirective = true;
        advance();
        IdentifierExpression ie = parseIdentifierOrKeyword();
        String ppKind = ie.Identifier[0];
        byte id = PreprocessorID.Empty;
        if (preprocessor.containsKey(ppKind)) {
            id = preprocessor.get(ppKind);
        } else {
            ReportError("Preprocessor directive must be valid identifier, rather than \"" + ppKind + "\".");
        }
        switch (id) {
            case PreprocessorID.Define:
               
                IdentifierExpression def = parseIdentifierOrKeyword();
                if (!ppDefs.containsKey(def.Identifier[0])) {
                    ppDefs.put(def.Identifier[0], PreprocessorID.Empty);
                }
                result = new PPDefineNode(def);
                break;
            case PreprocessorID.Undef:
               
                IdentifierExpression undef = parseIdentifierOrKeyword();
                if (ppDefs.containsKey(undef.Identifier[0])) {
                    ppDefs.remove(undef.Identifier[0]);
                }
                result = new PPDefineNode(undef);
                break;
            case PreprocessorID.If:
               
                if (curtok.id == TokenID.LParen) {
                    advance();
                }
                int startCount = lineCount;
                ppCondition = false;
               
                IdentifierExpression ifexpr = parseIdentifierOrKeyword();
                if (ppDefs.containsKey(ifexpr.Identifier[0])) {
                    ppCondition = true;
                }
               
                if (curtok.id == TokenID.RParen) {
                    advance();
                }
                if (ppCondition == false) {
                   
                    SkipToElseOrEndIf();
                }
                break;
            case PreprocessorID.Elif:
               
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Else:
               
                if (ppCondition == true) {
                   
                    SkipToElseOrEndIf();
                }
                break;
            case PreprocessorID.Endif:
               
                result = new PPEndIfNode();
                ppCondition = false;
                break;
            case PreprocessorID.Line:
               
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Error:
               
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Warning:
               
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Region:
               
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Endregion:
               
                SkipToEOL(startLine);
                break;
            case PreprocessorID.Pragma:
               
                SkipToEOL(startLine);
                break;
            default:
                break;
        }
        inPPDirective = false;
        return result;
    }
private ppnode parsepreprocessordirective() throws featurenotsupportedexception { ppnode result = null; int startline = linecount; inppdirective = true; advance(); identifierexpression ie = parseidentifierorkeyword(); string ppkind = ie.identifier[0]; byte id = preprocessorid.empty; if (preprocessor.containskey(ppkind)) { id = preprocessor.get(ppkind); } else { reporterror("preprocessor directive must be valid identifier, rather than \"" + ppkind + "\"."); } switch (id) { case preprocessorid.define: identifierexpression def = parseidentifierorkeyword(); if (!ppdefs.containskey(def.identifier[0])) { ppdefs.put(def.identifier[0], preprocessorid.empty); } result = new ppdefinenode(def); break; case preprocessorid.undef: identifierexpression undef = parseidentifierorkeyword(); if (ppdefs.containskey(undef.identifier[0])) { ppdefs.remove(undef.identifier[0]); } result = new ppdefinenode(undef); break; case preprocessorid.if: if (curtok.id == tokenid.lparen) { advance(); } int startcount = linecount; ppcondition = false; identifierexpression ifexpr = parseidentifierorkeyword(); if (ppdefs.containskey(ifexpr.identifier[0])) { ppcondition = true; } if (curtok.id == tokenid.rparen) { advance(); } if (ppcondition == false) { skiptoelseorendif(); } break; case preprocessorid.elif: skiptoeol(startline); break; case preprocessorid.else: if (ppcondition == true) { skiptoelseorendif(); } break; case preprocessorid.endif: result = new ppendifnode(); ppcondition = false; break; case preprocessorid.line: skiptoeol(startline); break; case preprocessorid.error: skiptoeol(startline); break; case preprocessorid.warning: skiptoeol(startline); break; case preprocessorid.region: skiptoeol(startline); break; case preprocessorid.endregion: skiptoeol(startline); break; case preprocessorid.pragma: skiptoeol(startline); break; default: break; } inppdirective = false; return result; }