标签: parser-combinators

使用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
查看次数

uu-parsinglib中的计划外贪婪行为

问题

我今天遇到了一个问题,我不知道如何解决它.这对我来说很奇怪,因为我写的代码应该(根据我目前的知识)是正确的.

所以下面你可以找到一个示例解析器组合器.最重要的是pOperator,它以非常简单的方式(仅用于演示目的)构建运算符AST.它消耗"x"并且可以消耗由空格分隔的多个"x".

我也有pParenscombinator,定义如下:

pPacked pParenL (pWSpaces *> pParenR)
Run Code Online (Sandbox Code Playgroud)

所以它在关闭括号之前消耗空格.

样本输入/输出

正确的输入/输出应该是:

in: "(x)"
out: Single "x"

in: "(x )"
out: Single "x"
Run Code Online (Sandbox Code Playgroud)

但我得到了:

in: "(x)"
out: Single "x"

in: "(x )" 
out: Multi (Single "x") (Single "x")
--  Correcting steps: 
--    Inserted  'x' at position LineColPos 0 3 3 expecting one of ['\t', ' ', 'x']
Run Code Online (Sandbox Code Playgroud)

但是在第二个例子中我得到了错误 - 解析器的行为就像它贪婪地吃了一些令牌(而且没有贪婪的操作).

我会感谢任何帮助.

示例代码

import Prelude hiding(lex)
import Data.Char hiding (Space)
import qualified Text.ParserCombinators.UU as UU
import           Text.ParserCombinators.UU …
Run Code Online (Sandbox Code Playgroud)

parsing haskell parsec parser-combinators uu-parsinglib

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

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
查看次数

只需在python中使用parsec

我正在看这个图书馆,那里没有多少文档:https : //pythonhosted.org/parsec/#examples

知道还有其他选择,但我想使用这个库。

我想解析以下字符串:

mystr = """
<kv>
  key1: "string"
  key2: 1.00005
  key3: [1,2,3]
</kv>
<csv>
date,windspeed,direction
20190805,22,NNW
20190805,23,NW
20190805,20,NE
</csv>"""
Run Code Online (Sandbox Code Playgroud)

虽然我想解析整个事情,但我只想抓住<tags>。我有:

>>> import parsec
>>> tag_start = parsec.Parser(lambda x: x == "<")
>>> tag_end = parsec.Parser(lambda x: x == ">")
>>> tag_name = parsec.Parser(parsec.Parser.compose(parsec.many1, parsec.letter))
>>> tag_open = parsec.Parser(parsec.Parser.joint(tag_start, tag_name, tag_end))
Run Code Online (Sandbox Code Playgroud)

好,看起来不错 现在使用它:

>>> tag_open.parse(mystr)
Traceback (most recent call last):
...
TypeError: <lambda>() takes 1 positional argument but 2 were given
Run Code Online (Sandbox Code Playgroud)

这失败了。恐怕我什至不明白我的lambda表达式给出两个参数的含义,这很明显是1.如何进行?

对于所有奖励积分,我的最佳期望输出是: …

python parsec parser-combinators

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

使用解析器组合器解析简单的数学表达式

parsimmon用来解析一个简单的数学表达式,但我无法解析一个遵循操作顺序的简单数学表达式(即*/优先级高于+-)。

即使你不熟悉这个库,也请帮助我解决没有左递归和无限递归的优先级问题。

谢谢你。

我使用了打字稿:

"use strict";

// Run me with Node to see my output!

import * as P from "parsimmon";
import {Parser} from "parsimmon";
// @ts-ignore
import util from "util";


///////////////////////////////////////////////////////////////////////

// Use the JSON standard's definition of whitespace rather than Parsimmon's.
let whitespace = P.regexp(/\s*/m);

// JSON is pretty relaxed about whitespace, so let's make it easy to ignore
// after most text.
function token(parser: Parser<string>) {
  return parser.skip(whitespace);
}

// Several …
Run Code Online (Sandbox Code Playgroud)

javascript parser-combinators typescript

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

不区分大小写的Scala解析器 - 组合子

我正在尝试创建一种语言,并且我希望它的一些部分不区分大小写.我确信这很容易,但我找不到它.

编辑:重新阅读让我为这个问题感到羞耻.是一个失败的测试,解释了我的意思.

parsing scala parser-combinators

5
推荐指数
1
解决办法
1247
查看次数

Scala Parser Combinators:有效解析C风格的评论

/* ... */使用Scala解析器组合器(有效)解析C风格的多行注释(即)的最佳方法是什么?

在我参与的项目中,我们解析了类似C语言的编程语言,并希望支持多行注释.我们使用的子类StandardTokenParsers已经处理了这样的注释(通过StdLexical.但是,该类仅适用于相当短的多行注释,否则会耗尽堆栈空间.

我们还尝试提供我们自己的空白定义,以提高效率.我们使用了RegexParser(受StackOverflow上另一个问题的启发)如下:

class Parser extends StandardTokenParsers {

  override val lexical = new StdLexical {
    def rp: RegexParsers = new RegexParsers {}
    override val whitespace: Parser[Any] = rp.regex("""(\s|//.*|(?m)/\*(\*(?!/)|[^*])*\*/)*""".r).asInstanceOf[Parser[Any]]
  }

  // ...

}
Run Code Online (Sandbox Code Playgroud)

这略微改善了这种情况,但如果评论超过几十行,仍会导致堆栈溢出.任何想法如何改善这个?

scala parser-combinators

5
推荐指数
1
解决办法
818
查看次数

在scala combinatorparser中访问位置信息会导致性能下降

我在scala中为我的解析器编写了一个新的组合子.

它是^^组合子的变体,它传递位置信息.但访问输入元素的位置信息确实是性价比.

在我的情况下,解析一个大的例子需要大约3秒没有位置信息,它需要超过30秒.

我编写了一个可运行的示例,其中运行时在访问位置时大约多50%.

这是为什么?我怎样才能获得更好的运行时间?

例:

import scala.util.parsing.combinator.RegexParsers
import scala.util.parsing.combinator.Parsers
import scala.util.matching.Regex
import scala.language.implicitConversions
object FooParser extends RegexParsers with Parsers {
  var withPosInfo = false
  def b: Parser[String] = regexB("""[a-z]+""".r)  ^^@ { case (b, x) => b + " ::" + x.toString }
  def regexB(p: Regex): BParser[String] = new BParser(regex(p))
  class BParser[T](p: Parser[T]) {
    def ^^@[U](f: ((Int, Int), T) => U): Parser[U] = Parser { in =>
      val source = in.source
      val offset = in.offset
      val start = handleWhiteSpace(source, offset) …
Run Code Online (Sandbox Code Playgroud)

performance parsing scala parser-combinators

5
推荐指数
1
解决办法
787
查看次数