123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- lunr.QueryParser = function (str, query) {
- this.lexer = new lunr.QueryLexer (str)
- this.query = query
- this.currentClause = {}
- this.lexemeIdx = 0
- }
- lunr.QueryParser.prototype.parse = function () {
- this.lexer.run()
- this.lexemes = this.lexer.lexemes
- var state = lunr.QueryParser.parseClause
- while (state) {
- state = state(this)
- }
- return this.query
- }
- lunr.QueryParser.prototype.peekLexeme = function () {
- return this.lexemes[this.lexemeIdx]
- }
- lunr.QueryParser.prototype.consumeLexeme = function () {
- var lexeme = this.peekLexeme()
- this.lexemeIdx += 1
- return lexeme
- }
- lunr.QueryParser.prototype.nextClause = function () {
- var completedClause = this.currentClause
- this.query.clause(completedClause)
- this.currentClause = {}
- }
- lunr.QueryParser.parseClause = function (parser) {
- var lexeme = parser.peekLexeme()
- if (lexeme == undefined) {
- return
- }
- switch (lexeme.type) {
- case lunr.QueryLexer.PRESENCE:
- return lunr.QueryParser.parsePresence
- case lunr.QueryLexer.FIELD:
- return lunr.QueryParser.parseField
- case lunr.QueryLexer.TERM:
- return lunr.QueryParser.parseTerm
- default:
- var errorMessage = "expected either a field or a term, found " + lexeme.type
- if (lexeme.str.length >= 1) {
- errorMessage += " with value '" + lexeme.str + "'"
- }
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- }
- lunr.QueryParser.parsePresence = function (parser) {
- var lexeme = parser.consumeLexeme()
- if (lexeme == undefined) {
- return
- }
- switch (lexeme.str) {
- case "-":
- parser.currentClause.presence = lunr.Query.presence.PROHIBITED
- break
- case "+":
- parser.currentClause.presence = lunr.Query.presence.REQUIRED
- break
- default:
- var errorMessage = "unrecognised presence operator'" + lexeme.str + "'"
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- var nextLexeme = parser.peekLexeme()
- if (nextLexeme == undefined) {
- var errorMessage = "expecting term or field, found nothing"
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- switch (nextLexeme.type) {
- case lunr.QueryLexer.FIELD:
- return lunr.QueryParser.parseField
- case lunr.QueryLexer.TERM:
- return lunr.QueryParser.parseTerm
- default:
- var errorMessage = "expecting term or field, found '" + nextLexeme.type + "'"
- throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
- }
- }
- lunr.QueryParser.parseField = function (parser) {
- var lexeme = parser.consumeLexeme()
- if (lexeme == undefined) {
- return
- }
- if (parser.query.allFields.indexOf(lexeme.str) == -1) {
- var possibleFields = parser.query.allFields.map(function (f) { return "'" + f + "'" }).join(', '),
- errorMessage = "unrecognised field '" + lexeme.str + "', possible fields: " + possibleFields
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- parser.currentClause.fields = [lexeme.str]
- var nextLexeme = parser.peekLexeme()
- if (nextLexeme == undefined) {
- var errorMessage = "expecting term, found nothing"
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- switch (nextLexeme.type) {
- case lunr.QueryLexer.TERM:
- return lunr.QueryParser.parseTerm
- default:
- var errorMessage = "expecting term, found '" + nextLexeme.type + "'"
- throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
- }
- }
- lunr.QueryParser.parseTerm = function (parser) {
- var lexeme = parser.consumeLexeme()
- if (lexeme == undefined) {
- return
- }
- parser.currentClause.term = lexeme.str.toLowerCase()
- if (lexeme.str.indexOf("*") != -1) {
- parser.currentClause.usePipeline = false
- }
- var nextLexeme = parser.peekLexeme()
- if (nextLexeme == undefined) {
- parser.nextClause()
- return
- }
- switch (nextLexeme.type) {
- case lunr.QueryLexer.TERM:
- parser.nextClause()
- return lunr.QueryParser.parseTerm
- case lunr.QueryLexer.FIELD:
- parser.nextClause()
- return lunr.QueryParser.parseField
- case lunr.QueryLexer.EDIT_DISTANCE:
- return lunr.QueryParser.parseEditDistance
- case lunr.QueryLexer.BOOST:
- return lunr.QueryParser.parseBoost
- case lunr.QueryLexer.PRESENCE:
- parser.nextClause()
- return lunr.QueryParser.parsePresence
- default:
- var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'"
- throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
- }
- }
- lunr.QueryParser.parseEditDistance = function (parser) {
- var lexeme = parser.consumeLexeme()
- if (lexeme == undefined) {
- return
- }
- var editDistance = parseInt(lexeme.str, 10)
- if (isNaN(editDistance)) {
- var errorMessage = "edit distance must be numeric"
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- parser.currentClause.editDistance = editDistance
- var nextLexeme = parser.peekLexeme()
- if (nextLexeme == undefined) {
- parser.nextClause()
- return
- }
- switch (nextLexeme.type) {
- case lunr.QueryLexer.TERM:
- parser.nextClause()
- return lunr.QueryParser.parseTerm
- case lunr.QueryLexer.FIELD:
- parser.nextClause()
- return lunr.QueryParser.parseField
- case lunr.QueryLexer.EDIT_DISTANCE:
- return lunr.QueryParser.parseEditDistance
- case lunr.QueryLexer.BOOST:
- return lunr.QueryParser.parseBoost
- case lunr.QueryLexer.PRESENCE:
- parser.nextClause()
- return lunr.QueryParser.parsePresence
- default:
- var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'"
- throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
- }
- }
- lunr.QueryParser.parseBoost = function (parser) {
- var lexeme = parser.consumeLexeme()
- if (lexeme == undefined) {
- return
- }
- var boost = parseInt(lexeme.str, 10)
- if (isNaN(boost)) {
- var errorMessage = "boost must be numeric"
- throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
- }
- parser.currentClause.boost = boost
- var nextLexeme = parser.peekLexeme()
- if (nextLexeme == undefined) {
- parser.nextClause()
- return
- }
- switch (nextLexeme.type) {
- case lunr.QueryLexer.TERM:
- parser.nextClause()
- return lunr.QueryParser.parseTerm
- case lunr.QueryLexer.FIELD:
- parser.nextClause()
- return lunr.QueryParser.parseField
- case lunr.QueryLexer.EDIT_DISTANCE:
- return lunr.QueryParser.parseEditDistance
- case lunr.QueryLexer.BOOST:
- return lunr.QueryParser.parseBoost
- case lunr.QueryLexer.PRESENCE:
- parser.nextClause()
- return lunr.QueryParser.parsePresence
- default:
- var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'"
- throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
- }
- }
|