我有针对scala 2.8.0编译的以下代码:
import scala.util.parsing.combinator.{syntactical,PackratParsers}
import syntactical.StandardTokenParsers
object MyParser extends StandardTokenParsers with PackratParsers{
lexical.reserved ++= Set("int","char","boolean")
lazy val primitiveType:PackratParser[PrimitiveType[_]] = primitiveChar | primitiveInt | primitiveBool
lazy val primitiveInt:PackratParser[PrimitiveType[Int]] = "int" ^^ { _ => PrimitiveType[Int]() }
lazy val primitiveChar:PackratParser[PrimitiveType[Char]] = "char" ^^ { _ => PrimitiveType[Char]() }
lazy val primitiveBool:PackratParser[PrimitiveType[Boolean]] = "boolean" ^^ { _ => PrimitiveType[Boolean]() }
}
object MyParser2 extends StandardTokenParsers with PackratParsers{
lexical.reserved ++= Set("int","char","boolean")
lazy val primitiveType:PackratParser[PrimitiveType[_]] = primitiveChar | primitiveIntOrBool
lazy val primitiveIntOrBool:PackratParser[PrimitiveType[_]] = "int" ^^ …Run Code Online (Sandbox Code Playgroud) 我应该使用RegexParsers,StandardTokenParsers还是完全适合解析这种语法?语法示例可以在这里找到.
我试图在Haskell中组合解析器,以便我可以解析某些模式n次.为了说明,想象一下我想从输入中解析最多八位数.我知道我可以使用count从Text.Parser.Combinators精确解析n个出现的,例如:
import Text.Parser.Char (digit)
import Text.Parser.Combinators (count)
eightDigits :: Parser [Char]
eightDigits = count 8 digit
Run Code Online (Sandbox Code Playgroud)
但是,如果它没有找到正好8位数,则会失败.我也可以some用来解析一个或多个数字:
import Text.Parser.Char (digit)
import Text.Parser.Combinators (some)
someDigits :: Parser [Char]
someDigits = some digit
Run Code Online (Sandbox Code Playgroud)
上面的问题是它可能会消耗比我想要的更多的数字.最后,我可以使用try,它结合了可能消耗输入的解析器,并且在失败时返回到它开始的位置:
import Text.Parser.Char (digit)
import Text.Parser.Combinators (count, try)
import Control.Applicative ((<|>))
twoOrThreeDigits :: Parser [Char]
twoOrThreeDigits = try (count 3 digit) <|> count 2 digit
Run Code Online (Sandbox Code Playgroud)
虽然这可以扩展到最多8次重复,但它不可扩展也不优雅,所以问题是我如何组合解析器来解析1到n次之间的模式?
我尝试解析类似 xml 的标签(但不是正确的 xml 文档..):目标是返回没有开头或结尾空格的“法兰宽度”,但带有内部空格。
open FParsec
let testParser =
pstring "<desc>" .>>. spaces
>>. manyCharsTill anyChar (spaces .>>. pstring "</desc>")
run testParser "<desc> Flange width </desc>"
Run Code Online (Sandbox Code Playgroud)
如果我理解解析器组合器的预期结果:
保持吞咽字符的 anyChar 解析器单元“直到”解析器,它寻找空格,然后是结束标记成功。
实际发生的情况是,“直到”解析器在“宽度”之前的空间上失败(应该如此),但会使 manyTill 解析器短路,而不是让 anyChar 吞下该空间并继续前进。
输出:
val it : ParserResult<string,unit> =
Failure:
Error in Ln: 1 Col: 15
<desc> Flange width </desc>
^
Expecting: '</desc>'
Run Code Online (Sandbox Code Playgroud)
我没有得到什么?或者这里的惯用解决方案是什么?
文档Text.Megaparsec.Char.Lexer.charLiteral建议char '"' *> manyTill charLiteral (char '"')用于解析字符串文字(在库manyTill中的模块Control.Applicative.Combinators中定义parser-combinators)。
然而,Control.Applicative.Combinators也定义了between,它-只要我能看见-像这样使用时也应该这样做的上述建议:between (char '"') (char '"') (many charLiteral)。
但是,使用between上面的解析器不能解析字符串文字——以“意外的输入结束。期待 '”' 或文字字符“(表示永远不会检测到结束引号)而失败。为什么不呢?
此外,更一般地说,为什么不between pBegin pEnd (many p)等于pBegin *> manyTill p pEnd?
Scala 2.8.1
我使用解析器/组合器实现了一个非常简单的外部DSL,用于QA编写验收测试.
最近我添加了循环遍历一组表达式的能力
sealed trait Expr
...
//insert other case classes extending 'Expr' here
...
case class Repetition(times: Int, expressions: List[Expr]) extends Expr
class TestFixtureParser(....) extends RegexParsers {
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
case (times: Int) ~ (exprs: List[Expr]) => {
Repetition(times, exprs)
}
}
private val expressions: Parser[List[Expr]] = (repeatParser |
/*insert other Parser[Expr]s '|' together here */ | verifyParser ).*
}
Run Code Online (Sandbox Code Playgroud)
在构建时,我会warning: non variable type-argument ... …
我正在使用Scala中的本机解析器组合器库,我想解析输入的一些部分,但不解析其他部分.具体来说,我想丢弃我关心的输入之间的所有任意文本.例如,使用此输入:
begin
Text I care about
Text I care about
DONT CARE
Text I don't care about
begin
More text I care about
...
Run Code Online (Sandbox Code Playgroud)
现在我有:
object MyParser extends RegexParsers {
val beginToken: Parser[String] = "begin"
val dontCareToken: Parser[String] = "DONT CARE"
val text: Parser[String] = not(dontCareToken) ~> """([^\n]+)""".r
val document: Parser[String] = begin ~> text.+ <~ dontCareToken ^^ { _.mkString("\n") }
val documents: Parser[Iterable[String]] = document.+
Run Code Online (Sandbox Code Playgroud)
但我不确定如何忽略之后DONT CARE直到下一个文本begin.具体来说,我不想对该文本的形式做任何假设,我只想在下一个begin语句中再次开始解析.
我在scala中使用本机解析器组合器库,我想用它来解析许多大文件.我已经设置了组合器,但是我要解析的文件太大而无法一次性读入内存.我希望能够通过我的解析器从输入文件流式传输并将其读回磁盘,这样我就不需要将它全部存储在内存中了.我当前的系统看起来像这样:
val f = Source.fromFile("myfile")
parser.parse(parser.document.+, f.reader).get.map{_.writeToFile}
f.close
Run Code Online (Sandbox Code Playgroud)
这会在解析时读取整个文件,我想避免使用它.
我一直在努力找到一个简明扼要的措辞,所以请继续阅读详细信息和示例......
我正在为Parsec编写一些帮助操作符,从以下开始:
(<@) :: GenParser tok st a -> (a -> b) -> GenParser tok st b
p <@ f = do {
x <- p ;
return (f x)
}
(<>) :: GenParser tok st a -> GenParser tok st b -> GenParser tok st (a, b)
p <> q = do {
x <- p ;
y <- q ;
return (x, y)
}
Run Code Online (Sandbox Code Playgroud)
这些工作如下:
parseTest ((many upper) <@ length) "HELLO"
5
parseTest (many upper) …Run Code Online (Sandbox Code Playgroud) 我正在为大学构建应用程序.根据需要,我添加段落为每个段落采用单独的TextView.有没有办法让我可以合并段落.我只想到这是否可能?这是我工作的代码片段.
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPostalAddress"
android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry." />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView2"
android:layout_below="@+id/textView2"
android:layout_marginTop="14dp"
android:inputType="numberSigned"
android:text="+91 12 12345678" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:inputType="phone"
android:text="+91 12 12345678" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView3"
android:layout_below="@+id/textView3"
android:autoLink="email"
android:inputType="textEmailAddress"
android:text="admissions@abc.edu" />
Run Code Online (Sandbox Code Playgroud)
在我的代码中,我想在单个TextView中将两个电话号码和电子邮件ID组合在一起.可能吗?
scala ×5
haskell ×3
parsing ×2
android ×1
f# ×1
fparsec ×1
megaparsec ×1
paragraphs ×1
parsec ×1
trifecta ×1
type-erasure ×1