标签: parser-combinators

翻译scala StdLexical的新行?

我正在尝试lex(然后解析)一个C语言.在C中有预处理器指令,其中换行符很重要,然后是实际代码,它们只是空格.

执行此操作的一种方法是执行像早期C编译器这样的双通过程 - 为#指令设置单独的预处理器,然后将其输出调整为lex.

但是,我想知道是否可以在一个词法分析器中完成它.我很高兴编写scala解析器 - 组合器代码,但我不太确定如何StdLexical处理空格.

有人可以写一些简单的示例代码,这些代码可以说是#include一行(使用换行符)和一些简单的代码(忽略换行符)?或者这是不可能的,最好选择2-pass appproach?

scala newline lexer parser-combinators

3
推荐指数
1
解决办法
607
查看次数

Scala Parser,为什么不"轻拍<~pat~> pat"工作?

试用一个简单的解析器组合器,我遇到了编译错误.

我想解析一下 - "Smith,Joe"进入Name对象,如Name(Joe,Smith).我想这很简单.

这是与之相关的代码:

    import util.parsing.combinator._

    class NameParser extends JavaTokenParsers {
      lazy val name: Parser[Name] = 
        lastName <~ "," ~> firstName ^^ {case (l ~ f) => Name(f, l)}
      lazy val lastName = stringLiteral
      lazy val firstName = stringLiteral
    }

    case class Name(firstName:String, lastName: String)
Run Code Online (Sandbox Code Playgroud)

我正在测试它

object NameParserTest {
  def main(args: Array[String]) {
    val parser = new NameParser()
    println(parser.parseAll(parser.name, "Schmo, Joe"))
  }
}
Run Code Online (Sandbox Code Playgroud)

获取编译错误:

error: constructor cannot be instantiated to expected type;
found   : NameParser.this.~[a,b]
required: java.lang.String
lazy val …
Run Code Online (Sandbox Code Playgroud)

scala parser-combinators

3
推荐指数
2
解决办法
608
查看次数

使用scala中的解析器组合器逐步评估

我刚学习Scala解析器组合库.我已经尝试了一个工作解析器,它使用抽象语法树解析一些算术表达式.所以我打电话的时候

phrase(expr)(tokens)
Run Code Online (Sandbox Code Playgroud)

我的解析器解析所有输入然后给我一个评估.但是我怎么能逐步评估呢?

3 + 4*7

它打印

3 + 28

然后

31

在单独的行中.

我已经扫描了api,但那里的文档并不是很有帮助...感谢您的帮助.

parsing scala parser-combinators

3
推荐指数
1
解决办法
1160
查看次数

深入扩展Parser库的方法

我发现的解析器组合器的材料包括构建复杂的解析器虽然组合,但我想知道是否有任何好的方法来通过调整库的组合解析器来定义解析器而不完全复制原始库的逻辑.

例如,这是在Real world Haskell中定义的简化CSV解析器

import Text.ParserCombinators.Parsec

csvFile = endBy line eol
line = sepBy cell (char ',')
cell = many (noneOf ",\n")
eol = char '\n'
Run Code Online (Sandbox Code Playgroud)

假设csvFile在一个库中定义,另一个库是否可以使用自定义版本的cell解析器创建自己的CSV解析器,而不必重写linecsvFile解析器?可以重写源库以使其成为可能吗?这对于CSV解析器来说非常简单,但我对广泛适用的解决方案感兴趣.

parsing haskell functional-programming parser-combinators

3
推荐指数
1
解决办法
83
查看次数

如何使用FastParse准确匹配'n'给定的字符

FastParse解析器组合子Scala库给你的.rep(n)"重复"的方法,让您创建一个新的解析器,试图解析givenParser n 或更多次.如果我想完全 n匹配,那么规范的方法是什么?

在我的情况下,我想解析一个40个字符的Git提交ID - 如果它超过40个字符,那不是一个提交ID,它不应该是匹配.

到目前为止,我在docs中找到的最接近的例子是:

val unicodeEscape = P( "u" ~ hexDigit ~ hexDigit ~ hexDigit ~ hexDigit )
Run Code Online (Sandbox Code Playgroud)

...通过简单的重复匹配4个字符(40个字符的提交ID详细).

这些是解析器组合器,而不是正则表达式,答案就是这样的\p{XDigit}{40}.

scala parser-combinators fastparse

3
推荐指数
1
解决办法
417
查看次数

我怎么能写一个更通用(但有效)的attoparsec版本的takeWhile1?

Data.Attoparsec.Text出口takeWhiletakeWhile1:

takeWhile :: (Char -> Bool) -> Parser Text
Run Code Online (Sandbox Code Playgroud)

只要谓词返回True就消耗输入,并返回消耗的输入.

此解析器不会失败.如果谓词False在输入的第一个字符上返回,它将返回一个空字符串.

[...]

takeWhile1 :: (Char -> Bool) -> Parser Text
Run Code Online (Sandbox Code Playgroud)

只要谓词返回True就消耗输入,并返回消耗的输入.

此解析器要求谓词在至少一个输入字符上成功:如果谓词永不返回True或者没有输入,则它将失败.

