pike.git / lib / modules / Search.pmod / Grammar.pmod / DefaultParser.pike

version» Context lines:

pike.git/lib/modules/Search.pmod/Grammar.pmod/DefaultParser.pike:1:   #pike __REAL_VERSION__    - static inherit .AbstractParser; - static inherit .Lexer; + protected inherit .AbstractParser; + protected inherit .Lexer;   import ".";      #include "debug.h"      // =========================================================================   // GRAMMAR FOR IMPLICIT AND/OR   // =========================================================================   //   // START : query   // ;
pike.git/lib/modules/Search.pmod/Grammar.pmod/DefaultParser.pike:57:   //   // expr6 : '-' expr7   // | '+' expr7   // | expr7   // ;   //   // expr7 : word   // | phrase   // ;    - static array(array(Token|string)) tokens; - static array(string) fieldstack; + protected array(array(Token|string)) tokens; + protected array(string) fieldstack;      // fields : multiset(string)   // implicit : "or"/"and"   //!   mapping(string:mixed) options;    - static array(Token|string) peek(void|int lookahead) { + protected array(Token|string) peek(void|int lookahead) {    if (lookahead >= sizeof(tokens))    lookahead = sizeof(tokens) - 1;    return tokens[lookahead];   }    - static array advance() + protected array advance()   {    array res = tokens[0];    if (sizeof(tokens) > 1)    tokens = tokens[1 .. ];    return res;   }    - static int lookingAtFieldStart(void|int offset) { + protected int lookingAtFieldStart(void|int offset) {    multiset(string) fields = options["fields"];    // SHOW(tokens);    return peek(offset)[0] == TOKEN_TEXT    && fields[ lower_case(peek(offset)[1]) ]    && peek(offset + 1)[0] == TOKEN_COLON;   }    - static int lookingAtDateStart(void|int offset) { + protected int lookingAtDateStart(void|int offset) {    // SHOW(tokens);    return    peek(offset)[0] == TOKEN_TEXT &&    lower_case(peek(offset)[1])=="date" &&    (< TOKEN_EQUAL, TOKEN_LESSEQUAL, TOKEN_GREATEREQUAL,    TOKEN_NOTEQUAL, TOKEN_LESS, TOKEN_GREATER >)[ peek(offset + 1)[0]];   }         //! - static void create(mapping(string:mixed)|void opt) { + protected void create(mapping(string:mixed)|void opt) {    options = opt || ([ "implicit" : "or" ]);    if (!options["fields"])    options["fields"] = getDefaultFields();   }      //!   ParseNode parse(string q) {    fieldstack = ({ "any" });    tokens = tokenize(q);    return parseQuery();   }    - static ParseNode parseQuery() { + protected ParseNode parseQuery() {    // TRACE;    ParseNode or = OrNode();    for (;;) {    ParseNode n = parseExpr0();    or->addChild(n);    if (peek()[0] == TOKEN_OR)    advance();    else if ((< TOKEN_END,    TOKEN_RPAREN >)[ peek()[0] ] ||    options->implicit != "or")    break;    }    if (sizeof(or->children) == 1)    return or->children[0];    return or;   }    - static ParseNode parseExpr0() { + protected ParseNode parseExpr0() {    // TRACE;    ParseNode and = AndNode();    for (;;) {    ParseNode n = parseExpr1();    and->addChild(n);    if (peek()[0] == TOKEN_AND)    advance();    else if ((< TOKEN_END,    TOKEN_RPAREN,    TOKEN_OR >)[ peek()[0] ] ||    options->implicit != "and")    break;    // implicit AND    }    if (sizeof(and->children) == 1)    return and->children[0];    return and;   }    - static ParseNode parseExpr1() { + protected ParseNode parseExpr1() {    // TRACE;    return parseExpr2();   }    - static ParseNode parseExpr2() { + protected ParseNode parseExpr2() {    // TRACE;       // field ':' expr3    if (lookingAtFieldStart())    {    // TRACE;    fieldstack = ({ peek()[1] }) + fieldstack;    advance();    advance();    ParseNode n = parseExpr3();
pike.git/lib/modules/Search.pmod/Grammar.pmod/DefaultParser.pike:188:    if (peek()[0] == TOKEN_LPAREN) {    advance();    ParseNode n = parseQuery();    if (peek()[0] == TOKEN_RPAREN)    advance();    return n;    }    return parseExpr3();   }    - static ParseNode parseExpr3() { + protected ParseNode parseExpr3() {    // TRACE;    if (lookingAtFieldStart() || lookingAtDateStart())    return 0;    ParseNode or = OrNode();    for (;;) {    ParseNode n = parseExpr4();    or->addChild(n);    if (peek()[0] == TOKEN_OR)    if (lookingAtFieldStart(1) || lookingAtDateStart(1))    break; // it was a higher level OR    else    advance();    else    break;    }    if (sizeof(or->children) == 1)    return or->children[0];    return or;   }    - static ParseNode parseExpr4() { + protected ParseNode parseExpr4() {    // TRACE;    ParseNode and = AndNode();    for (;;) {    ParseNode n = parseExpr5();    and->addChild(n);    // NOTE: No implicit and here!    if (peek()[0] == TOKEN_AND    && !(lookingAtFieldStart(1) // it was a higher level AND    || lookingAtDateStart(1)    || peek(1)[0] == TOKEN_LPAREN))    advance();    else    break;    }    if (sizeof(and->children) == 1)    return and->children[0];    return and;   }    - static ParseNode parseExpr5() { + protected ParseNode parseExpr5() {    // TRACE;    ParseNode text = TextNode();    ParseNode res;    text->field = fieldstack[0];    if (options->implicit == "or") {    res = OrNode();    } else {    res = AndNode();    }    for (;;) {
pike.git/lib/modules/Search.pmod/Grammar.pmod/DefaultParser.pike:309:    || sizeof(text->plusWords)    || sizeof(text->plusPhrases)    || sizeof(text->minusWords)    || sizeof(text->minusPhrases))    res->addChild(text);    if (sizeof(res->children) > 1) return res;    if (sizeof(res->children) == 1) return res->children[0];    return 0;   }    - static void parseExpr6(int prefix, TextNode node) { + protected void parseExpr6(int prefix, TextNode node) {    // TRACE;       if (peek()[0] == TOKEN_TEXT) {    string text = peek()[1];    advance();    string star = "86196759014593256";    string questionmark = "76196758925470133";    text=replace(text,({"*","?"}), ({star, questionmark}));    array(string) words = Unicode.split_words_and_normalize(text);    for(int i=0; i<sizeof(words); i++)    words[i]=replace(words[i], ({star, questionmark}), ({"*","?"}));    // End of abominable kludge    if (words) {    // If search phrase, remove empty globs. This might promote to    // ordinary search word that do support remining globs.    if (sizeof(words) > 1)    words = filter(words, lambda(string w) { return (w - "*" - "?") == "" ? 0 : 1; });    -  if (sizeof(words) == 1) +  if (sizeof(words) == 1) { +  // If auto-globbing has been requested we take a word not using any +  // glob characters and wrap it in "*" + word + "*". +  if (options["auto-glob"] && +  !has_value(words[0], "*") && +  !has_value(words[0], "?")) { +  words[0] = "*" + words[0] + "*"; +  } +     switch (prefix) {    case '+': node->plusWords += words; break;    case '-': node->minusWords += words; break;    default: node->words += words; break;    } -  else if (sizeof(words) > 1) { -  // No use of globs at this point so remove them +  } else if (sizeof(words) > 1) { +  // No use of globs at this point so remove them. Auto-globbing isn't +  // used in this case either.    words = map(words, lambda(string w) { return w - "*" - "?"; } );    switch (prefix) {    case '+': node->plusPhrases += ({ words }); break;    case '-': node->minusPhrases += ({ words }); break;    default: node->phrases += ({ words }); break;    }    }    }    }   }    - static ParseNode parseDate(array operator) + protected ParseNode parseDate(array operator)   {    // TRACE;    DateNode n = DateNode();    n->date = "";    n->operator = operator;   loop:    for (;;) {    switch (peek()[0]) {    case TOKEN_TEXT:    if (lookingAtFieldStart())