由于这是我的第一篇文章,我想借此机会说:这是一个多么伟大的网站!
无论如何,对于这个问题:
我有点像Scala新手,我正在尝试用Scala中的解析器组合器解决数据提取和解析问题,我得到了java.lang.StackOverflowError异常.
我的真实世界的例子太大了,所以我没有重复使用来自另一个SO问题的代码同样的问题.虽然代码略有修改.我尝试使用PackratParsers解决问题,但没有成功.
import scala.util.parsing.combinator.syntactical.StandardTokenParsers
import scala.util.parsing.combinator.PackratParsers
object ArithmeticParser1 extends StandardTokenParsers with PackratParsers {
lexical.delimiters ++= List("(", ")", "+", "-", "*", "/")
lazy val reduceList: Int ~ List[String ~ Int] => Int = {
case i ~ ps => (i /: ps)(reduce)
}
def reduce(x: Int, r: String ~ Int) = (r: @unchecked) match {
case "+" ~ y => x + y
case "-" ~ y => x - y
case "*" ~ y => x …Run Code Online (Sandbox Code Playgroud) stack-overflow parsing scala text-parsing parser-combinators
我正在尝试使用nom来解析基于文本的协议.此协议可以具有以下形式的浮点值:
[-]digit+[.digit+]
Run Code Online (Sandbox Code Playgroud)
其中的例子是:
我构建的nom解析器是为了识别这个......不漂亮.它也不太明显.到目前为止我得到了什么:
named!(float_prs <&[u8], f64>,
alt!(
take_while!(nom::is_digit) => {|x| FromStr::from_str(std::str::from_utf8(x).unwrap()).unwrap()} |
recognize!(chain!(
take_while!(nom::is_digit) ~
tag!(".") ~
take_while!(nom::is_digit),
|| {})
) => {|x: &[u8]| FromStr::from_str(std::str::from_utf8(x).unwrap()).unwrap() }
)
);
Run Code Online (Sandbox Code Playgroud)
第一个替代解析器识别digit+,第二个是尝试识别digit+.digit+但是
<nom macros>:5:38: 5:62 error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
<nom macros>:5 let index = ( $ i ) . offset ( i ) ; $ crate:: IResult:: Done (
Run Code Online (Sandbox Code Playgroud)
-digit …
在以下Parsers/Trifecta示例中,应该正确使用什么而不是失败?
parserNaturalNoLeadZero :: Parser Integer
parserNaturalNoLeadZero = do
digits <- some digit
if length digits > 1 && head digits == '0'
then fail "Leading Zeros"
else return $ read digits
Run Code Online (Sandbox Code Playgroud) 编译器不接受将元组直接传递给构造函数,如最小示例所示:
scala> case class A(a:Int, b:Int)
defined class A
scala> List((1, 2)).map(A)
<console>:14: error: type mismatch;
found : A.type
required: ((Int, Int)) => ?
List((1, 2)).map(A)
^
scala> List((1, 2)).map(A _)
<console>:14: error: _ must follow method; cannot follow A.type
List((1, 2)).map(A _)
^
Run Code Online (Sandbox Code Playgroud)
Scala 解析器组合器具有^^用于此的运算符。fastparse 库中有类似的东西吗?
我试图让这个工作:
def emptyCond: Parser[Cond] = ("if" ~ "(") ~> regularStr <~ ")" ^^ { case s => Cond("",Nil,Nil) }
Run Code Online (Sandbox Code Playgroud)
其中regularStr被定义为接受许多东西,包括")".当然,我希望这是一个可接受的输入:if(foo()).但对于任何if(x),它将")"作为regularStr的一部分,因此这个解析器永远不会成功.
我错过了什么?
编辑:
regularStr不是正则表达式.它定义如下:
def regularStr = rep(ident | numericLit | decimalLit | stringLit | stmtSymbol) ^^ { case s => s.mkString(" ") }
Run Code Online (Sandbox Code Playgroud)
符号是:
val stmtSymbol = "*" | "&" | "." | "::" | "(" | ")" | "*" | ">=" | "<=" | "=" |
"<" | ">" | …Run Code Online (Sandbox Code Playgroud) 我想在文本中搜索字符串"W foo X bar Y baz Z".W,X,Y,Z是不重要的分隔符,我不能搜索它们.foo,bar和baz是我感兴趣的词.订单并不重要.我想知道文本中出现的所需词语"好".
我正在尝试以下方面
(?:\Qfoo\E)?.{0,3}(?:\Qbar\E)?.{0,3}(?:\Qbaz\E)?
Run Code Online (Sandbox Code Playgroud)
我的理由是:
此正则表达式始终匹配,因为它只包含可选组,但结果匹配始终为空,即使它可以完全匹配所有可选组.但是,我想对结果匹配进行后期处理,因此我需要尽可能多地捕获它.
我可以强制正则表达式尝试尽可能匹配所有组吗?
或者您是否知道如何搜索多个单词,由某些单词分隔,然后检查哪些单词出现以计算某些相似性?
非常感谢你
来自Text.Parsec.Token:
lexeme p = do { x <- p; whiteSpace; return x }
Run Code Online (Sandbox Code Playgroud)
看来,语义需要一个解析器P和提供具有相同行为为p,但它也跳过所有尾随空格的分析器.正确?
那怎么来以下不起作用:
constant :: Parser Int
constant = do
digits <- many1 digit
return (read digits)
lexConst :: Parser Int
lexConst = lexeme constant
Run Code Online (Sandbox Code Playgroud)
最后一行导致以下错误消息:
Couldn't match expected type `ParsecT
String () Data.Functor.Identity.Identity Int'
with actual type `ParsecT s0 u0 m0 a0 -> ParsecT s0 u0 m0 a0'
Expected type: Parser Int
Actual type: ParsecT s0 u0 m0 a0 -> ParsecT s0 u0 m0 a0 …Run Code Online (Sandbox Code Playgroud) 我正在尝试解析日期,例如09/10/2015 17:20:52:
{-# LANGUAGE FlexibleContexts #-}
import Text.Parsec
import Text.Parsec.String
import Text.Read
import Control.Applicative hiding (many, (<|>))
data Day = Day
{ mo :: Int
, dy :: Int
, yr :: Int
} deriving (Show)
data Time = Time
{ hr :: Int
, min :: Int
, sec :: Int
} deriving (Show)
day = listUncurry Day <$> (sepCount 3 (char '/') $ read <$> many digit)
time = listUncurry Time <$> (sepCount 3 (char ':') …Run Code Online (Sandbox Code Playgroud) 这是我尝试为正 Int s 编写一个小解析器:
import scala.util.parsing.combinator.RegexParsers
object PositiveIntParser extends RegexParsers {
private def positiveInt: Parser[Int] = """0*[1-9]\d*""".r ^^ { _.toInt }
def apply(input: String): Option[Int] = parseAll(positiveInt, input) match {
case Success(result, _) => Some(result)
case _ => None
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,如果输入字符串太长,则toInt抛出一个NumberFormatException,这会使我的解析器爆炸:
scala> :load PositiveIntParser.scala
Loading PositiveIntParser.scala...
import scala.util.parsing.combinator.RegexParsers
defined object PositiveIntParser
scala> PositiveIntParser("12")
res0: Option[Int] = Some(12)
scala> PositiveIntParser("-12")
res1: Option[Int] = None
scala> PositiveIntParser("123123123123123123")
java.lang.NumberFormatException: For input string: "123123123123123123"
at ...
Run Code Online (Sandbox Code Playgroud)
相反,我希望我的positiveInt …
我正在尝试为与Milner的CCS非常相似的语言编写解析器.基本上我到目前为止解析的是以下类型的表达式:
表达式必须以字母开头(不包括t),并且可以在第一个字母后面加上任意数量的字母(以"."分隔).Expression必须以数字结尾(为简单起见,我现在选择0到2之间的数字).我想为Scala使用Parser Combinators,但这是我第一次使用它们.这是我到目前为止:
import scala.util.parsing.combinator._
class SimpleParser extends RegexParsers {
def alpha: Parser[String] = """[^t]{1}""".r ^^ { _.toString }
def digit: Parser[Int] = """[0-2]{1}""".r ^^ { _.toInt }
def expr: Parser[Any] = alpha ~ "." ~ digit ^^ {
case al ~ "." ~ di => List(al, di)
}
def simpleExpression: Parser[Any] = alpha ~ "." ~ rep(alpha ~ ".") ~ digit //^^ { }
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,def expr :Parser[Any]我试图将结果作为列表返回,因为Scala中的列表非常容易使用(在我看来).这是如何将Parser [Any]结果转换为List的正确方法吗?任何人都可以给我任何关于如何做到这一点的提示def simpleExpression:Parser[Any].
我想使用Lists的主要原因是因为在解析和Expression之后我希望能够使用它.例如,给定表达式ab1,如果给出 …
假设我想创建一个多次使用另一个解析器的组合器,例如,解析由两种引号分隔的字符串:
fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
where
F: Fn(&'a str) -> IResult<&'a str, O, E>,
{
map(
alt((
tuple((tag("'"), f, tag("'"))),
tuple((tag("\""), f, tag("\"")))
)),
|(_, res, _)| res,
)
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,该解析器无法编译并出现“使用移动值”错误:
fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
where
F: Fn(&'a str) -> IResult<&'a str, O, E>,
{
map(
alt((
tuple((tag("'"), f, tag("'"))),
tuple((tag("\""), f, …Run Code Online (Sandbox Code Playgroud) scala ×6
parsing ×5
haskell ×3
parsec ×2
rust ×2
applicative ×1
case-class ×1
fastparse ×1
java ×1
lambda ×1
lexer ×1
nom ×1
polyvariadic ×1
regex ×1
text-parsing ×1
whitespace ×1