标签: parser-combinators

解析器组合器无法终止 - 如何记录正在发生的事情?

我正在尝试使用解析器组合器,我经常遇到无限递归.这是我遇到的第一个:

import util.parsing.combinator.Parsers
import util.parsing.input.CharSequenceReader

class CombinatorParserTest extends Parsers {

  type Elem = Char

  def notComma = elem("not comma", _ != ',')

  def notEndLine = elem("not end line", x => x != '\r' && x != '\n')

  def text = rep(notComma | notEndLine)

}

object CombinatorParserTest {

  def main(args:Array[String]): Unit = {
    val p = new CombinatorParserTest()
    val r = p.text(new CharSequenceReader(","))
    // does not get here
    println(r)
  }

}
Run Code Online (Sandbox Code Playgroud)

如何打印正在发生的事情?为什么没有完成?

scala parser-combinators

7
推荐指数
1
解决办法
1203
查看次数

如何在基于Scala解析器组合器的解析器中进一步改进错误消息?

我编写了一个基于Scala解析器组合器的解析器:

class SxmlParser extends RegexParsers with ImplicitConversions with PackratParsers {
    [...]
    lazy val document: PackratParser[AstNodeDocument] =
        ((procinst | element | comment | cdata | whitespace | text)*) ^^ {
            AstNodeDocument(_)
        }
    [...]
}
object SxmlParser {
    def parse(text: String): AstNodeDocument = {
        var ast = AstNodeDocument()
        val parser = new SxmlParser()
        val result = parser.parseAll(parser.document, new CharArrayReader(text.toArray))
        result match {
            case parser.Success(x, _) => ast = x
            case parser.NoSuccess(err, next) => {
                tool.die("failed to parse SXML input " +
                    "(line …
Run Code Online (Sandbox Code Playgroud)

error-handling scala parser-combinators

7
推荐指数
1
解决办法
2169
查看次数

将组合子解析器的列表/序列转换为单个

我有一个值列表,我可以从中构建一个解析器列表,它通过映射依赖于这些值(参见示例).那么我想要做的是通过连接将解析器列表转换为单个解析器.

一种可能性是使用foldLeft~:

parsers.foldLeft(success(Nil)){case (ps,p) => rs ~ p ^^ {case xs ~ x => x ::xs}} ^^ (_.reverse)
Run Code Online (Sandbox Code Playgroud)

这有效吗?

我不知道组合器解析器是如何工作的; 会有一个深度为列表长度的调用堆栈吗?因此,我可能会遇到SO错误很长时间的连接?

更好的方法

有不同的方式更具可读性吗?

假设您有一个包含两行的文件.第一行包含n个整数x_1到x_n.第二行包含根据第一行属于组的x_1 + x_2 + ... x_n整数.我想从第一行获取整数序列并创建n个解析器p_1到p_n,其中p_i解析x_i整数.

假设我有l = List(1,2,3)第一行的整数列表.对于每个整数,n我创建一个解析n整数的解析器:parsers = l.map(repN(_,integer)).

scala parser-combinators

7
推荐指数
1
解决办法
915
查看次数

Scala Parser组合器的运算符优先级

我正在研究一种需要考虑运算符优先级的解析逻辑.我的需求并不太复杂.首先,我需要乘法和除法,以获得比加法和减法更高的优先级.

例如:1 + 2*3应视为1 +(2*3).这是一个简单的例子,但你明白了!

[我还需要添加几个自定义令牌才能添加到优先级逻辑中,我可以根据我在此处收到的建议添加这些令牌.]

以下是处理运算符优先级的一个示例:http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html#precedencerevisited.

还有其他想法吗?

functional-programming scala parser-combinators

7
推荐指数
1
解决办法
2527
查看次数

使用scala解析器组合解析基于缩进的语言

有没有一种方便的方法来使用Scala的解析器组合器来解析缩进很重要的语言?(例如Python)

parsing scala indentation parser-combinators

7
推荐指数
1
解决办法
1068
查看次数

基于Agda论文在Idris中实现总分析器

我正在尝试使用Idris实现总解析器,基于本文.首先,我尝试实现更基本的识别器类型P:

Tok : Type
Tok = Char

mutual
  data P : Bool -> Type where
    fail : P False
    empty : P True
    sat : (Tok -> Bool) -> P False
    (<|>) : P n -> P m -> P (n || m)
    (.) : LazyP m n -> LazyP n m -> P (n && m)
    nonempty : P n -> P False
    cast : (n = m) -> P n -> P m

  LazyP …
Run Code Online (Sandbox Code Playgroud)

parsing parser-combinators agda dependent-type idris

7
推荐指数
1
解决办法
421
查看次数

使用Trifecta的布局解析器

我正在尝试使用Trifecta来解析一个非常简单的函数式语言,使用类似Haskell的布局语法.我正在处理Haddock文档和我对Parsec的经验,因为我找不到关于Trifecta本身的任何介绍性材料.

我遇到的问题是使用布局的东西,因为即使是Haddock文档也没有多大帮助.

给出以下代码:

import Text.Trifecta
import Text.Trifecta.Parser.Token.Style
import Text.Trifecta.Parser.Identifier.Style
import Text.Trifecta.Layout.Combinators
import Text.Trifecta.Language.Prim

import Control.Applicative
import Control.Monad.Trans
import Data.Maybe (fromMaybe)

import Data.HashSet as HashSet
import Data.ByteString.UTF8 as UTF8

-- Copypasta from Text.Trifecta.Parser.Identifier.Style
set :: [String] -> HashSet ByteString
set = HashSet.fromList . fmap UTF8.fromString

lang :: MonadParser m => LanguageDef m
lang = LanguageDef{ languageCommentStyle = haskellCommentStyle
                  , languageIdentifierStyle = emptyIdents{ styleReserved = set keywords }
                  , languageOperatorStyle = emptyOps{ styleReserved = set ops }
                  }
  where
    keywords = ["where"] …
Run Code Online (Sandbox Code Playgroud)

parsing haskell parser-combinators trifecta

6
推荐指数
1
解决办法
996
查看次数

在C中使用解析器组合器的更好方法?

我正在尝试从头启动C(的子集),而不使用额外的依赖项(解析器生成器,库等)。我也想利用解析器组合器的思想,这在函数式编程中是一种很棒的技术。我想以一种简洁实用的方式将这种想法从功能世界借鉴到过程C中。

我尝试为以下玩具语法实现一些必要的解析器组合器,这也是Simon Peyton Jones 的《实现功能语言-教程》一书中的示例。

greeting -> hg person "!"
hg       -> "hello"
          | "goodbye"
Run Code Online (Sandbox Code Playgroud)

person以字母开头的令牌在哪里?例如,令牌列表

["goodbye", "James", "!"]
Run Code Online (Sandbox Code Playgroud)

被解析为

[(("goodbye", "James"), ["!"])]
Run Code Online (Sandbox Code Playgroud)

(这本书使用了Haskell,很难使它与语言无关,但是您会明白的:-)

我用C语言实现了这一点,您可以在这里查看代码:https : //gist.github.com/4451478

此实现花费200多行C代码,远远超过本书中编写的约20行Haskell。因此,我不确定我是否在使用C进行解析器组合器方面是否正确,以及是否有任何可能的改进。任何建议都欢迎。提前致谢。

c compiler-construction parsing parser-combinators

6
推荐指数
2
解决办法
2870
查看次数

Trifecta中的自定义状态

我正在使用Trifecta解析器组合库,我的解析器输出AST数据类型的实例.我希望每个实例都有唯一的ID(简单的Int).

在Parsec中,我会创建自定义状态并在neccesery时递增ID.我们怎样才能在Trifecta中做到这一点?

monads parsing haskell parser-combinators trifecta

6
推荐指数
1
解决办法
393
查看次数

何时使用scala triple caret(^^^)vs双插入符号(^^)和into方法(>>)

在设计scala解析器组合器时,有人可以解释如何以及何时使用三重插入符^^^(与双插入符^^)?以及何时/如何使用parser.into()方法(>>).

scala parser-combinators

6
推荐指数
1
解决办法
1824
查看次数