Parsing 解析器组合器-简单语法
我试图在一个简单的语法上使用Scala中的解析器组合符,我从一本书中复制了这个语法。当我运行下面的代码时,它会在第一个令牌被解析为错误后立即停止Parsing 解析器组合器-简单语法,parsing,scala,context-free-grammar,parser-combinators,Parsing,Scala,Context Free Grammar,Parser Combinators,我试图在一个简单的语法上使用Scala中的解析器组合符,我从一本书中复制了这个语法。当我运行下面的代码时,它会在第一个令牌被解析为错误后立即停止 [1.3]失败:应为与正则表达式“\z”匹配的字符串,但找到“+” 我明白为什么事情会出错。第一个标记是一个表达式,因此它是唯一需要根据语法进行解析的东西。然而,我不知道什么是修复它的好方法 object SimpleParser extends RegexParsers { def Name = """[a-zA-Z]+""".r
[1.3]失败:应为与正则表达式“\z”匹配的字符串,但找到“+”
我明白为什么事情会出错。第一个标记是一个表达式,因此它是唯一需要根据语法进行解析的东西。然而,我不知道什么是修复它的好方法
object SimpleParser extends RegexParsers
{
def Name = """[a-zA-Z]+""".r
def Int = """[0-9]+""".r
def Main:Parser[Any] = Expr
def Expr:Parser[Any] =
(
Term
| Term <~ "+" ~> Expr
| Term <~ "-" ~> Expr
)
def Term:Parser[Any] =
(
Factor
| Factor <~ "*" ~> Term
)
def Factor:Parser[Any] =
(
Name
| Int
| "-" ~> Int
| "(" ~> Expr <~ ")"
| "let" ~> Name <~ "=" ~> Expr <~ "in" ~> Expr <~ "end"
)
def main(args: Array[String])
{
var input = "2 + 2"
println(input)
println(parseAll(Main, input))
}
}
objectsimpleparser扩展regexparser
{
def Name=“”[a-zA-Z]+“”。r
def Int=“”[0-9]+”。r
def Main:Parser[Any]=Expr
def Expr:解析器[任何]=
(
学期
|术语表达式
|术语表达式
)
定义术语:解析器[任何]=
(
因素
|因子项
)
定义因子:解析器[任何]=
(
名称
|Int
|“-”~>Int
|“(“~>Expr Name Expr Expr ExprFactor Term
的意思是Factor.Term)
,因此整个右侧部分被删除。
使用Factor~“*”~Term^{case f~~t=>?}
或rep1sep
:
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.util.parsing.combinator.RegexParsers
object SimpleParser extends RegexParsers
{
def Name = """[a-zA-Z]+""".r
def Int = """[0-9]+""".r
def Main:Parser[Any] = Expr
def Expr:Parser[Any] = rep1sep(Term, "+" | "-")
def Term:Parser[Any] = rep1sep(Factor, "*")
def Factor:Parser[Any] =
(
"let" ~> Name ~ "=" ~ Expr ~ "in" ~ Expr <~ "end" ^^ { case n ~ _ ~ e1 ~ _ ~ e2 => (n, e1, e2)
| Int
| "-" ~> Int
| "(" ~> Expr <~ ")"
| Name }
)
}
SimpleParser.parseAll(SimpleParser.Main, "2 + 2")
// Exiting paste mode, now interpreting.
import scala.util.parsing.combinator.RegexParsers
defined module SimpleParser
res1: SimpleParser.ParseResult[Any] = [1.6] parsed: List(List(2), List(2))
scala>:粘贴
//进入粘贴模式(按ctrl-D键完成)
导入scala.util.parsing.combinator.RegexParsers
对象SimpleParser扩展regexparser
{
def Name=“”[a-zA-Z]+“”。r
def Int=“”[0-9]+”。r
def Main:Parser[Any]=Expr
def Expr:Parser[Any]=rep1sep(术语“+”|“-”)
def Term:Parser[Any]=rep1sep(Factor,“*”)
定义因子:解析器[任何]=
(
让“~>Name~”=“~Expr~”在“~Expr(n,e1,e2)中
|Int
|“-”~>Int
|“(“~>Expr谢谢!我可以理解我用了一种错误的方式。但是我不明白为什么有必要使用rep1sep。它以前的方式有什么问题?rep1sep
只是比较短。你可以用def Term:Parser[Any]=rep1sep(Factor,“*”/code>替换为def Term:Parser[Any]=Factor~“*”~Term^{case f~\ut=>(f,t)}Factor
@MadsAndersen,有必要使用Factor~“*”~Term}Factor
而不是Factor}Factor~“*”~Term
。请参阅更新的答案。感谢您的帮助!我想我已经了解到规则的顺序很重要。Fx,let定义必须在名称定义之前。