Я считаю, что функция регистрации крайне неудобна для ввода. Например, почему я должен делать log(parser)("string")
? Почему бы не иметь что-то столь же простое как parser.log("string")
?. В любом случае, чтобы преодолеть это, я сделал это вместо:
trait Logging { self: Parsers =>
// Used to turn logging on or off
val debug: Boolean
// Much easier than having to wrap a parser with a log function and type a message
// i.e. log(someParser)("Message") vs someParser.log("Message")
implicit class Logged[+A](parser: Parser[A]) {
def log(msg: String): Parser[A] =
if (debug) self.log(parser)(msg) else parser
}
}
Теперь в вашем парсере вы можете добавить эту черту следующим образом:
import scala.util.parsing.combinator.Parsers
import scala.util.parsing.input.CharSequenceReader
object CombinatorParserTest extends App with Parsers with Logging {
type Elem = Char
override val debug: Boolean = true
def notComma: Parser[Char] = elem("not comma", _ != ',')
def notEndLine: Parser[Char] = elem("not end line", x => x != '\r' && x != '\n')
def text: Parser[List[Char]] = rep(notComma.log("notComma") | notEndLine.log("notEndLine"))
val r = text(new CharSequenceReader(","))
println(r)
}
Вы также можете переопределить поле debug
, чтобы отключить ведение журнала, если это необходимо.
Выполнение этого также показывает, что второй парсер правильно проанализировал запятую:
trying notComma at scala.util.parsing.input.CharSequenceReader@506e6d5e
notComma --> [1.1] failure: not comma expected
,
^
trying notEndLine at scala.util.parsing.input.CharSequenceReader@506e6d5e
notEndLine --> [1.2] parsed: ,
trying notComma at scala.util.parsing.input.CharSequenceReader@15975490
notComma --> [1.2] failure: end of input
,
^
trying notEndLine at scala.util.parsing.input.CharSequenceReader@15975490
notEndLine --> [1.2] failure: end of input
,
^
The result is List(,)
Process finished with exit code 0