Search code examples
parsingfastparse

How to handle text tables with FastParse?


I have text file with single row table (tab separated) and I need to parse it to receive Map("one" -> 1, "two" -> 2, "three" -> 3). I can't figure out how to do it and even not sure that it is possible at all. Any ideas guys?

one two three
1   2   3

Solution

  • Ok, I've figured out how to do it by myself.

    val lines = Source.fromResource("test.txt").getLines().mkString("\r\n")
    
      def sentence[_: P] = P(CharIn("0-9", "a-z").rep(1).!)
    
      def tableHeader[_: P] = P((sentence.! ~ "\t".?).rep ~ lineSeparator)
      def tableRow[_: P](h: Seq[String]) = P((sentence.! ~ "\t".?).rep ~ (lineSeparator | End))
        .map(r => println(h.zip(r).toMap))
      def singleRowTable[_: P] = P(tableHeader.flatMap(tableRow))
      def lineSeparator[_: P] = P("\r\n" | "\r" | "\n")
      def parseA[_: P] = P(singleRowTable)
    
    
      parse(lines, parseA(_), true) match {
        case Parsed.Success(value, successIndex) =>
          println("Success value=" + value +" successIndex=" + successIndex)
        case f @ Parsed.Failure(label, index, extra) =>
          println("Failure " + f.trace(true))
    
      }
    

    It will print

    Map(one -> 1, two -> 2, three -> 3)
    Success value=() successIndex=20