Reputation: 1506
I am new to scala language and its parser combinators. I was working on a task and got stuck at a requirement:
My requirement is to get repetitive Type
for eg: I created parser for logical operator and word (which means string)
def logicalOperator:Parser[Operator] = "(&&|\\|\\|)".r ^^ {case op => Operator(op)}
def word: Parser[word] = """[a-z\\\s]+""".r ^^ { case x => word(x) }
Now My input may contain a single word or repetitive words separated by multiple operators. For ex:
input1=> once&&upon||time||forest.
input2=> therewasatime // this is also a valid input , it does not have any operators
I would process words as per the operators between them.In case there is no operator present (i.e input is a single word , I would process on single word).
&& operator and || operator would decide the operation. (we can consider it to be similar to && and || operator in case of boolean values , to understand clearly )
I was thinking of a case class Sentence , which would represent a single word as well as multiple words . And in case of multiple words it would contain operator.In case single word, operator and second word would be null
case class Sentence(word1:Word, op:Operator, word2:Word).
So this would be a tree structure with leaf node contains only Word and rest nodes would contain operators.
But I am not sure how to write Sentence Parser. I tried using :
def sentence = repsep(word,logicalOperator)^^{// creating sentence object here}.
But I cannot extract operator from repsep()
operation.
Any suggestion for this case ?
thanks
Upvotes: 0
Views: 354
Reputation: 422
The problem with repsep
is that is discards the result of its second argument, you won't be able to identify which operator was used.
Another things is: How do you want once&&upon||time||forest
to be represented, if Sentence
can only contain Words, not other Sentences. In the following, I assumed you meant something like this:
trait Node
case class Operator(s: String)
case class Word(s: String) extends Node
case class Sentence(a: Node, op: Operator, b: Node) extends Node
Then you can write sentence
like this:
def sentence: Parser[Node] = word ~ opt(logicalOperator ~ sentence) ^^ {
case w ~ Some(op ~ sentence) ⇒ Sentence(w, op, sentence)
case w ~ None ⇒ w
}
With this method, once&&upon||time||forest
is parsed as
Sentence(
Word(once),
Operator(&&),
Sentence(
Word(upon),
Operator(||),
Sentence(
Word(time),
Operator(||),
Word(forest)
)
)
)
Upvotes: 0