From 78467c0836b981393e8bddb7a8b0af00c5b679c5 Mon Sep 17 00:00:00 2001 From: Marty Schoch Date: Thu, 23 Oct 2014 15:56:59 -0400 Subject: [PATCH] refactored yacc parsing code to be threadsafe, removed mutex --- genparser.sh | 6 +- query_boolean.go | 22 ++ query_string.nex | 4 +- query_string.nn.go | 662 +++++++++++++++++++------------------- query_string.y | 93 +++--- y.go => query_string.y.go | 150 +++++---- query_string_parser.go | 79 +++-- 7 files changed, 529 insertions(+), 487 deletions(-) rename y.go => query_string.y.go (83%) diff --git a/genparser.sh b/genparser.sh index 5ed5666a..7b4bd80f 100755 --- a/genparser.sh +++ b/genparser.sh @@ -3,10 +3,10 @@ echo Running nex... nex query_string.nex echo Running goyacc... -go tool yacc query_string.y +go tool yacc -o query_string.y.go query_string.y # remove first line which pollutes godocs -tail -n +2 y.go > y.go.new -mv y.go.new y.go +tail -n +2 query_string.y.go > query_string.y.go.new +mv query_string.y.go.new query_string.y.go # change public Lexer to private lexer sed -i '' -e 's/Lexer/lexer/g' query_string.nn.go sed -i '' -e 's/Newlexer/newLexer/g' query_string.nn.go diff --git a/query_boolean.go b/query_boolean.go index c5939921..3b61c962 100644 --- a/query_boolean.go +++ b/query_boolean.go @@ -63,6 +63,28 @@ func NewBooleanQueryMinShould(must []Query, should []Query, mustNot []Query, min return &rv } +func (q *booleanQuery) AddMust(m Query) { + if q.Must == nil { + q.Must = NewConjunctionQuery([]Query{}) + } + q.Must.(*conjunctionQuery).AddQuery(m) +} + +func (q *booleanQuery) AddShould(m Query) { + if q.Should == nil { + q.Should = NewDisjunctionQuery([]Query{}) + } + q.Should.(*disjunctionQuery).AddQuery(m) + q.Should.(*disjunctionQuery).SetMin(1) +} + +func (q *booleanQuery) AddMustNot(m Query) { + if q.MustNot == nil { + q.MustNot = NewDisjunctionQuery([]Query{}) + } + q.MustNot.(*disjunctionQuery).AddQuery(m) +} + func (q *booleanQuery) Boost() float64 { return q.BoostVal } diff --git a/query_string.nex b/query_string.nex index 66f99dc4..70d2679c 100644 --- a/query_string.nex +++ b/query_string.nex @@ -15,8 +15,7 @@ /-?([0-9]|[1-9][0-9]*)(\.[0-9][0-9]*)?/ { lval.s = yylex.Text() - lval.f,_ = strconv.ParseFloat(yylex.Text(), 64); - logDebugTokens("NUMBER - %f", lval.f); + logDebugTokens("NUMBER - %s", lval.s); return tNUMBER } /[ \t\n]+/ { logDebugTokens("WHITESPACE (count=%d)", len(yylex.Text())) /* eat up whitespace */ } @@ -29,7 +28,6 @@ package bleve import("log") -import("strconv") func logDebugTokens(format string, v ...interface{}) { if debugLexer { diff --git a/query_string.nn.go b/query_string.nn.go index 0d1d2ebc..6d318f5c 100644 --- a/query_string.nn.go +++ b/query_string.nn.go @@ -3,9 +3,6 @@ package bleve import ( "log" ) -import ( - "strconv" -) import ("bufio";"io";"strings") type dfa struct { acc []bool @@ -23,17 +20,17 @@ a = make([]family, 1) { var acc [18]bool var fun [18]func(rune) int -fun[13] = func(r rune) int { +fun[6] = func(r rune) int { switch(r) { - case 47: return 2 case 116: return 2 - case 102: return 2 - case 98: return 2 - case 34: return 3 - case 114: return 2 - case 117: return 2 case 110: return 2 - case 92: return 4 + case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 2 + case 34: return 4 + case 102: return 2 + case 114: return 2 default: switch { case 48 <= r && r <= 57: return 2 @@ -44,17 +41,39 @@ fun[13] = func(r rune) int { } panic("unreachable") } -fun[7] = func(r rune) int { +acc[11] = true +fun[11] = func(r rune) int { switch(r) { - case 117: return 2 - case 110: return 2 - case 92: return 4 - case 47: return 2 - case 116: return 2 - case 102: return 2 + case 92: return 3 case 98: return 2 - case 34: return 3 + case 34: return 4 + case 102: return 2 case 114: return 2 + case 116: return 2 + case 110: return 2 + case 117: return 2 + case 47: return 2 + default: + switch { + case 48 <= r && r <= 57: return 2 + case 65 <= r && r <= 70: return 2 + case 97 <= r && r <= 102: return 2 + default: return 2 + } + } + panic("unreachable") +} +fun[9] = func(r rune) int { + switch(r) { + case 116: return 5 + case 110: return 6 + case 117: return 7 + case 47: return 8 + case 92: return 9 + case 98: return 10 + case 34: return 11 + case 102: return 12 + case 114: return 13 default: switch { case 48 <= r && r <= 57: return 2 @@ -68,14 +87,14 @@ fun[7] = func(r rune) int { fun[16] = func(r rune) int { switch(r) { case 47: return 2 - case 116: return 2 - case 102: return 17 + case 92: return 3 case 98: return 17 - case 34: return 3 + case 34: return 4 + case 102: return 17 case 114: return 2 - case 117: return 2 + case 116: return 2 case 110: return 2 - case 92: return 4 + case 117: return 2 default: switch { case 48 <= r && r <= 57: return 17 @@ -86,39 +105,38 @@ fun[16] = func(r rune) int { } panic("unreachable") } -acc[3] = true +fun[17] = func(r rune) int { + switch(r) { + case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 2 + case 34: return 4 + case 102: return 2 + case 114: return 2 + case 116: return 2 + case 110: return 2 + default: + switch { + case 48 <= r && r <= 57: return 2 + case 65 <= r && r <= 70: return 2 + case 97 <= r && r <= 102: return 2 + default: return 2 + } + } + panic("unreachable") +} fun[3] = func(r rune) int { - switch(r) { - case 110: return -1 - case 92: return -1 - case 47: return -1 - case 116: return -1 - case 102: return -1 - case 98: return -1 - case 34: return -1 - case 114: return -1 - case 117: return -1 - default: - switch { - case 48 <= r && r <= 57: return -1 - case 65 <= r && r <= 70: return -1 - case 97 <= r && r <= 102: return -1 - default: return -1 - } - } - panic("unreachable") -} -fun[4] = func(r rune) int { switch(r) { case 116: return 5 - case 102: return 6 - case 98: return 7 - case 34: return 8 - case 114: return 9 - case 117: return 10 - case 110: return 11 - case 92: return 12 - case 47: return 13 + case 110: return 6 + case 117: return 7 + case 47: return 8 + case 92: return 9 + case 98: return 10 + case 34: return 11 + case 102: return 12 + case 114: return 13 default: switch { case 48 <= r && r <= 57: return 2 @@ -129,59 +147,17 @@ fun[4] = func(r rune) int { } panic("unreachable") } -fun[11] = func(r rune) int { +fun[13] = func(r rune) int { switch(r) { - case 110: return 2 - case 92: return 4 - case 47: return 2 - case 116: return 2 - case 102: return 2 case 98: return 2 - case 34: return 3 - case 114: return 2 - case 117: return 2 - default: - switch { - case 48 <= r && r <= 57: return 2 - case 65 <= r && r <= 70: return 2 - case 97 <= r && r <= 102: return 2 - default: return 2 - } - } - panic("unreachable") -} -fun[12] = func(r rune) int { - switch(r) { - case 47: return 13 - case 116: return 5 - case 102: return 6 - case 98: return 7 - case 34: return 8 - case 114: return 9 - case 117: return 10 - case 110: return 11 - case 92: return 12 - default: - switch { - case 48 <= r && r <= 57: return 2 - case 65 <= r && r <= 70: return 2 - case 97 <= r && r <= 102: return 2 - default: return 2 - } - } - panic("unreachable") -} -fun[9] = func(r rune) int { - switch(r) { - case 47: return 2 - case 116: return 2 + case 34: return 4 case 102: return 2 - case 98: return 2 - case 34: return 3 case 114: return 2 - case 117: return 2 + case 116: return 2 case 110: return 2 - case 92: return 4 + case 117: return 2 + case 47: return 2 + case 92: return 3 default: switch { case 48 <= r && r <= 57: return 2 @@ -194,15 +170,15 @@ fun[9] = func(r rune) int { } fun[15] = func(r rune) int { switch(r) { - case 110: return 2 - case 92: return 4 - case 47: return 2 - case 116: return 2 + case 34: return 4 case 102: return 16 - case 98: return 16 - case 34: return 3 case 114: return 2 + case 116: return 2 + case 110: return 2 case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 16 default: switch { case 48 <= r && r <= 57: return 16 @@ -213,17 +189,60 @@ fun[15] = func(r rune) int { } panic("unreachable") } -fun[2] = func(r rune) int { +fun[0] = func(r rune) int { + switch(r) { + case 117: return -1 + case 47: return -1 + case 92: return -1 + case 98: return -1 + case 34: return 1 + case 102: return -1 + case 114: return -1 + case 116: return -1 + case 110: return -1 + default: + switch { + case 48 <= r && r <= 57: return -1 + case 65 <= r && r <= 70: return -1 + case 97 <= r && r <= 102: return -1 + default: return -1 + } + } + panic("unreachable") +} +acc[4] = true +fun[4] = func(r rune) int { + switch(r) { + case 117: return -1 + case 47: return -1 + case 92: return -1 + case 98: return -1 + case 34: return -1 + case 102: return -1 + case 114: return -1 + case 116: return -1 + case 110: return -1 + default: + switch { + case 48 <= r && r <= 57: return -1 + case 65 <= r && r <= 70: return -1 + case 97 <= r && r <= 102: return -1 + default: return -1 + } + } + panic("unreachable") +} +fun[10] = func(r rune) int { switch(r) { - case 47: return 2 - case 116: return 2 - case 102: return 2 case 98: return 2 - case 34: return 3 + case 34: return 4 + case 102: return 2 case 114: return 2 - case 117: return 2 + case 116: return 2 case 110: return 2 - case 92: return 4 + case 117: return 2 + case 47: return 2 + case 92: return 3 default: switch { case 48 <= r && r <= 57: return 2 @@ -234,60 +253,17 @@ fun[2] = func(r rune) int { } panic("unreachable") } -fun[17] = func(r rune) int { - switch(r) { - case 47: return 2 - case 116: return 2 - case 102: return 2 - case 98: return 2 - case 34: return 3 - case 114: return 2 - case 117: return 2 - case 110: return 2 - case 92: return 4 - default: - switch { - case 48 <= r && r <= 57: return 2 - case 65 <= r && r <= 70: return 2 - case 97 <= r && r <= 102: return 2 - default: return 2 - } - } - panic("unreachable") -} -fun[6] = func(r rune) int { - switch(r) { - case 110: return 2 - case 92: return 4 - case 47: return 2 - case 116: return 2 - case 102: return 2 - case 98: return 2 - case 34: return 3 - case 114: return 2 - case 117: return 2 - default: - switch { - case 48 <= r && r <= 57: return 2 - case 65 <= r && r <= 70: return 2 - case 97 <= r && r <= 102: return 2 - default: return 2 - } - } - panic("unreachable") -} -acc[8] = true fun[8] = func(r rune) int { switch(r) { - case 116: return 2 - case 102: return 2 - case 98: return 2 - case 34: return 3 - case 114: return 2 - case 117: return 2 - case 110: return 2 - case 92: return 4 case 47: return 2 + case 92: return 3 + case 98: return 2 + case 34: return 4 + case 102: return 2 + case 114: return 2 + case 116: return 2 + case 110: return 2 + case 117: return 2 default: switch { case 48 <= r && r <= 57: return 2 @@ -300,15 +276,15 @@ fun[8] = func(r rune) int { } fun[14] = func(r rune) int { switch(r) { - case 47: return 2 - case 116: return 2 - case 102: return 15 - case 98: return 15 - case 34: return 3 - case 114: return 2 - case 117: return 2 case 110: return 2 - case 92: return 4 + case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 15 + case 34: return 4 + case 102: return 15 + case 114: return 2 + case 116: return 2 default: switch { case 48 <= r && r <= 57: return 15 @@ -319,38 +295,17 @@ fun[14] = func(r rune) int { } panic("unreachable") } -fun[10] = func(r rune) int { +fun[2] = func(r rune) int { switch(r) { - case 116: return 2 - case 102: return 14 - case 98: return 14 - case 34: return 3 case 114: return 2 - case 117: return 2 + case 116: return 2 case 110: return 2 - case 92: return 4 + case 117: return 2 case 47: return 2 - default: - switch { - case 48 <= r && r <= 57: return 14 - case 65 <= r && r <= 70: return 14 - case 97 <= r && r <= 102: return 14 - default: return 2 - } - } - panic("unreachable") -} -fun[1] = func(r rune) int { - switch(r) { - case 102: return 2 + case 92: return 3 case 98: return 2 - case 34: return 3 - case 114: return 2 - case 117: return 2 - case 110: return 2 - case 92: return 4 - case 47: return 2 - case 116: return 2 + case 34: return 4 + case 102: return 2 default: switch { case 48 <= r && r <= 57: return 2 @@ -361,38 +316,80 @@ fun[1] = func(r rune) int { } panic("unreachable") } -fun[0] = func(r rune) int { +fun[1] = func(r rune) int { switch(r) { - case 92: return -1 - case 47: return -1 - case 116: return -1 - case 102: return -1 - case 98: return -1 - case 34: return 1 - case 114: return -1 - case 117: return -1 - case 110: return -1 + case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 2 + case 34: return 4 + case 102: return 2 + case 114: return 2 + case 116: return 2 + case 110: return 2 default: switch { - case 48 <= r && r <= 57: return -1 - case 65 <= r && r <= 70: return -1 - case 97 <= r && r <= 102: return -1 - default: return -1 + case 48 <= r && r <= 57: return 2 + case 65 <= r && r <= 70: return 2 + case 97 <= r && r <= 102: return 2 + default: return 2 + } + } + panic("unreachable") +} +fun[7] = func(r rune) int { + switch(r) { + case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 14 + case 34: return 4 + case 102: return 14 + case 114: return 2 + case 116: return 2 + case 110: return 2 + default: + switch { + case 48 <= r && r <= 57: return 14 + case 65 <= r && r <= 70: return 14 + case 97 <= r && r <= 102: return 14 + default: return 2 } } panic("unreachable") } fun[5] = func(r rune) int { switch(r) { - case 116: return 2 - case 102: return 2 - case 98: return 2 - case 34: return 3 - case 114: return 2 case 117: return 2 - case 110: return 2 - case 92: return 4 case 47: return 2 + case 92: return 3 + case 98: return 2 + case 34: return 4 + case 102: return 2 + case 114: return 2 + case 116: return 2 + case 110: return 2 + default: + switch { + case 48 <= r && r <= 57: return 2 + case 65 <= r && r <= 70: return 2 + case 97 <= r && r <= 102: return 2 + default: return 2 + } + } + panic("unreachable") +} +fun[12] = func(r rune) int { + switch(r) { + case 116: return 2 + case 110: return 2 + case 117: return 2 + case 47: return 2 + case 92: return 3 + case 98: return 2 + case 34: return 4 + case 102: return 2 + case 114: return 2 default: switch { case 48 <= r && r <= 57: return 2 @@ -410,9 +407,10 @@ a0[0].id = 0 { var acc [2]bool var fun [2]func(rune) int -fun[0] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { - case 43: return 1 + case 43: return -1 default: switch { default: return -1 @@ -420,10 +418,9 @@ fun[0] = func(r rune) int { } panic("unreachable") } -acc[1] = true -fun[1] = func(r rune) int { +fun[0] = func(r rune) int { switch(r) { - case 43: return -1 + case 43: return 1 default: switch { default: return -1 @@ -466,10 +463,9 @@ a0[2].id = 2 { var acc [2]bool var fun [2]func(rune) int -acc[1] = true -fun[1] = func(r rune) int { +fun[0] = func(r rune) int { switch(r) { - case 58: return -1 + case 58: return 1 default: switch { default: return -1 @@ -477,9 +473,10 @@ fun[1] = func(r rune) int { } panic("unreachable") } -fun[0] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { - case 58: return 1 + case 58: return -1 default: switch { default: return -1 @@ -522,9 +519,10 @@ a0[4].id = 4 { var acc [2]bool var fun [2]func(rune) int -fun[0] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { - case 40: return 1 + case 40: return -1 default: switch { default: return -1 @@ -532,10 +530,9 @@ fun[0] = func(r rune) int { } panic("unreachable") } -acc[1] = true -fun[1] = func(r rune) int { +fun[0] = func(r rune) int { switch(r) { - case 40: return -1 + case 40: return 1 default: switch { default: return -1 @@ -606,10 +603,9 @@ a0[7].id = 7 { var acc [2]bool var fun [2]func(rune) int -acc[1] = true -fun[1] = func(r rune) int { +fun[0] = func(r rune) int { switch(r) { - case 60: return -1 + case 60: return 1 default: switch { default: return -1 @@ -617,9 +613,10 @@ fun[1] = func(r rune) int { } panic("unreachable") } -fun[0] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { - case 60: return 1 + case 60: return -1 default: switch { default: return -1 @@ -634,9 +631,10 @@ a0[8].id = 8 { var acc [2]bool var fun [2]func(rune) int -fun[0] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { - case 61: return 1 + case 61: return -1 default: switch { default: return -1 @@ -644,10 +642,9 @@ fun[0] = func(r rune) int { } panic("unreachable") } -acc[1] = true -fun[1] = func(r rune) int { +fun[0] = func(r rune) int { switch(r) { - case 61: return -1 + case 61: return 1 default: switch { default: return -1 @@ -662,11 +659,25 @@ a0[9].id = 9 { var acc [8]bool var fun [8]func(rune) int -acc[7] = true -fun[7] = func(r rune) int { +acc[5] = true +fun[5] = func(r rune) int { switch(r) { - case 46: return -1 case 45: return -1 + case 46: return 4 + default: + switch { + case 48 <= r && r <= 48: return 5 + case 49 <= r && r <= 57: return 5 + default: return -1 + } + } + panic("unreachable") +} +acc[6] = true +fun[6] = func(r rune) int { + switch(r) { + case 45: return -1 + case 46: return -1 default: switch { case 48 <= r && r <= 48: return 7 @@ -690,6 +701,19 @@ fun[3] = func(r rune) int { } panic("unreachable") } +fun[4] = func(r rune) int { + switch(r) { + case 45: return -1 + case 46: return -1 + default: + switch { + case 48 <= r && r <= 48: return 6 + case 49 <= r && r <= 57: return 6 + default: return -1 + } + } + panic("unreachable") +} fun[0] = func(r rune) int { switch(r) { case 45: return 1 @@ -703,14 +727,28 @@ fun[0] = func(r rune) int { } panic("unreachable") } -fun[4] = func(r rune) int { +acc[7] = true +fun[7] = func(r rune) int { switch(r) { case 45: return -1 case 46: return -1 default: switch { - case 48 <= r && r <= 48: return 6 - case 49 <= r && r <= 57: return 6 + case 48 <= r && r <= 48: return 7 + case 49 <= r && r <= 57: return 7 + default: return -1 + } + } + panic("unreachable") +} +fun[1] = func(r rune) int { + switch(r) { + case 45: return -1 + case 46: return -1 + default: + switch { + case 48 <= r && r <= 48: return 2 + case 49 <= r && r <= 57: return 3 default: return -1 } } @@ -730,47 +768,6 @@ fun[2] = func(r rune) int { } panic("unreachable") } -acc[6] = true -fun[6] = func(r rune) int { - switch(r) { - case 46: return -1 - case 45: return -1 - default: - switch { - case 48 <= r && r <= 48: return 7 - case 49 <= r && r <= 57: return 7 - default: return -1 - } - } - panic("unreachable") -} -fun[1] = func(r rune) int { - switch(r) { - case 46: return -1 - case 45: return -1 - default: - switch { - case 48 <= r && r <= 48: return 2 - case 49 <= r && r <= 57: return 3 - default: return -1 - } - } - panic("unreachable") -} -acc[5] = true -fun[5] = func(r rune) int { - switch(r) { - case 45: return -1 - case 46: return 4 - default: - switch { - case 48 <= r && r <= 48: return 5 - case 49 <= r && r <= 57: return 5 - default: return -1 - } - } - panic("unreachable") -} a0[10].acc = acc[:] a0[10].f = fun[:] a0[10].id = 10 @@ -778,12 +775,11 @@ a0[10].id = 10 { var acc [2]bool var fun [2]func(rune) int -acc[1] = true -fun[1] = func(r rune) int { +fun[0] = func(r rune) int { switch(r) { + case 10: return 1 case 32: return 1 case 9: return 1 - case 10: return 1 default: switch { default: return -1 @@ -791,7 +787,8 @@ fun[1] = func(r rune) int { } panic("unreachable") } -fun[0] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { case 10: return 1 case 32: return 1 @@ -810,21 +807,21 @@ a0[11].id = 11 { var acc [3]bool var fun [3]func(rune) int -acc[2] = true -fun[2] = func(r rune) int { +acc[1] = true +fun[1] = func(r rune) int { switch(r) { - case 61: return 2 - case 45: return 2 - case 32: return -1 - case 62: return 2 - case 58: return -1 - case 12: return -1 - case 94: return -1 - case 10: return -1 - case 43: return 2 - case 13: return -1 case 60: return 2 + case 62: return 2 + case 32: return -1 + case 58: return -1 + case 10: return -1 + case 94: return -1 case 9: return -1 + case 12: return -1 + case 45: return 2 + case 61: return 2 + case 13: return -1 + case 43: return 2 default: switch { default: return 2 @@ -832,21 +829,21 @@ fun[2] = func(r rune) int { } panic("unreachable") } -acc[1] = true -fun[1] = func(r rune) int { +acc[2] = true +fun[2] = func(r rune) int { switch(r) { - case 13: return -1 - case 60: return 2 - case 9: return -1 - case 61: return 2 case 45: return 2 - case 32: return -1 - case 62: return 2 - case 58: return -1 - case 12: return -1 - case 94: return -1 - case 10: return -1 + case 61: return 2 + case 13: return -1 case 43: return 2 + case 60: return 2 + case 62: return 2 + case 32: return -1 + case 58: return -1 + case 10: return -1 + case 94: return -1 + case 9: return -1 + case 12: return -1 default: switch { default: return 2 @@ -856,18 +853,18 @@ fun[1] = func(r rune) int { } fun[0] = func(r rune) int { switch(r) { - case 43: return -1 - case 13: return -1 - case 60: return -1 - case 9: return -1 - case 61: return -1 - case 45: return -1 - case 32: return -1 case 62: return -1 + case 32: return -1 case 58: return -1 - case 12: return -1 - case 94: return -1 case 10: return -1 + case 94: return -1 + case 9: return -1 + case 12: return -1 + case 45: return -1 + case 61: return -1 + case 13: return -1 + case 43: return -1 + case 60: return -1 default: switch { default: return 1 @@ -1007,8 +1004,7 @@ func (yylex lexer) Lex(lval *yySymType) int { case 10: //-?([0-9]|[1-9][0-9]*)(\.[0-9][0-9]*)?/ { lval.s = yylex.Text() - lval.f,_ = strconv.ParseFloat(yylex.Text(), 64); - logDebugTokens("NUMBER - %f", lval.f); + logDebugTokens("NUMBER - %s", lval.s); return tNUMBER } case 11: //[ \t\n]+/ diff --git a/query_string.y b/query_string.y index 0a91dbd5..d013c2dd 100644 --- a/query_string.y +++ b/query_string.y @@ -1,6 +1,7 @@ %{ package bleve import "log" +import "strconv" func logDebugGrammar(format string, v ...interface{}) { if debugParser { @@ -12,10 +13,20 @@ func logDebugGrammar(format string, v ...interface{}) { %union { s string n int -f float64} +f float64 +q Query} %token tSTRING tPHRASE tPLUS tMINUS tCOLON tBOOST tLPAREN tRPAREN tNUMBER tSTRING tGREATER tLESS tEQUAL +%type tSTRING +%type tPHRASE +%type tNUMBER +%type searchBase +%type searchSuffix +%type searchPrefix +%type searchMustMustNot +%type searchBoost + %% input: @@ -34,125 +45,133 @@ searchPart { searchPart: searchPrefix searchBase searchSuffix { - + query := $2 + query.SetBoost($3) + switch($1) { + case queryShould: + yylex.(*lexerWrapper).query.AddShould(query) + case queryMust: + yylex.(*lexerWrapper).query.AddMust(query) + case queryMustNot: + yylex.(*lexerWrapper).query.AddMustNot(query) + } }; searchPrefix: /* empty */ { + $$ = queryShould } | searchMustMustNot { - + $$ = $1 } ; searchMustMustNot: tPLUS { logDebugGrammar("PLUS") - parsingMust = true + $$ = queryMust } | tMINUS { logDebugGrammar("MINUS") - parsingMustNot = true + $$ = queryMustNot }; searchBase: tSTRING { - str := $1.s + str := $1 logDebugGrammar("STRING - %s", str) q := NewMatchQuery(str) - addQueryToList(q) + $$ = q } | tNUMBER { - str := $1.s + str := $1 logDebugGrammar("STRING - %s", str) q := NewMatchQuery(str) - addQueryToList(q) + $$ = q } | tPHRASE { - phrase := $1.s + phrase := $1 logDebugGrammar("PHRASE - %s", phrase) q := NewMatchPhraseQuery(phrase) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tSTRING { - field := $1.s - str := $3.s + field := $1 + str := $3 logDebugGrammar("FIELD - %s STRING - %s", field, str) q := NewMatchQuery(str).SetField(field) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tNUMBER { - field := $1.s - str := $3.s + field := $1 + str := $3 logDebugGrammar("FIELD - %s STRING - %s", field, str) q := NewMatchQuery(str).SetField(field) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tPHRASE { - field := $1.s - phrase := $3.s + field := $1 + phrase := $3 logDebugGrammar("FIELD - %s PHRASE - %s", field, phrase) q := NewMatchPhraseQuery(phrase).SetField(field) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tGREATER tNUMBER { - field := $1.s - min := $4.f + field := $1 + min, _ := strconv.ParseFloat($4, 64) minInclusive := false logDebugGrammar("FIELD - GREATER THAN %f", min) q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil).SetField(field) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tGREATER tEQUAL tNUMBER { - field := $1.s - min := $5.f + field := $1 + min, _ := strconv.ParseFloat($5, 64) minInclusive := true logDebugGrammar("FIELD - GREATER THAN OR EQUAL %f", min) q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil).SetField(field) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tLESS tNUMBER { - field := $1.s - max := $4.f + field := $1 + max, _ := strconv.ParseFloat($4, 64) maxInclusive := false logDebugGrammar("FIELD - LESS THAN %f", max) q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive).SetField(field) - addQueryToList(q) + $$ = q } | tSTRING tCOLON tLESS tEQUAL tNUMBER { - field := $1.s - max := $5.f + field := $1 + max, _ := strconv.ParseFloat($5, 64) maxInclusive := true logDebugGrammar("FIELD - LESS THAN OR EQUAL %f", max) q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive).SetField(field) - addQueryToList(q) + $$ = q }; searchBoost: tBOOST tNUMBER { - boost := $2.f - if parsingLastQuery != nil { - parsingLastQuery.SetBoost(boost) - } + boost, _ := strconv.ParseFloat($2, 64) + $$ = boost logDebugGrammar("BOOST %f", boost) }; searchSuffix: /* empty */ { - + $$ = 1.0 } | searchBoost { diff --git a/y.go b/query_string.y.go similarity index 83% rename from y.go rename to query_string.y.go index fcca93a9..21c87d7b 100644 --- a/y.go +++ b/query_string.y.go @@ -4,6 +4,7 @@ import __yyfmt__ "fmt" //line query_string.y:2 import "log" +import "strconv" func logDebugGrammar(format string, v ...interface{}) { if debugParser { @@ -11,12 +12,13 @@ func logDebugGrammar(format string, v ...interface{}) { } } -//line query_string.y:12 +//line query_string.y:13 type yySymType struct { yys int s string n int f float64 + q Query } const tSTRING = 57346 @@ -73,8 +75,8 @@ const yyLast = 28 var yyAct = []int{ 18, 20, 25, 23, 28, 26, 24, 27, 19, 21, - 22, 10, 12, 17, 15, 14, 16, 6, 7, 11, - 2, 5, 13, 9, 8, 4, 3, 1, + 22, 10, 12, 17, 15, 3, 16, 6, 7, 11, + 2, 1, 14, 5, 8, 4, 13, 9, } var yyPact = []int{ @@ -84,13 +86,13 @@ var yyPact = []int{ } var yyPgo = []int{ - 0, 27, 20, 26, 25, 23, 22, 21, 15, + 0, 27, 26, 25, 23, 22, 21, 20, 15, } var yyR1 = []int{ - 0, 1, 2, 2, 3, 4, 4, 7, 7, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, - 6, 6, + 0, 6, 7, 7, 8, 3, 3, 4, 4, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, + 2, 2, } var yyR2 = []int{ @@ -100,8 +102,8 @@ var yyR2 = []int{ } var yyChk = []int{ - -1000, -1, -2, -3, -4, -7, 6, 7, -2, -5, - 4, 12, 5, -6, -8, 9, 8, 12, 4, 12, + -1000, -6, -7, -8, -3, -4, 6, 7, -7, -1, + 4, 12, 5, -2, -5, 9, 8, 12, 4, 12, 5, 13, 14, 12, 15, 12, 15, 12, 12, } var yyDef = []int{ @@ -349,153 +351,161 @@ yydefault: switch yynt { case 1: - //line query_string.y:22 + //line query_string.y:33 { logDebugGrammar("INPUT") } case 2: - //line query_string.y:27 + //line query_string.y:38 { logDebugGrammar("SEARCH PARTS") } case 3: - //line query_string.y:31 + //line query_string.y:42 { logDebugGrammar("SEARCH PART") } case 4: - //line query_string.y:36 + //line query_string.y:47 { - + query := yyS[yypt-1].q + query.SetBoost(yyS[yypt-0].f) + switch yyS[yypt-2].n { + case queryShould: + yylex.(*lexerWrapper).query.AddShould(query) + case queryMust: + yylex.(*lexerWrapper).query.AddMust(query) + case queryMustNot: + yylex.(*lexerWrapper).query.AddMustNot(query) + } } case 5: - //line query_string.y:42 - { - } - case 6: - //line query_string.y:45 - { - - } - case 7: - //line query_string.y:51 - { - logDebugGrammar("PLUS") - parsingMust = true - } - case 8: - //line query_string.y:56 - { - logDebugGrammar("MINUS") - parsingMustNot = true - } - case 9: //line query_string.y:62 { - str := yyS[yypt-0].s - logDebugGrammar("STRING - %s", str) - q := NewMatchQuery(str) - addQueryToList(q) + yyVAL.n = queryShould } - case 10: - //line query_string.y:69 + case 6: + //line query_string.y:66 + { + yyVAL.n = yyS[yypt-0].n + } + case 7: + //line query_string.y:72 + { + logDebugGrammar("PLUS") + yyVAL.n = queryMust + } + case 8: + //line query_string.y:77 + { + logDebugGrammar("MINUS") + yyVAL.n = queryMustNot + } + case 9: + //line query_string.y:83 { str := yyS[yypt-0].s logDebugGrammar("STRING - %s", str) q := NewMatchQuery(str) - addQueryToList(q) + yyVAL.q = q + } + case 10: + //line query_string.y:90 + { + str := yyS[yypt-0].s + logDebugGrammar("STRING - %s", str) + q := NewMatchQuery(str) + yyVAL.q = q } case 11: - //line query_string.y:76 + //line query_string.y:97 { phrase := yyS[yypt-0].s logDebugGrammar("PHRASE - %s", phrase) q := NewMatchPhraseQuery(phrase) - addQueryToList(q) + yyVAL.q = q } case 12: - //line query_string.y:83 + //line query_string.y:104 { field := yyS[yypt-2].s str := yyS[yypt-0].s logDebugGrammar("FIELD - %s STRING - %s", field, str) q := NewMatchQuery(str).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 13: - //line query_string.y:91 + //line query_string.y:112 { field := yyS[yypt-2].s str := yyS[yypt-0].s logDebugGrammar("FIELD - %s STRING - %s", field, str) q := NewMatchQuery(str).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 14: - //line query_string.y:99 + //line query_string.y:120 { field := yyS[yypt-2].s phrase := yyS[yypt-0].s logDebugGrammar("FIELD - %s PHRASE - %s", field, phrase) q := NewMatchPhraseQuery(phrase).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 15: - //line query_string.y:107 + //line query_string.y:128 { field := yyS[yypt-3].s - min := yyS[yypt-0].f + min, _ := strconv.ParseFloat(yyS[yypt-0].s, 64) minInclusive := false logDebugGrammar("FIELD - GREATER THAN %f", min) q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 16: - //line query_string.y:116 + //line query_string.y:137 { field := yyS[yypt-4].s - min := yyS[yypt-0].f + min, _ := strconv.ParseFloat(yyS[yypt-0].s, 64) minInclusive := true logDebugGrammar("FIELD - GREATER THAN OR EQUAL %f", min) q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 17: - //line query_string.y:125 + //line query_string.y:146 { field := yyS[yypt-3].s - max := yyS[yypt-0].f + max, _ := strconv.ParseFloat(yyS[yypt-0].s, 64) maxInclusive := false logDebugGrammar("FIELD - LESS THAN %f", max) q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 18: - //line query_string.y:134 + //line query_string.y:155 { field := yyS[yypt-4].s - max := yyS[yypt-0].f + max, _ := strconv.ParseFloat(yyS[yypt-0].s, 64) maxInclusive := true logDebugGrammar("FIELD - LESS THAN OR EQUAL %f", max) q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive).SetField(field) - addQueryToList(q) + yyVAL.q = q } case 19: - //line query_string.y:145 + //line query_string.y:166 { - boost := yyS[yypt-0].f - if parsingLastQuery != nil { - parsingLastQuery.SetBoost(boost) - } + boost, _ := strconv.ParseFloat(yyS[yypt-0].s, 64) + yyVAL.f = boost logDebugGrammar("BOOST %f", boost) } case 20: - //line query_string.y:154 + //line query_string.y:173 { - + yyVAL.f = 1.0 } case 21: - //line query_string.y:158 + //line query_string.y:177 { } diff --git a/query_string_parser.go b/query_string_parser.go index 3557376f..36efdf25 100644 --- a/query_string_parser.go +++ b/query_string_parser.go @@ -12,60 +12,57 @@ package bleve import ( "fmt" "strings" - "sync" ) -var crashHard = false -var parserMutex sync.Mutex -var parsingMust bool -var parsingMustNot bool var debugParser bool var debugLexer bool -var parsingLastQuery Query -var parsingMustList []Query -var parsingMustNotList []Query -var parsingShouldList []Query -var parsingIndexMapping *IndexMapping - func parseQuerySyntax(query string, mapping *IndexMapping) (rq Query, err error) { - parserMutex.Lock() - defer parserMutex.Unlock() + lex := newLexerWrapper(newLexer(strings.NewReader(query))) + doParse(lex) - parsingIndexMapping = mapping - parsingMustList = make([]Query, 0) - parsingMustNotList = make([]Query, 0) - parsingShouldList = make([]Query, 0) + if len(lex.errs) > 0 { + return nil, fmt.Errorf(strings.Join(lex.errs, "\n")) + } else { + return lex.query, nil + } +} +func doParse(lex *lexerWrapper) { defer func() { r := recover() - if r != nil && r == "syntax error" { - // if we're panicing over a syntax error, chill - err = fmt.Errorf("Parse Error - %v", r) - } else if r != nil { - // otherise continue to panic - if crashHard { - panic(r) - } else { - err = fmt.Errorf("Other Error - %v", r) - } + if r != nil { + lex.Error("Errors while parsing.") } }() - yyParse(newLexer(strings.NewReader(query))) - rq = NewBooleanQuery(parsingMustList, parsingShouldList, parsingMustNotList) - return rq, err + yyParse(lex) } -func addQueryToList(q Query) { - if parsingMust { - parsingMustList = append(parsingMustList, q) - parsingMust = false - } else if parsingMustNot { - parsingMustNotList = append(parsingMustNotList, q) - parsingMustNot = false - } else { - parsingShouldList = append(parsingShouldList, q) - } - parsingLastQuery = q +const ( + queryShould = iota + queryMust + queryMustNot +) + +type lexerWrapper struct { + nex yyLexer + errs []string + query *booleanQuery +} + +func newLexerWrapper(nex yyLexer) *lexerWrapper { + return &lexerWrapper{ + nex: nex, + errs: []string{}, + query: NewBooleanQuery(nil, nil, nil), + } +} + +func (this *lexerWrapper) Lex(lval *yySymType) int { + return this.nex.Lex(lval) +} + +func (this *lexerWrapper) Error(s string) { + this.errs = append(this.errs, s) }