attoparsec的文档鼓励用户

Text尽可能使用面向对象的解析器,例如takeWhile1代替many1 anyChar.两种解析器之间的性能差异大约为100倍.

这两个解析器非常有用,但我一直觉得需要更通用的版本takeWhile1,更具体地说,是一些假设的解析器

takeWhileLo :: (Char -> Bool) -> Int -> Parser Text
takeWhileLo f lo = undefined
Run Code Online (Sandbox Code Playgroud)

这将解析至少 lo满足谓词的字符f,其中lo是任意非负整数.

我看了一下它takeWhile1的实现,但是它使用了一堆私有的函数,Data.Attoparsec.Text.Internal并且似乎不易泛化.

我想出了以下应用实现:

{-# LANGUAGE OverloadedStrings …
Run Code Online (Sandbox Code Playgroud)

haskell parser-combinators attoparsec

3
推荐指数
1
解决办法
130
查看次数

使用scala-parser-combinators进行递归定义

我一直在尝试使用scala-parser-combinator库构建一个SQL解析器,我已将其大大简化为以下代码。

class Expression
case class FalseExpr() extends Expression
case class TrueExpr() extends Expression
case class AndExpression(expr1: Expression, expr2: Expression) extends Expression

object SimpleSqlParser {
  def parse(sql: String): Try[Expression] = new SimpleSqlParser().parse(sql)
}

class SimpleSqlParser extends RegexParsers {
  def parse(sql: String): Try[_ <: Expression] = parseAll(expression, sql) match {
    case Success(matched,_) => scala.util.Success(matched)
    case Failure(msg,remaining) => scala.util.Failure(new Exception("Parser failed: "+msg + "remaining: "+ remaining.source.toString.drop(remaining.offset)))
    case Error(msg,_) => scala.util.Failure(new Exception(msg))
  }

  private def expression: Parser[_ <: Expression] =
    andExpr | falseExpr | …
Run Code Online (Sandbox Code Playgroud)

scala parser-combinators left-recursion

3
推荐指数
1
解决办法
851
查看次数

Text.Regex.Applicative-多行注释

我无法弄清楚使用Haskell regex-applicative软件包使用该replace功能对多行注释执行替换的正确方法。首先,我试图match返回正确的字符串作为测试:

regex = pure (++) <$> string "/*" <*> many (anySym) <*> string "*/"
match regex "/* hello world */"
Run Code Online (Sandbox Code Playgroud)

哪个返回hello world */。我不明白为什么第一个匹配部分被切除。有任何想法吗?

regex haskell parser-combinators applicative

3
推荐指数
1
解决办法
93
查看次数

用于嵌入在html或文本中的语言的Scala解析器组合器(如php)

我一直在玩Scala解析器组合器已经有一段时间了,并且学习了一些方法来使它表现得很好并且使用内置函数完成我想要的大部分工作.

但是你如何制作嵌入式语言(如php或ruby的erb)?在嵌入真实代码之外,它要求不要忽略空格.

我设法创建一个简单的解析器,匹配所有文本,直到给定的正则表达式匹配,但我正在寻找一个更好,更漂亮的方法来做到这一点.可能有一些已定义的功能可以完成所需的工作.

测试语言解析文本,如:

now: [[ millis; ]]
and now: [[; millis; ]]
Run Code Online (Sandbox Code Playgroud)

并由以下代码生成:

package test

import scala.util.parsing.combinator.RegexParsers
import scala.util.matching.Regex

sealed abstract class Statement
case class Print(s: String) extends Statement
case class Millis() extends Statement

object SimpleLang extends RegexParsers {

  def until(r: Regex): Parser[String] = new Parser[String]{
    def apply(in: Input) = {
      val source = in.source
      val offset = in.offset
      val start = offset
      (r.findFirstMatchIn( source.subSequence(offset, source.length) )) match {
        case Some(matched) => 
          Success(source.subSequence(offset, offset + matched.start).toString, in.drop(matched.start))
        case None …
Run Code Online (Sandbox Code Playgroud)

scala embedded-language parser-combinators

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

使用解析器组合器来整理文本行

我正在尝试使用解析器组合器解析文本文件.我想捕获一个名为的类中的索引和文本Example.这是一个测试,显示输入文件中的表单:

object Test extends ParsComb with App {
  val input = """
0)
blah1
blah2
blah3
1)
blah4
blah5
END
"""
  println(parseAll(examples, input))
}
Run Code Online (Sandbox Code Playgroud)

这是我的尝试不起作用:

import scala.util.parsing.combinator.RegexParsers

case class Example(index: Int, text: String)

class ParsComb extends RegexParsers {
  def examples: Parser[List[Example]] = rep(divider~example) ^^ 
                                          {_ map {case d ~ e => Example(d,e)}}
  def divider:  Parser[Int]           = "[0-9]+".r <~ ")"    ^^ (_.toInt)
  def example:  Parser[String]        = ".*".r <~ (divider | "END") 
}
Run Code Online (Sandbox Code Playgroud)

它失败了:

[4.1] failure: `END' expected but `b' …
Run Code Online (Sandbox Code Playgroud)

regex scala parser-combinators

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