标签: parser-combinators

Scala PackratParser忽略失败解析器

我有一个使用Scala的编写的解析器RegexParsers- 链接

在解析具有深层嵌套表达式的语法时,它有一些严重的性能问题.因此我创建了一个版本,我将其混合在Scala的PackratParsers- 链接中

Packrat版本没有出现相同的性能问题并正确解析语法.但是,当我提供无效的语法进行测试时,例如这个

用于通过此处的失败解析器组合器正确报告"无效规则"失败的旧(非包装)解析器| failure("Invalid rule")- 链接

当使用packrat-parser版本时,如果我启用跟踪,我可以从跟踪中看到故障是在非packrat版本中创建的,但PackratParser似乎忽略了这一点并且总是返回failure: Base Failure.

在使用我需要理解的PackratParsers时,是否存在与故障处理有所不同的内容?

parsing scala parser-combinators

43
推荐指数
1
解决办法
392
查看次数

使用Scala解析器组合器来解析CSV文件

我正在尝试使用Scala解析器组合器编写CSV解析器.语法基于RFC4180.我想出了以下代码.它几乎可以工作,但我不能让它正确地分隔不同的记录.我错过了什么?

object CSV extends RegexParsers {
  def COMMA   = ","
  def DQUOTE  = "\""
  def DQUOTE2 = "\"\"" ^^ { case _ => "\"" }
  def CR      = "\r"
  def LF      = "\n"
  def CRLF    = "\r\n"
  def TXT     = "[^\",\r\n]".r

