2012-01-13 21 views
5

Część aplikacji Lua to pasek wyszukiwania i staram się, aby rozumiał wyrażenia boolowskie. Używam LPeg, ale obecna gramatyka daje dziwne wyniki:Gramatyka LPeg dziwności

> re, yajl = require're', require'yajl' 
> querypattern = re.compile[=[ 
    QUERY  <- (EXPR/TERM)? S? !. -> {} 
    EXPR  <- S? TERM ((S OPERATOR)? S TERM)+ -> {} 
    TERM  <- KEYWORD/("(" S? EXPR S? ")") -> {} 
    KEYWORD  <- (WORD {":"})? (WORD/STRING) 
    WORD  <- {[A-Za-z][A-Za-z0-9]*} 
    OPERATOR <- {("AND"/"XOR"/"NOR"/"OR")} 
    STRING  <- ('"' {[^"]*} '"'/"'" {[^']*} "'") -> {} 
    S   <- %s+ 
]=] 
> = yajl.to_string(lpeg.match(querypattern, "bar foo")) 
"bar" 
> = yajl.to_string(lpeg.match(querypattern, "name:bar AND foo")) 
> = yajl.to_string(lpeg.match(querypattern, "name:bar AND foo")) 
"name" 
> = yajl.to_string(lpeg.match(querypattern, "name:'bar' AND foo")) 
"name" 
> = yajl.to_string(lpeg.match(querypattern, "bar AND (name:foo OR place:here)")) 
"bar" 

Analizuje tylko pierwszy znak, a ja nie mogę zrozumieć, dlaczego to robi. O ile mi wiadomo, częściowe dopasowanie jest niemożliwe z powodu !. na końcu początkowego nie-terminala. Jak mogę to naprawić?

Odpowiedz

10

Mecz otrzymuje cały ciąg, ale przechwyty są nieprawidłowe. Zauważ, że „->” ma wyższy priorytet niż łączenie, więc prawdopodobnie trzeba nawiasy wokół rzeczy tak:

EXPR  <- S? (TERM ((S OPERATOR)? S TERM)+) -> {} 
+0

Dziękujemy! To był właśnie problem, który miałem. Nigdy nie zdawałem sobie sprawy, że przechwytywanie stołów ma w rzeczywistości wysoki priorytet. – mmirate