2011-07-19 10 views
7

Czy istnieje biblioteka łączników parsera, która zapewnia wydajność porównywalną z funkcją Happy/Alex?Biblioteka łączników parserów z wyboru (haskell)

wiem o Attoparsec, ale czasami to nie działa dobrze, jak w poniższym przykładzie:

isToken c = isLetter c || isDigit c 

symbol :: Parser Expr 
symbol = do 
    c <- skipSpace >> satisfy isLetter 
    rest <- takeWhile isToken 
    let token = C.cons c rest -- oops... O(N) 
    error $ show token 

Rozwiązaniem jest dość brzydki:

do { skipSpace; bs <- scan go True; when (null bs) (fail "Not a symbol"); return bs} 
    where go True c = if isLetter c then Just False else Nothing 
      go False c = if isToken c then Just Fasle else Nothing 

Również Attoparsec brakuje obsługi błędów.

Happy/Alex są dość nieprzyjazne (dla mnie) w porównaniu do ocamlyacc/ocamllex, BNFC jest nieelastyczny iw moim przypadku wymaga dodatkowego ruchu AST po analizie składniowej. Ponadto obsługa błędów nie jest zbyt dobra.

Dostępne są trzy opcje odpoczynku: Parsec2, Parsec3 i uu-parselib. Znalazłem wiele kontrowersyjnych benchmarków, zakładając, że Parsec2 jest szybszy niż Parsec3 lub UU jest szybsze, lub wolniejsze.

Ale co wybrać? Czy ktoś ma doświadczenie z wykorzystaniem uu-parselib? Potrzebuję parsera do jakiegoś rodzaju DSL, potrzebuję paczek wystarczająco szybko, aby nie zmienić go w przyszłości.

+1

Jeśli analizujesz dane o "wielkości człowieka" (tzn. Pliki napisane przez ludzi), każda z głównych bibliotek kombinatorycznych parserów powinna być w porządku pod względem szybkości, ale być może trzeba będzie zwrócić uwagę na kontrolowanie cofania w parser, który piszesz. Jeśli analizujesz ogromne pliki danych, to równanie nieco się zmienia. Poszukiwałbym wtedy benchmarków i zastanawiałem się, jakie funkcje można wykupić w zamian za szybkość (np. Śledzenie pozycji źródła może być znacznym spowolnieniem). –

+1

Nie jestem odpowiedzią, ale bardzo często używałam uu-parselib. Jest bardzo wydajny i ma kilka fajnych funkcji, takich jak automatyczna korekta strumienia. Moją jedyną skargą jest to, że nie wszystkie funkcje są od razu oczywiste; zwłaszcza jeśli nie znasz już parserów. Nigdy nie miałem problemu z szybkością, ale moje dane wejściowe były głównie w rozmiarze kbyte. –

Odpowiedz

7
  1. Istnieje jeszcze jedna alternatywa: poliparse.

  2. Po zeszłorocznym GSoC, parsec3 został zoptymalizowany i nie jest już znacznie wolniej niż parsec2

  3. Kilka lat temu robiłem testy na kilku gramatyk (średniej wielkości) i stwierdził, że wykonanie zadowolony/alex , parsec2/alex, parsec2 i polyparse są bardzo bliskie. Attoparsec był szybszy w strumieniach bajtów, ale potrzebowałem wielobajtowego.

Moja rada: przyjrzeć się sposobowi alternatyw obsłużyć stan wewnętrzny i zdefiniowane przez użytkownika i zgłaszać błędy i wybrać tych kryteriów.

+2

Czy jesteś pewien, że Parsec jest blisko Happy/Alex? W takim przypadku nie ma sensu używanie Happy lub BNFC w ogóle. Czy mogą istnieć jakieś punkty odniesienia do samodzielnego prowadzenia? – voidlizard

+3

Bez względu na wydajność, używanie generatora analizatora składni takiego jak Happy ma tę zaletę, że dostajesz błędy i ostrzeżenia o swojej gramatyce (jak niejednoznaczności). – augustss

+1

Co z tekstem attoparsec? – alternative