  def file: Parser[List[List[String]]] = ((record~((CRLF~>record)*))<~(CRLF?)) ^^ { 
    case r~rs => r::rs
  }
  def record: Parser[List[String]] = (field~((COMMA~>field)*)) ^^ {
    case f~fs => f::fs
  }
  def field: Parser[String] = escaped|nonescaped
  def escaped: Parser[String] = (DQUOTE~>((TXT|COMMA|CR|LF|DQUOTE2)*)<~DQUOTE) ^^ { case …
Run Code Online (Sandbox Code Playgroud)

csv parsing scala parser-combinators

38
推荐指数
2
解决办法
1万
查看次数

解析器组合器可以提高效率吗?

大约6年前,我在OCaml中对自己的解析器组合器进行了基准测试,结果发现它们比当时提供的解析器生成器慢〜5倍.我最近重新审视了这个主题,并对Haskell的Parsec和一个用F#编写的简单的手动优先攀爬解析器进行了基准测试,并惊讶地发现F#比Haskell快25倍.

这是我用来从文件中读取大型数学表达式的Haskell代码,解析并评估它:

import Control.Applicative
import Text.Parsec hiding ((<|>))

expr = chainl1 term ((+) <$ char '+' <|> (-) <$ char '-')

term = chainl1 fact ((*) <$ char '*' <|> div <$ char '/')

fact = read <$> many1 digit <|> char '(' *> expr <* char ')'

eval :: String -> Int
eval = either (error . show) id . parse expr "" . filter (/= ' ')

main :: IO ()
main = do
    file <- …
Run Code Online (Sandbox Code Playgroud)

f# haskell parsec parser-generator parser-combinators

33
推荐指数
4
解决办法
6967
查看次数

Scala Parsers:可用性,差异和组合?

我的问题是关于Scala解析器:

  • 哪些可用(在标准库和外部),
  • 他们之间有什么区别,
  • 他们共享一个共同的API和
  • 可以组合不同的解析器来解析一个输入字符串吗?

我发现至少这些:

parsing scala parser-generator parser-combinators

25
推荐指数
4
解决办法
2642
查看次数

Scala解析器组合器与ANTLR/Java生成的解析器?

我正在为一个主要用Scala编写的应用程序编写表达式解析器.我在Scala中构建了AST对象,现在需要编写解析器.我听说过Scala的内置解析器组合器,以及ANTLR3,我想知道:哪个可以提供更好的性能和编写代码的简易性?至今:

ANTLR专业人士

  1. 知名
  2. 快速
  3. 外部DSL
  4. ANTLRWorks(用于解析器语法调试/测试的出色IDE)

ANTLR缺点

  1. 基于Java(Scala互操作可能具有挑战性,任何经验?)
  2. 在运行时需要很大的依赖关系

Parser combinator专业人士

  1. Scala的一部分
  2. 少一个构建步骤
  3. 不需要运行时依赖; 例如,已经包含在Scala的运行时库中

解析器组合器缺点

  1. 内部DSL(可能意味着执行速度较慢?)
  2. 没有ANTLRWorks(提供很好的解析器测试和可视化功能)

有什么想法吗?

编辑:此表达式解析器解析代数/微积分表达式.它将在最终确定的Android应用程序Magnificalc中使用.

java parsing scala parser-combinators antlr3

25
推荐指数
2
解决办法
5115
查看次数

Scala解析器组合器与Haskell的Parsec相比如何?

我已经读过Haskell解析器组合器(在Parsec中)可以解析上下文敏感语法.Scala解析器组合器也是如此吗?如果是这样,这就是"进入"(又名">>")功能的用途吗?

与Haskell相比,Scala实现解析器组合器有哪些优点/缺点?他们接受同一类语法吗?是否更容易生成错误消息或使用其中一个进行其他各种有用的事情?

packrat解析(在Scala 2.8中引入)如何适应这张图片?

是否有网页或其他资源显示一种语言的实现中不同的运算符/函数/ DSL-sugar如何映射到另一种语言?

parsing haskell scala parsec parser-combinators

22
推荐指数
2
解决办法
4453
查看次数

解析器组合器,分离语法和AST结构

我正在使用解析器 - 组合器库在Scala中编写一个简单的函数式编程语言.

语法在此处指定:https://github.com/hejfelix/Frase/blob/master/src/main/scala/it/vigtig/lambda/ParserLike.scala

有一件事我无法通过实现来解决:如何将语法定义与转换为AST节点分开?

直接在解析器源中使用接近人类可读的语法真的很酷,特别是考虑到我是项目ATM上唯一的程序员,它可以作为文档.

如何分离语法和AST特定代码?

grammar scala abstract-syntax-tree parser-combinators

22
推荐指数
1
解决办法
1117
查看次数

理解Scala解析器组合器中的波浪号

我是相当新的Scala和一边念叨解析器组合(魔术解析器组合的背后,在斯卡拉领域特定语言),我遇到的方法定义来是这样的:

def classPrefix = "class" ~ ID ~ "(" ~ formals ~ ")"
Run Code Online (Sandbox Code Playgroud)

我一直在阅读scala.util.parsing.Parsers的API文档,它定义了一个名为(代字号)的方法,但我仍然不能理解它在上面例子中的用法.在该示例中(代字号)是在java.lang.String上调用的方法,该方法没有该方法并导致编译器失败.我知道(代字号)被定义为

case class ~ [+a, +b] (_1: a, _2: b)
Run Code Online (Sandbox Code Playgroud)

但是这对上面的例子有什么帮助呢?

如果有人能给我一些提示来了解这里发生了什么,我会很高兴.非常感谢你提前!

一月

scala parser-combinators

21
推荐指数
2
解决办法
1万
查看次数

如何创建一个解析器组合器,其中行结尾很重要?

我正在创建一个DSL,并使用Scala的解析器组合库来解析DSL.DSL遵循简单的类似Ruby的语法.源文件可以包含一系列看起来像这样的块:

create_model do
  at 0,0,0
end
Run Code Online (Sandbox Code Playgroud)

线路结尾在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 …
Run Code Online (Sandbox Code Playgroud)

parsing scala parser-combinators

16
推荐指数
1
解决办法
4763
查看次数

Scala:如何组合来自不同对象的解析器组合器

给定一系列实现解析器组合器的对象,如何组合解析器?由于Parsers.Parser是一个内部类,并且在Scala 内部类中绑定到外部对象,故事变得有点复杂.

这是一个尝试组合来自不同对象的两个解析器的示例.

import scala.util.parsing.combinator._

class BinaryParser extends JavaTokenParsers {
  def anyrep: Parser[Any] = rep(any)
  def any: Parser[Any] = zero | one
  def zero: Parser[Any] = "0"
  def one: Parser[Any] = "1"
}

object LongChainParser extends BinaryParser {
  def parser1: Parser[Any] = zero~zero~one~one
}

object ShortChainParser extends BinaryParser {
  def parser2: Parser[Any] = zero~zero
}

object ExampleParser extends BinaryParser {
  def parser: Parser[Any] = (LongChainParser.parser1
    ||| ShortChainParser.parser2) ~ anyrep

  def main(args: Array[String]) {
    println(parseAll(parser, args(0) )) …
Run Code Online (Sandbox Code Playgroud)

parsing scala parser-combinators

16
推荐指数
1
解决办法
1696
查看次数