Hi guys. I’ ve decided to have a try at parser combinators.
So given the following text:
<b>Il profilo alare rappresentato appartiene alla categoria:</b><br>
<img src="q75_small.png"><br>
<ol type="A">
<li>dei piano/convessi</li>
<li>dei concavi/convessi</li>
<li>dei biconvessi asimmetrici</li>
<li>dei biconvessi, simmetrici</li>
</ol>B
I’ m trying to parse it according to the following schema:
import scala.util.parsing.combinator._
trait QuestionParser extends JavaTokenParsers {
def card: Parser[Card] = {
question ~ rep(choice) ~ answer ^^ {
case q ~ cs ~ a => Card(q, cs, a)
}
}
def question: Parser[Question] =
"<b>" ~ text ~ "</b>" ~ opt(image) ^^ {
case tag1 ~ txt ~ tag2 ~ img => Question(txt, img)
}
def choice: Parser[Choice] =
"<li>" ~ text ~ "</li>" ^^ {
case tag1 ~ txt ~ tag2 => Choice(txt)
}
def answer: Parser[Answer] = "</ol>" ~ answerChar ^^ {
case tag ~ aC => Answer(aC)
}
def answerChar: Parser[String] = raw"[A-E]".r
def image: Parser[String] = "<img src=" ~> stringLiteral <~ ">"
def text: Parser[String] = """(.?)""".r
}
and these are the relevant classes:
case class Card(question: Question, choices: List[Choice], ans: Answer)
case class Question(text: String, image: Option[String])
case class Choice(text: String)
case class Answer(char: String) {
override def toString = char
}
But if I run the code as follows:
object Main extends App with QuestionParser{
val testCard: String = Connector.cards(74).card
val p = parseAll(image, testCard) match {
case Success(matched,_) => println(matched)
case Failure(msg,_) => println(s"FAILURE: $msg")
case Error(msg,_) => println(s"ERROR: $msg")
}
//println(p.ans)
}
I get the following message:
FAILURE: '<img src=' expected but '<' found
that is, the parser doesn’t recognize the tag.
Any idea?
Thank you, have a lovely day.
G.