1

I am writing software that will interface external device via exchange of ASCII commands. Example:

POS? 1 2
=>1=-1158.4405
=>2=+0000.0000

where above we ask for position of motorised microscope stage for the 1-st and 2-nd axes. It responds with positions in um. More details and examples.

My Question: is there a library that would ease parsing such string outputs, and/or would help generate queries? Otherwise, what are the best practises for parsing and communicating with hardware using Java/Scala?

6
  • You can use the built in String handling and pattern matching library in the JDK. Best practice would be to use the driver or method the hardware vendor recommends. Commented Jul 7, 2015 at 23:05
  • Take a look at Combinator Parsing Commented Jul 8, 2015 at 7:26
  • Built-in Scala string matching will probably suffice. Regular expressions can be helpful. In your example, what is the input and what the output? What strings do you want to generate and parse? What have you tried so far? Commented Jul 8, 2015 at 8:27
  • Sounds like a job for regular expressions. See, for example, this question: stackoverflow.com/questions/30907921/regex-extraction-in-scala/… Commented Jul 8, 2015 at 9:08
  • @Madoc, i am sending string "POS? 1 2" and receiving two lines back: "1=-1158.4405" and "2=+0000.0000". These strings have general rules of formatting, see doc in the link above, that would be nice to capture with universal parsing script/library. Commented Jul 8, 2015 at 9:51

1 Answer 1

1

Trying to cope with following syntax (see 12.1 Format):

 Reply syntax:
     [<argument>[{SP<argument>}]"="]<value>LF
 Multi-line reply syntax:
     {[<argument>[{SP<argument>}]"="]<value>SP LF}
     [<argument>[{SP<argument>}]"="]<value>LF for the last line!

This is my code:

import scala.util.parsing.combinator._

case class Result(argument: String, value: Float)

class ReplyParser extends RegexParsers{
    override def skipWhitespace = false
    private def floatingPointNumber: Parser[String] = 
        """(-|\+)?(\d+(\.\d*)?|\d*\.\d+)""".r
    private def value: Parser[Float] = floatingPointNumber ^^ (_.toFloat)
    private def argument: Parser[String] = "[^= \n]+".r
    private def arguments: Parser[List[String]] = rep1sep(argument," ") <~ "="
    private def result: Parser[List[Result]] = arguments.? ~ value ^^ {
        case arguments ~ value => 
            arguments.getOrElse(List("")).map {
                Result(_,value)
            }
    }
    def reply: Parser[List[Result]] = rep1sep(result, " \n".r) <~ " " ^^ {
        case result => result.flatten
    }
}

object Parsing extends ReplyParser {
    def main(args: Array[String]) {
        val result = parseAll(reply,"a=+000.123 \nc d=-999.567 \n789 ")
        println(s"$result")
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.