HEX
Server: nginx/1.24.0
System: Linux nowruzgan 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025 x86_64
User: babak (1000)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: //usr/share/opensearch-dashboards/node_modules/lucene/lib/lucene.grammar
/*
 * Lucene Query Grammar for PEG.js
 * ========================================
 *
 * This grammar supports many of the constructs contained in the Lucene Query Syntax.
 *
 * Supported features:
 * - conjunction operators (AND, OR, ||, &&, NOT, AND NOT, OR NOT)
 * - prefix operators (+, -)
 * - quoted values ("foo bar")
 * - named fields (foo:bar)
 * - range expressions (foo:[bar TO baz], foo:{bar TO baz})
 * - regex expressions (/^f?o[1-5]o/)
 * - proximity search expressions ("foo bar"~5)
 * - boost expressions (foo^5, "foo bar"^5)
 * - fuzzy search expressions (foo~, foo~0.5)
 * - parentheses grouping ( (foo OR bar) AND baz )
 * - field groups ( foo:(bar OR baz) )
 *
 * The grammar will create a parser which returns an AST for the query in the form of a tree
 * of nodes, which are dictionaries. There are three basic types of expression dictionaries:
 *
 * A node expression generally has the following structure:
 *
 * {
 *     'left' : dictionary,     // field expression or node
 *     'operator': string,      // operator value
 *     'right': dictionary,     // field expression OR node
 *     'field': string          // field name (for field group syntax) [OPTIONAL]
 *     'parenthesized': boolean // whether or not the expression was placed in parentheses
 *                              // in the input
 * }
 *
 *
 * A field expression has the following structure:
 *
 * {
 *     'field': string,         // field name
 *     'term': string,          // term value
 *     'quoted': boolean,       // whether or not the value was quoted in the input string
 *     'regex': boolean,        // whether or not the value is a regex expression
 *     'prefix': string         // prefix operator (+/-) [OPTIONAL]
 *     'boost': float           // boost value, (value > 1 must be integer) [OPTIONAL]
 *     'similarity': float      // similarity value, (value must be > 0 and < 1) [OPTIONAL]
 *     'proximity': integer     // proximity value [OPTIONAL]
 * }
 *
 *
 * A range expression has the following structure:
 *
 * {
 *     'field': string,         // field name
 *     'term_min': string,      // minimum value (left side) of range
 *     'term_max': string,      // maximum value (right side) of range
 *     'inclusive': string     // inclusive ([...]) or exclusive ({...}) or mixed ({...],[...})
 * }
 *
 * Other Notes:
 *
 * - For any field name, unnamed/default fields will have the value "<implicit>".
 * - Wildcards (fo*, f?o) and fuzzy search modifiers (foo~.8) will be part of the term value.
 * - Escaping is not supported and generally speaking, will break the parser.
 * - Conjunction operators that appear at the beginning of the query violate the logic of the
 *   syntax, and are currently "mostly" ignored. The last element will be returned.
 *
 *   For example:
 *       Query: OR
 *       Return: { "operator": "OR" }
 *
 *       Query: OR AND
 *       Return: { "operator": "AND" }
 *
 *       Query: OR AND foo
 *       Return: { "left": { "field": "<implicit>", "term": "foo" } }
 *
 *  To test the grammar, use the online parser generator at http://pegjs.majda.cz/online
 *
 */

start
  = _* node:node+
    {
        return node[0];
    }
  / _*
    {
        return {};
    }
  / EOF
    {
        return {};
    }

node
  = operator:operator_exp EOF
    {
        return {
            'operator': operator,
        };
    }
  / start:operator_exp left:group_exp operator:operator_exp* right:node*
    {
        var node = {
            'start': start,
            'left': left,
        };

        var right =
                right.length == 0
                ? null
                : right[0]['right'] == null
                    ? right[0]['left']
                    : right[0];

        if (right != null) {
            node['operator'] = operator == '' ? '<implicit>' : operator[0];
            node['right'] = right;
        }

        return node;
    }
  / operator:operator_exp right:node
    {
        return right;
    }
  / left:group_exp operator:operator_exp* right:node*
    {
        var node = {
            'left':left
        };

        var right =
                right.length == 0
                ? null
                : right[0]['right'] == null
                    ? right[0]['left']
                    : right[0];

        if (right != null) {
            node['operator'] = operator == '' ? '<implicit>' : operator[0];
            node['right'] = right;
        }

        return node;
    }

group_exp
  = field_exp:field_exp _*
    {
        return field_exp;
    }
  / paren_exp

paren_exp
  = "(" _* node:node+ ")" _*
    {
        node[0]['parenthesized'] = true;
        return node[0];
    }

