// $ANTLR : "TreeParser.g" -> "SearchExpressionTreeParser.java"$ package net.sf.jabref.search; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import net.sf.jabref.BibtexEntry; import net.sf.jabref.export.layout.format.RemoveLatexCommands; import antlr.MismatchedTokenException; import antlr.NoViableAltException; import antlr.RecognitionException; import antlr.collections.AST; @SuppressWarnings({"unused"}) public class SearchExpressionTreeParser extends antlr.TreeParser implements SearchExpressionTreeParserTokenTypes { // Formatter used on every field before searching. Removes Latex commands that // may interfere with the search: static RemoveLatexCommands removeLatexCommands = new RemoveLatexCommands(); private static final int MATCH_EXACT = 0; private static final int MATCH_CONTAINS = 1; private static final int MATCH_DOES_NOT_CONTAIN = 2; private BibtexEntry bibtexEntry; private Object[] searchKeys; private static final int PSEUDOFIELD_TYPE = 1; public int apply(AST ast, BibtexEntry bibtexEntry) throws antlr.RecognitionException { this.bibtexEntry = bibtexEntry; // specification of fields to search is done in the search expression itself this.searchKeys = bibtexEntry.getAllFields().toArray(); return tSearchExpression(ast) ? 1 : 0; } public SearchExpressionTreeParser() { tokenNames = _tokenNames; } public final boolean tSearchExpression(AST _t) throws RecognitionException, PatternSyntaxException { boolean ret = false; AST tSearchExpression_AST_in = (_t == ASTNULL) ? null : (AST)_t; boolean a = false, b = false; try { // for error handling if (_t==null) _t=ASTNULL; switch ( _t.getType()) { case And: { AST __t87 = _t; AST tmp1_AST_in = _t; match(_t,And); _t = _t.getFirstChild(); a=tSearchExpression(_t); _t = _retTree; { if (_t==null) _t=ASTNULL; if ((((_t.getType() >= And && _t.getType() <= ExpressionSearch)))&&(a)) { b=tSearchExpression(_t); _t = _retTree; } else if (((_t.getType() >= LITERAL_and && _t.getType() <= ExpressionSearch))) { AST tmp2_AST_in = _t; if ( _t==null ) throw new MismatchedTokenException(); _t = _t.getNextSibling(); } else { throw new NoViableAltException(_t); } } _t = __t87; _t = _t.getNextSibling(); ret = a && b; break; } case Or: { AST __t89 = _t; AST tmp3_AST_in = _t; match(_t,Or); _t = _t.getFirstChild(); a=tSearchExpression(_t); _t = _retTree; { if (_t==null) _t=ASTNULL; if ((((_t.getType() >= And && _t.getType() <= ExpressionSearch)))&&(!a)) { b=tSearchExpression(_t); _t = _retTree; } else if (((_t.getType() >= LITERAL_and && _t.getType() <= ExpressionSearch))) { AST tmp4_AST_in = _t; if ( _t==null ) throw new MismatchedTokenException(); _t = _t.getNextSibling(); } else { throw new NoViableAltException(_t); } } _t = __t89; _t = _t.getNextSibling(); ret = a || b; break; } case Not: { AST __t91 = _t; AST tmp5_AST_in = _t; match(_t,Not); _t = _t.getFirstChild(); a=tSearchExpression(_t); _t = _retTree; _t = __t91; _t = _t.getNextSibling(); ret = !a; break; } case ExpressionSearch: { ret=tExpressionSearch(_t); _t = _retTree; break; } default: { throw new NoViableAltException(_t); } } } catch (RecognitionException ex) { reportError(ex); if (_t!=null) {_t = _t.getNextSibling();} } _retTree = _t; return ret; } public final boolean tExpressionSearch(AST _t) throws RecognitionException, PatternSyntaxException { boolean ret = false; AST var_f = null; AST var_v = null; int matchType = 0; try { // for error handling AST __t94 = _t; AST tmp6_AST_in = _t; match(_t,ExpressionSearch); _t = _t.getFirstChild(); var_f = _t; match(_t,RegularExpression); _t = _t.getNextSibling(); matchType=tSearchType(_t); _t = _retTree; var_v = _t; match(_t,RegularExpression); _t = _t.getNextSibling(); Pattern fieldSpec = ((RegExNode)var_f).getPattern(); Pattern valueSpec = ((RegExNode)var_v).getPattern(); boolean noSuchField = true; // this loop iterates over all regular keys, then over pseudo keys like "type" for (int i = 0; i < searchKeys.length + PSEUDOFIELD_TYPE && !ret; ++i) { String content; switch (i - searchKeys.length + 1) { case PSEUDOFIELD_TYPE: if (!fieldSpec.matcher("entrytype").matches()) continue; content = bibtexEntry.getType().getName(); break; default: // regular field if (!fieldSpec.matcher(searchKeys[i].toString()).matches()) continue; String field = bibtexEntry.getField(searchKeys[i].toString()); content = field != null ? removeLatexCommands.format(field) : null; } noSuchField = false; if (content == null) continue; // paranoia Matcher matcher = valueSpec.matcher(content); switch (matchType) { case MATCH_CONTAINS: ret = matcher.find(); break; case MATCH_EXACT: ret = matcher.matches(); break; case MATCH_DOES_NOT_CONTAIN: ret = !matcher.find(); break; } } if (noSuchField && matchType == MATCH_DOES_NOT_CONTAIN) ret = true; // special case _t = __t94; _t = _t.getNextSibling(); } catch (RecognitionException ex) { reportError(ex); if (_t!=null) {_t = _t.getNextSibling();} } _retTree = _t; return ret; } public final int tSearchType(AST _t) throws RecognitionException { int matchType = 0; AST tSearchType_AST_in = (_t == ASTNULL) ? null : (AST)_t; try { // for error handling if (_t==null) _t=ASTNULL; switch ( _t.getType()) { case LITERAL_contains: { AST tmp7_AST_in = _t; match(_t,LITERAL_contains); _t = _t.getNextSibling(); matchType = MATCH_CONTAINS; break; } case LITERAL_matches: { AST tmp8_AST_in = _t; match(_t,LITERAL_matches); _t = _t.getNextSibling(); matchType = MATCH_EXACT; break; } case EQUAL: { AST tmp9_AST_in = _t; match(_t,EQUAL); _t = _t.getNextSibling(); matchType = MATCH_CONTAINS; break; } case EEQUAL: { AST tmp10_AST_in = _t; match(_t,EEQUAL); _t = _t.getNextSibling(); matchType = MATCH_EXACT; break; } case NEQUAL: { AST tmp11_AST_in = _t; match(_t,NEQUAL); _t = _t.getNextSibling(); matchType = MATCH_DOES_NOT_CONTAIN; break; } default: { throw new NoViableAltException(_t); } } } catch (RecognitionException ex) { reportError(ex); if (_t!=null) {_t = _t.getNextSibling();} } _retTree = _t; return matchType; } public static final String[] _tokenNames = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "\"and\"", "\"or\"", "\"not\"", "\"contains\"", "\"matches\"", "white space", "'('", "')'", "'='", "'=='", "'!='", "'\\\"'", "a text literal", "a letter", "a field type", "RegularExpression", "And", "Or", "Not", "ExpressionSearch" }; }