boolean (PsiBuilder builder) { PsiBuilder.Marker expr = builder.mark(); final PsiBuilder.Marker mark = builder.mark(); if (XPathTokenTypes.AXIS.contains(builder.getTokenType())) { builder.advanceLexer(); mark.done(XPathElementTypes.AXIS_SPECIFIER); checkMatches(builder, XPathTokenTypes.COLCOL, XPathBundle.message("parsing.error.double.colon.expected")); if (!parseNodeTest(builder)) { builder.error(XPathBundle.message("parsing.error.node.test.expected")); } } else if (builder.getTokenType() == XPathTokenTypes.AT) { builder.advanceLexer(); mark.done(XPathElementTypes.AXIS_SPECIFIER); if (!parseNodeTest(builder)) { builder.error(XPathBundle.message("parsing.error.node.test.expected")); } } else if (builder.getTokenType() == XPathTokenTypes.DOTDOT) { mark.drop(); builder.advanceLexer(); } else { mark.done(XPathElementTypes.AXIS_SPECIFIER); if (!parseNodeTest(builder)) { mark.rollbackTo(); expr.drop(); return false; } } while (XPathTokenTypes.LBRACKET == builder.getTokenType()) { parsePredicate(builder); expr.done(XPathElementTypes.FILTER_EXPRESSION); expr = expr.precede(); } expr.drop(); return true; }