How can I create a parser combinator in which line endings are significant?

前端 未结 2 1924
名媛妹妹
名媛妹妹 2020-12-31 04:51

I am creating a DSL, and using Scala\'s parser combinator library to parse the DSL. The DSL follows a simple, Ruby-like syntax. A source file can contain a series of blocks

相关标签:
2条回答
  • 2020-12-31 05:26

    I get the same error in both ways, but I think you are misinterpreting it. What it's saying is that it is expecting an end, but it already reached the end of the input.

    And the reason that is happening is that end is being read as a statement. Now, I'm sure there's a nice way to solve this, but I'm not experienced enough with Scala parsers. It seems the way to go would be to use token parsers with a scanning part, but I couldn't figure a way to make the standard token parser not treat newlines as whitespace.

    So, here's an alternative:

    import scala.util.parsing.combinator.JavaTokenParsers
    
    class ML3D extends JavaTokenParsers {
      override val whiteSpace = """[ \t]+""".r
      def keywords: Parser[Any] = "do" | "end"
      def identifier: Parser[Any] = not(keywords)~ident
    
      def model: Parser[Any] = commandList
      def commandList: Parser[Any] = rep(commandBlock)
      def commandBlock: Parser[Any] = command~"do"~eol~statementList~"end"~opt(eol)
      def eol: Parser[Any] = """(\r?\n)+""".r
      def command: Parser[Any] = commandName~opt(commandLabel)
      def commandName: Parser[Any] = identifier
      def commandLabel: Parser[Any] = stringLiteral
      def statementList: Parser[Any] = rep(statement)
      def statement: Parser[Any] = functionName~argumentList~eol
      def functionName: Parser[Any] = identifier
      def argumentList: Parser[Any] = repsep(argument, ",")
      def argument: Parser[Any] = stringLiteral | constant
      def constant: Parser[Any] = wholeNumber | floatingPointNumber
    }
    
    0 讨论(0)
  • 2020-12-31 05:30

    You can either override the protected val whiteSpace (a Regex) whose default is """\s+""".r or override the protected def handleWhiteSpace(...) method if you need more control than is readily achieved with a regular expression. Both these members orginate in RegexParsers, which is the base class for JavaTokenParsers.

    0 讨论(0)
提交回复
热议问题