标签: uu-parsinglib

Parsec或happy(使用alex)或uu-parsinglib

我将编写一个verilog(或vhdl)语言的解析器,并将对解析数据进行大量操作(某种转换).我打算解析真正的大文件(完整的Verilog设计,大到10K行),我最终会支持大部分的Verilog.我不介意输入,但每当我添加对其他规则的支持时,我不想重写代码的任何部分.

在Haskell,你会推荐哪个图书馆?我知道Haskell并且之前使用过Happy(玩).我觉得有可能使用Parsec来转换代码中的解析字符串(这是一个很好的加分).我没有使用uu-paringlib的经验.

那么要解析verilog/VHDL的全语法,推荐其中一个?我主要担心的是我可以随心所欲地操纵解析数据的简易性和"正确性".速度不是主要问题.

parsing haskell parsec happy uu-parsinglib

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

uu-parsinglib的性能与Parsec中的"try"相比

我知道Parsec,uu-parsinglib而且我在两者中都编写过解析器.最近我发现,存在一个问题uu-parsinglib,可能会对其性能产生重大影响,我看不到解决问题的方法.

让我们考虑遵循Parsec解析器:

pa = char 'a'
pb = char 'b'
pTest = many $ try(pa <* pb)
Run Code Online (Sandbox Code Playgroud)

相当于uu-parsinglib什么?它不会是以下内容:

pa = pSym 'a'
pb = pSym 'b'
pTest = pList_ng (pa <* pb)
Run Code Online (Sandbox Code Playgroud)

所不同的是,在Parsec,many会吃(pa <* pb)(对"ab")贪婪,直到它不再匹配,而在uu-parsinglib,pList_ng不贪心,所以每次分析后,将保留在内存中可能原路返回的方式(pa <* pb).

有没有办法写出类似pList(try(pa <* pb))的内容uu-parsinglib

一个很好的例子

pExample = pTest <* (pa <* pb)
Run Code Online (Sandbox Code Playgroud)

和一个样本输入"ababab" …

performance parsing haskell parsec uu-parsinglib

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

正确解析Haskell中uu-parsinglib中的行缩进

我想创建一个解析器组合器,它将收集当前位置以下的所有行,这些缩进级别将大于或等于某些i.我认为这个想法很简单:

消耗一条线 - 如果它的缩进是:

  • 好的 - >为下一行做
  • 错 - >失败

让我们考虑以下代码:

import qualified Text.ParserCombinators.UU as UU
import           Text.ParserCombinators.UU hiding(parse)
import           Text.ParserCombinators.UU.BasicInstances hiding (Parser)

-- end of line
pEOL   = pSym '\n'

pSpace = pSym ' '
pTab   = pSym '\t'

indentOf s = case s of
    ' '  -> 1
    '\t' -> 4

-- return the indentation level (number of spaces on the beginning of the line)
pIndent = (+) <$> (indentOf <$> (pSpace <|> pTab)) <*> pIndent …
Run Code Online (Sandbox Code Playgroud)

parsing haskell parsec uu-parsinglib

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

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

使用解析器组合器解析具有函数应用程序的表达式语法(左递归)

作为真实语言解析器的简化子问题,我试图为虚构语言的表达式实现一个解析器,它看起来类似于标准命令式语言(如Python,JavaScript等).其语法具有以下构造:

  • 整数
  • 标识符([a-zA-Z]+)
  • +*和括号的算术表达式
  • 结构访问.(例如foo.bar.buz)
  • 元组(例如(1, foo, bar.buz))(删除歧义一元组写成(x,))
  • 功能应用(例如foo(1, bar, buz()))
  • 函数是第一类的,因此它们也可以从其他函数返回并直接应用(例如foo()(),因为foo()可能返回函数是合法的)

所以这个语言中的一个相当复杂的程序是

(1+2*3, f(4,5,6)(bar) + qux.quux()().quuux)
Run Code Online (Sandbox Code Playgroud)

相关性应该是

( (1+(2*3)), ( ((f(4,5,6))(bar)) + ((((qux.quux)())()).quuux) ) )
Run Code Online (Sandbox Code Playgroud)

我目前正在使用非常好的uu-parsinglib应用解析器组合器库.

第一个问题显然是直观的表达式语法(expr -> identifier | number | expr * expr | expr + expr | (expr)左递归.但我可以使用pChainl组合器解决这个问题(参见parseExpr下面的例子).

剩下的问题(因此这个问题)是函数应用程序,其函数返回其他函数(f()()).同样,语法是递归的expr -> fun-call | ...; fun-call -> …

parsing haskell parsec recursive-descent uu-parsinglib

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

无法计算解析器的最小长度 - 在Haskell中使用uu-parsinglib

让我们看看代码片段:

pSegmentBegin p i   = pIndentExact i *> ((:) <$> p i <*> ((pEOL *> pSegment p i) <|> pure []))
Run Code Online (Sandbox Code Playgroud)

如果我在我的解析器中将此代码更改为:

pSegmentBegin p i   = do
    pIndentExact i
    ((:) <$> p i <*> ((pEOL *> pSegment p i) <|> pure []))
Run Code Online (Sandbox Code Playgroud)

我有一个错误:

canot compute minmal length of a parser due to occurrence of a moadic bind, use addLength to override
Run Code Online (Sandbox Code Playgroud)

我认为上面的解析器应该以相同的方式运行.为什么会出现此错误?

编辑

上面的例子很简单(为了简化问题),如下所述,这里没有必要使用do notation,但我希望它使用的实际情况如下:

pSegmentBegin p i   = do
    j <- pIndentAtLast i
    (:) <$> p j <*> ((pEOL …
Run Code Online (Sandbox Code Playgroud)

parsing haskell parsec parser-combinators uu-parsinglib

5
推荐指数
2
解决办法
344
查看次数