标签: parser-combinators

如何在Scala的解析器组合结果上进行模式匹配

我们有一个多线程RPC服务器来解析输入字符串.我们碰到的地方Scala的解析器组合库不是多线程安全的问题:在var lastNoSuccess Parsers.scala用于任何解析.我们在这一行中得到一个NullPointerException

if (!(lastNoSuccess != null && next.pos < lastNoSuccess.next.pos))
Run Code Online (Sandbox Code Playgroud)

通过创建扩展其中一个解析器的对象来实现解析器的默认方式,但是我想按需构造解析器,因此每个解析器都有自己的内部状态,因此我使用的是类而不是对象.但是,由于我需要对结果进行模式匹配,因此我无法编译它:

import scala.util.parsing.combinator.RegexParsers

class SqlParserImpl
  extends RegexParsers
{
  val term: Parser[String] = """(?i)term\b""".r
}

object Test
{
  def main(args: Array[String]): Unit =
  {
    val parser = new SqlParserImpl
    parser.parseAll(parser.term, "term") match {
      // How do I match?
      case SqlParserImpl#Success(result, _) => true
      case SqlParserImpl#NoSuccess => false
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

失败了

t.scala:16: error: '=>' expected but '#' found.
          case SqlParserImpl#Success(result, _) => true
                            ^
t.scala:17: error: '=>' expected but …
Run Code Online (Sandbox Code Playgroud)

scala parser-combinators

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

Scala组合器解析器,>>什么意思?

我对scala中的">>"有点困惑.Daniel在解析xml的Scala解析器组合器中说道它可以用于根据先前解析器的结果参数化解析器.有人可以给我一些例子/提示吗?我已经读过scaladoc但仍然不理解它.

谢谢

parsing scala parser-combinators

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

使用 nom 捕获整个连续匹配的输入

我希望应用一系列nom解析器并返回&str匹配的完整内容。我想匹配表单的字符串a+bc+。使用现有的chain!宏,我可以非常接近:

named!(aaabccc <&[u8], &str>,
   map_res!(
       chain!(
           a: take_while!(is_a) ~
               tag!("b") ~
               take_while!(is_c) ,
           || {a}
           ),
       from_utf8
   ));
Run Code Online (Sandbox Code Playgroud)

在哪里

fn is_a(l: u8) -> bool {
   match l {
       b'a' => true,
       _ => false,
   }
}

fn is_c(l: u8) -> bool {
    match l {
        b'c' => true,
        _ => false,
    }
}
Run Code Online (Sandbox Code Playgroud)

假设我们有 'aaabccc' 作为输入。上面的解析器将匹配输入,但只会返回“aaa”。我想做的是返回原始输入“aaabccc”。

chain!不是正确的宏,但没有另一个看起来更正确的宏。最好的方法是什么?


在撰写本文时,我正在使用 nom1.2.2和 rustc 1.9.0-nightly (a1e29daf1 2016-03-25)

parser-combinators rust

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

FParsec:如何从错误消息中忽略“很多”解析器故障

考虑以下将数字字符串转换为ints的解析器:

let toInt (s:string) = 
    match Int32.TryParse(s) with
    | (true, n) -> preturn n
    | _         -> fail "Number must be below 2147483648"

let naturalNum = many1Chars digit >>= toInt <?> "natural number"
Run Code Online (Sandbox Code Playgroud)

当我在非数字字符串上运行它时,"abc"它显示正确的错误消息:

let toInt (s:string) = 
    match Int32.TryParse(s) with
    | (true, n) -> preturn n
    | _         -> fail "Number must be below 2147483648"

let naturalNum = many1Chars digit >>= toInt <?> "natural number"
Run Code Online (Sandbox Code Playgroud)

但是,当我给它一个超出int范围的数字字符串时,它会给出以下适得其反的信息:

Error in Ln: 1 Col: 1
abc …
Run Code Online (Sandbox Code Playgroud)

f# parser-combinators fparsec

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

如果 attoparsec 回溯,为什么它需要 manyTill?

考虑使用这些不同的解析器组合器。

import Control.Applicative.Combinators
import Text.Regex.Applicative
 
main :: IO ()
main = do
  let parser1 = sym '"' *> manyTill anySym (sym '"')
  print $ match parser1 "\"abc\""
  let parser2 = sym '"' *> many anySym <* sym '"'
  print $ match parser2 "\"abc\""
Run Code Online (Sandbox Code Playgroud)
import Control.Applicative.Combinators            
import Text.ParserCombinators.ReadP hiding(many, manyTill)
 
main :: IO ()
main = do
  let parser1 = char '"' *> manyTill get (char '"')
  print $ readP_to_S parser1 "\"abc\""
  let parser2 = char '"' *> many get <* …
Run Code Online (Sandbox Code Playgroud)

parsing haskell backtracking parser-combinators attoparsec

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

haskell解析器组合器无限循环

我试图通过 Haskell 编写一个简单的解析器,但陷入了无限循环。代码是:

import Control.Applicative (Alternative, empty, many, (<|>))

data Parser a = Parser {runParser :: String -> [(a, String)]}

instance Functor Parser where
  fmap f (Parser p) = Parser $ \s -> [(f x', s') | (x', s') <- p s]

instance Applicative Parser where
  pure x = Parser $ \s -> [(x, s)]
  (Parser pf) <*> (Parser p) = Parser $ \s -> [(f' x, ss') | (f', ss) <- pf s, (x, ss') <- p ss]

instance …
Run Code Online (Sandbox Code Playgroud)

haskell parser-combinators

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

如何使用解析器组合器进行条件检查

我试图编写一个简单的html模板引擎(为了好玩),并想解析这样的结构

A.正常行是HTML

B.如果一行开头,$则将其视为java代码行

$ if (isSuper) {
    <span>Are you wearing red underwear?</span>
$ }
Run Code Online (Sandbox Code Playgroud)

C.如果${}包装多行,其中的所有代码都应该是java代码.

D.如果一行开头$include然后在线上做一些技巧(调用另一个模板)

$include anotherTemplate(id, name)
Run Code Online (Sandbox Code Playgroud)

这将创建一个新实例anotherTemplate,并调用它的render()方法

E.和将有更多的"命令"比其他$include,例如$def,$val.

如何在解析器组合器中表达这一点?实际上它是一个条件分叉

对于1.和2.,我有这样的事情:

'$' ~> ( '{' ~> upto('}') <~ '}' |  not('{') <~ newline )
Run Code Online (Sandbox Code Playgroud)

其中,upto从Scalate的Scamel解析器借来的(我刚开始读,不是很了解)

我曾经not('{')$....代码行与${...}块区分开来.但这很麻烦,不会扩展到其他"命令"

那我该怎么办呢?

scala parser-combinators

4
推荐指数
1
解决办法
370
查看次数

FParsec标识符与关键字

对于具有关键字的语言,需要一些特殊的技巧来防止例如"if"被解释为标识符,并且"ifSomeVariableName"变为关键字"if",后跟标识符流中的标识符"SomeVariableName".

对于递归下降和Lex/Yacc,我简单地采用了在词法分析器和解析器之间转换令牌流的方法(根据有用的指令).

然而,FParsec似乎并没有真正做一个单独的词法分析步骤,所以我想知道处理这个问题的最佳方法是什么.说到,似乎Haskell的Parsec支持lexer层,但FParsec不支持?

f# parser-combinators fparsec

4
推荐指数
1
解决办法
836
查看次数

将解析器组合器应用于案例类

我正在使用Scala的Parser Combinators来解析一个字符串(没有新行,人为的例子).

字符串由许多不同的部分组成,我想分别提取并填充案例类.

case class MyRecord(foo: String, bar: String, baz: String, bam: String, bat: String)

object MyParser extends scala.util.parsing.combinator.RegexParsers {

  val foo: Parser[String] = "foo"
  val bar: Parser[String] = "bar"
  val baz: Parser[String] = "baz"
  val bam: Parser[String] = "bam"
  val bat: Parser[String] = "bat"

  val expression: Parser[MyRecord] =
    foo ~ bar ~ baz ~ bam ~ bat ^^ {
      case foo ~ bar ~ baz ~ bam ~ bat => MyRecord(foo, bar, baz, bam, bat)
    }

} …
Run Code Online (Sandbox Code Playgroud)

scala parser-combinators

4
推荐指数
1
解决办法
210
查看次数

据报道,简单表达式在解析器组合器中是递归的

猜猜这个编译的结果是什么?

import scala.util.parsing.combinator._

object ExprParser extends JavaTokenParsers {
    lazy val literal = int  
    lazy val int = rep("0")
}
Run Code Online (Sandbox Code Playgroud)

编译器说这int是递归的并要求它的类型.我的实验说,递归的核心隐藏在文字的声明中!删除它,你会看到递归消失了!

recursion overriding scala overloading parser-combinators

4
推荐指数
1
解决办法
114
查看次数