/*
 * Copyright (C) 2016 Reece H. Dunn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.reecedunn.intellij.plugin.xquery.parser;

import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import uk.co.reecedunn.intellij.plugin.xquery.XQueryBundle;
import uk.co.reecedunn.intellij.plugin.xquery.lexer.XQueryTokenType;

public class XQueryParser implements PsiParser {
    @NotNull
    @Override
    public ASTNode parse(@NotNull IElementType root, @NotNull PsiBuilder builder) {
        final PsiBuilder.Marker rootMarker = builder.mark();
        while (builder.getTokenType() != null) {
            if (!skipWhiteSpaceAndCommentTokens(builder) &&
                !parseNumericLiteral(builder)) {
                builder.advanceLexer();
            }
        }
        rootMarker.done(root);
        return builder.getTreeBuilt();
    }

    private boolean skipWhiteSpaceAndCommentTokens(@NotNull PsiBuilder builder) {
        boolean skipped = false;
        while (true) {
            if (builder.getTokenType() == XQueryTokenType.WHITE_SPACE ||
                builder.getTokenType() == XQueryTokenType.COMMENT) {
                skipped = true;
                builder.advanceLexer();
            } else if (builder.getTokenType() == XQueryTokenType.PARTIAL_COMMENT) {
                skipped = true;
                builder.advanceLexer();
                builder.error(XQueryBundle.message("parser.error.incomplete-comment"));
            } else if (builder.getTokenType() == XQueryTokenType.COMMENT_END_TAG) {
                skipped = true;
                builder.error(XQueryBundle.message("parser.error.end-of-comment-without-start"));
                builder.advanceLexer();
            } else {
                return skipped;
            }
        }
    }

    private boolean parseNumericLiteral(@NotNull PsiBuilder builder) {
        if (builder.getTokenType() == XQueryTokenType.INTEGER_LITERAL) {
            builder.advanceLexer();
            return true;
        } else if (builder.getTokenType() == XQueryTokenType.DECIMAL_LITERAL) {
            builder.advanceLexer();
            if (builder.getTokenType() == XQueryTokenType.PARTIAL_DOUBLE_LITERAL_EXPONENT) {
                builder.error(XQueryBundle.message("parser.error.incomplete-double-exponent"));
                builder.advanceLexer();
            }
            return true;
        } else if (builder.getTokenType() == XQueryTokenType.DOUBLE_LITERAL) {
            builder.advanceLexer();
            return true;
        }
        return false;
    }
}

@@ -1254,17 +1254,16 @@
     if (
-!
 skipWhit
@@ -1297,11 +1297,19 @@
 der)
- &&
+) continue;
 %0A   
@@ -1321,13 +1321,12 @@
     
-    !
+if (
 pars
@@ -1351,22 +1351,26 @@
 ilder)) 
-%7B%0A    
+continue;%0A
         
@@ -1393,38 +1393,24 @@
 nceLexer();%0A
-            %7D%0A
         %7D%0A  
@@ -2550,32 +2550,104 @@
 .INTEGER_LITERAL
+ %7C%7C%0A            builder.getTokenType() == XQueryTokenType.DOUBLE_LITERAL
 ) %7B%0A            
@@ -3083,148 +3083,8 @@
 ue;%0A
-        %7D else if (builder.getTokenType() == XQueryTokenType.DOUBLE_LITERAL) %7B%0A            builder.advanceLexer();%0A            return true;%0A
     

Simplify the parser logic.