我正在创建一个dsl,并使用scala的解析器组合库来解析dsl。dsl遵循一种简单的、类似ruby的语法。源文件可以包含一系列如下所示的块:
create_model do
at 0,0,0
end
行结束在dsl中是重要的,因为它们被有效地用作语句结束符。
我编写了一个scala解析器,如下所示:
class ML3D extends JavaTokenParsers {
override val whiteSpace = """[ \t]+""".r
def model: Parser[Any] = commandList
def commandList: Parser[Any] = rep(commandBlock)
def commandBlock: Parser[Any] = command~"do"~eol~statementList~"end"
def eol: Parser[Any] = """(\r?\n)+""".r
def command: Parser[Any] = commandName~opt(commandLabel)
def commandName: Parser[Any] = ident
def commandLabel: Parser[Any] = stringLiteral
def statementList: Parser[Any] = rep(statement)
def statement: Parser[Any] = functionName~argumentList~eol
def functionName: Parser[Any] = ident
def argumentList: Parser[Any] = repsep(argument, ",")
def argument: Parser[Any] = stringLiteral | constant
def constant: Parser[Any] = wholeNumber | floatingPointNumber
}
因为行尾很重要,所以我重写了
whiteSpace
所以它将只将空格和制表符视为空白(而不是将新行视为空白,从而忽略它们)。
这是有效的,除了
commandBlock
. 由于我的源文件包含一个尾随的新行,解析器抱怨它只需要一个
end
但是在
结束
关键字。
所以我改变了
命令块
的定义:
def commandBlock: Parser[Any] = command~"do"~eol~statementList~"end"~opt(eol)
(也就是说,我在“end”后面添加了一个可选的新行)。
但是现在,在分析源文件时,我得到以下错误:
[4.1] failure: `end' expected but `' found
我
认为
这是因为,在它吸干后面的新行之后,解析器遇到了一个它认为无效的空字符串,但我不确定它为什么这样做。
有什么解决办法吗?我可能从scala的parser combinator库中扩展了错误的解析器,因此,关于如何创建具有重要新行字符的语言定义的任何建议也都是受欢迎的。