Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 解析器组合器-简单语法_Parsing_Scala_Context Free Grammar_Parser Combinators - Fatal编程技术网

Parsing 解析器组合器-简单语法

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

我试图在一个简单的语法上使用Scala中的解析器组合符,我从一本书中复制了这个语法。当我运行下面的代码时,它会在第一个令牌被解析为错误后立即停止

[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 Expr
Factor 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定义必须在名称定义之前。