gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 16:40:27 25 4
gpt4 key购买 nike

我使用 Scala 解析器组合器已经有一段时间了,并且学习了一些方法来让它表现得很好,并使用内置函数做我想做的大部分事情。

但是如何制作嵌入式语言(如 php 或 ruby​​ 的 erb)?它要求在嵌入真实代码之外的空白不能被忽略。

我设法制作了一个简单的解析器,可以将所有文本匹配到给定的正则表达式匹配项,但我正在寻找一种更好、更漂亮的方法来执行此操作。可能有一些已经定义的函数可以完成所需的工作。

测试语言解析文本如下:

now: [[ millis; ]]
and now: [[; millis; ]]

由以下代码生成:

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 =>
Failure("string matching regex `"+ r +"' expected but `"+ in.first +"' found", in.drop(0))
}
}
}

def until(s: String): Parser[String] = until(java.util.regex.Pattern.quote(s).r)

def interpret(stats: List[Statement]): Unit = stats match {
case Print(s) :: rest => {
print(s)
interpret(rest)
}
case Millis() :: rest => {
print(System.currentTimeMillis)
interpret(rest)
}
case Nil => ()
}

def apply(input: String) : List[Statement] = parseAll(beginning, input) match {
case Success(tree,_) => tree
case e: NoSuccess => throw new RuntimeException("Syntax error: " + e)
}

/** GRAMMAR **/

def beginning = (
"[[" ~> stats |
until("[[") ~ "[[" ~ stats ^^ {
case s ~ _ ~ ss => Print(s) :: ss
}
)

def stats = rep1sep(stat, ";")

def stat = (
"millis" ^^^ { Millis() } |
"]]" ~> ( (until("[[") <~ "[[") | until("\\z".r)) ^^ {
case s => Print(s)
}
)

def main(args: Array[String]){
val tree = SimpleLang("now: [[ millis; ]]\nand now: [[; millis; ]]")
println(tree)
interpret(tree)
}

}

最佳答案

Scala 的 RegexParsers 特性提供了从 Regex 到 Parser[Char] 的隐式转换,它在检查正则表达式匹配之前跳过任何前导空格。你可以使用

override val skipWhitespace = false

关闭此行为,或覆盖 whiteSpace 成员(它是另一个正则表达式)以提供您自己的自定义字符串。

这些选项在全局范围内有效,关闭空白跳过意味着所有正则表达式产品都会看到空白。

另一种选择是避免在需要空格的少数情况下使用正则表达式转换。我这样做了here在 CSS 的解析器中,它忽略了大多数地方的注释,但就在规则之前,它需要读取它们以提取一些 javadoc 样式的元数据。

关于用于嵌入 html 或文本(如 php)的语言的 Scala 解析器组合器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3347552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com