Piszę gramaturę kombinatoryczną Scalera, która odczytuje listy słów rozdzielanych znakami nowej linii, gdzie listy są oddzielone jedną lub większą liczbą pustych wierszy. Biorąc pod uwagę następujący ciąg:Kombinatory parsera Scala i tekst rozdzielany wierszami
cat
mouse
horse
apple
orange
pear
Chciałbym go zwrócić List(List(cat, mouse, horse), List(apple, orange, pear))
.
Napisałem tę podstawową gramatykę, która traktuje listy słów jako słowa rozdzielone wierszami. Zauważ, że musiałem zastąpić domyślną definicję whitespace
.
import util.parsing.combinator.RegexParsers
object WordList extends RegexParsers {
private val eol = sys.props("line.separator")
override val whiteSpace = """[ \t]+""".r
val list: Parser[List[String]] = repsep("""\w+""".r, eol)
val lists: Parser[List[List[String]]] = repsep(list, eol)
def main(args: Array[String]) {
val s =
"""cat
|mouse
|horse
|
|apple
|orange
|pear""".stripMargin
println(parseAll(lists, s))
}
}
To niepoprawnie traktuje puste wiersze jako pustych list wyrazów, to znaczy powraca
[8.1] parsed: List(List(cat, mouse, horse), List(), List(apple, orange, pear))
(Uwaga pusty listy w środku).
mogę umieścić opcjonalny końca linii na koniec każdej listy.
val list: Parser[List[String]] = repsep("""\w+""".r, eol) <~ opt(eol)
ten obsługuje przypadek, w którym istnieje jeden pusty wiersz między listami, ale ma ten sam problem z wieloma pustymi wierszami.
Próbuję zmienić definicję lists
aby umożliwić wielu wycofanych z linii ograniczniki:
val lists:Parser[List[List[String]]] = repsep(list, rep(eol))
ale to wisi na powyższym wejścia.
Jaka jest poprawna gramatyka, która obsłuży wiele pustych linii jako ograniczniki?
który działa, jeśli jest tylko jeden pusty wiersz między listami słów. Jeśli istnieją _n_ puste linie, kończymy z pustymi listami _n-1_ po środku. (BTW: przykłady 'skipWhitespace' i' eoi' są bardzo przydatne.) –
@ W.P.McNeill - Zaktualizowałem kod, aby wyszukać 'rep1 (eol)' pomiędzy listami łańcuchów. Czy to właśnie zamierzałeś? – DaoWen
'rep1 (eol)' jest tym, czego szukałem. Dzięki. Wiem, że kombinatory parserów są tu przesadzone. Celowo uprościłem problem do celów ekspozycji. –