field_exp



  = fieldname:fieldname? range:range_operator_exp
    {
        range['field'] =
            fieldname == null || fieldname.label == ''
                ? "<implicit>"
                : fieldname.label;
        range['fieldLocation'] =
        fieldname == null || fieldname.label == ''
            ? null
            : fieldname.location;

        return range;
    }
  / fieldname:fieldname node:paren_exp
    {
        node['field']= fieldname.label;
        node['fieldLocation'] = fieldname.location;
        return node;
    }
  / fieldname:fieldname? term:term
    {
        var fieldexp = {
            'field':
                fieldname == null || fieldname.label == ''
                    ? "<implicit>"
                    : fieldname.label,
            'fieldLocation':
                fieldname == null || fieldname.label == ''
                    ? null
                    : fieldname.location,


            };

        for(var key in term)
            fieldexp[key] = term[key];

        return fieldexp;
    }

fieldname
  = fieldname:unquoted_term [:] _*
    {
        return {
          label: fieldname.label,
          location: fieldname.location
        }

    }

term
  = op:prefix_operator_exp? term:quoted_term proximity:proximity_modifier? boost:boost_modifier? _*
      {
        var result = {
          'term': term,
          'quoted': true,
          'regex' : false,
          'termLocation': location()
        };

        if('' != proximity)
        {
            result['proximity'] = proximity;
        }
        if('' != boost)
        {
            result['boost'] = boost;
        }
        if('' != op)
        {
            result['prefix'] = op;
        }

        return result;
    }
  / op:prefix_operator_exp? term:regex_term _*
      {
        var result = {
          'term': term,
          'quoted': false,
          'regex': true,
          'termLocation': location()
        };

        return result;
    }
  / op:prefix_operator_exp? term:unquoted_term similarity:fuzzy_modifier? boost:boost_modifier? _*
    {
        var result = {
          'term': term.label,
          'quoted': false,
          'regex': false,
          'termLocation': location()
        };
        if('' != similarity)
        {
            result['similarity'] = similarity;
        }
        if('' != boost)
        {
            result['boost'] = boost;
        }
        if('' != op)
        {
            result['prefix'] = op;
        }
        return result;
    }

rterm_char
  = "\\" sequence:EscapeSequence { return '\\' + sequence; }
  / '.' / [^ \t\r\n\f\{\}()"/^~\[\]]


ranged_term
  = term:rterm_char+
    {
        return term.join('');
    }

unquoted_term
  = term:term_char+
    {
        return {
          label: term.join(''),
          location: location(),
        };
    }

term_char
  = "\\" sequence:EscapeSequence { return '\\' + sequence; }
  / '.' / [^: \t\r\n\f\{\}()"/^~\[\]]


quoted_term
  = '"' chars:DoubleStringCharacter* '"' { return chars.join(''); }

regex_term
  = '/' chars:RegexCharacter+ '/' { return chars.join('') }

DoubleStringCharacter
  = !('"' / "\\") char:. { return char; }
  / "\\" sequence:EscapeSequence { return '\\' + sequence; }

RegexCharacter
  = !('/' / "\\") char:. { return char; }
  / "\\" sequence:EscapeSequence { return '\\' + sequence; }

EscapeSequence
  = "+"
  / "-"
  / "!"
  / "("
  / ")"
  / "{"
  / "}"
  / "["
  / "]"
  / "^"
  / "\""
  / "?"
  / ":"
  / "\\"
  / "&"
  / "|"
  / "'"
  / "/"
  / "~"
  / "*"
  / " "

proximity_modifier
  = '~' proximity:int_exp
    {
        return proximity;
    }

boost_modifier
  = '^' boost:decimal_or_int_exp
    {
        return boost;
    }

fuzzy_modifier
  = '~' fuzziness:decimal_exp?
    {
        return fuzziness == '' || fuzziness == null ? 0.5 : fuzziness;
    }

decimal_or_int_exp
 = decimal_exp
 / int_exp

decimal_exp
 = '0.' val:[0-9]+
    {
        return parseFloat("0." + val.join(''));
    }

int_exp
  = val:[0-9]+
    {
        return parseInt(val.join(''));
    }

range_operator_exp
  = '[' term_min:ranged_term _* 'TO' _+ term_max:ranged_term ']'
    {
        return {
            'term_min': term_min,
            'term_max': term_max,
            'inclusive': 'both'
        };
    }
  / '{' term_min:ranged_term _* 'TO' _+ term_max:ranged_term '}'
    {
        return {
            'term_min': term_min,
            'term_max': term_max,
            'inclusive': 'none'
        };
    }
  / '[' term_min:ranged_term _* 'TO' _+ term_max:ranged_term '}'
    {
        return {
            'term_min': term_min,
            'term_max': term_max,
            'inclusive': 'left'
        };
    }
  / '{' term_min:ranged_term _* 'TO' _+ term_max:ranged_term ']'
    {
        return {
            'term_min': term_min,
            'term_max': term_max,
            'inclusive': 'right'
        };
    }

operator_exp
  = _* operator:operator _+
    {
        return operator;
    }
  / _* operator:operator EOF
    {
        return operator;
    }

operator
  = 'OR NOT'
  / 'AND NOT'
  / 'OR'
  / 'AND'
  / 'NOT'
  / '||'
  / '&&'

prefix_operator_exp
  = _* operator:prefix_operator
    {
        return operator;
    }

prefix_operator
  = '+'
  / '-'
  / '!'

_ "whitespace"
  = [ \t\r\n\f]+

EOF
  = !.