" class"
"3.14"
"+"
expression
term ::= factor "*" term
term ::= factor
term ::= factor "*" term ::= factor "*" factor "*" term ::= factor "*" factor "*" factor
(1) (1, 24, 4) ()
list ::= "(" contents ")"
contents ::= contents ::= number contents ::= number "," contents
(1, 24, )
list ::= "(" contents ")" list ::= "(" ")"
contents ::= number contents ::= number "," contents
contents
yields n numbers separated by n - 1 commasA | B
(A)*
or {A}
(A)+
(A)?
or [A]
list ::= "(" ( number ( "," number )* )? ")"
~
|
rep(...)
opt(...)
class SimpleLanguageParser extends JavaTokenParsers { def expr: Parser[Any] = term ~ opt(("+" | "-") ~ expr) def term: Parser[Any] = factor ~ opt(("*" | "/" ) ~ term) def factor: Parser[Any] = wholeNumber | "(" ~ expr ~ ")" }
Parser[Any]
with something more useful lateropt(P)
returns Option
: Some
of the result of P
, or None
(see next slide)rep(P)
returns List
of the results of P
P ~ Q
returns instance of class ~
(similar to a pair)val parser = new SimpleLanguageParser val result = parser.parse(parser.expr, "3 - 4 * 5")
sets result
to
((3~None)~Some((-~((4~Some((*~(5~None))))~None))))
(x~None)
to x
, Some(y)
to y
, and ~
to spaces:
(3 (- (4 (* 5))))
Some
, None
List.find
returns Option[A]
.
val result = lst.find(_ % 2 == 0) result match { case Some(x) => println(x) case None => println("No match") }
null
if there is no match? Int
can't be null
null
might be a valid value in the collectionnull
can lead to NullPointerException
lab8/report.txt
inside the Git repo. Include the coder's name in the report! lab8
:
cd cs152 # (or whereever you store your git repo) PROJECT=lab8 # (or whatever project you want to make) echo $PROJECT | sbt new cayhorstmann/cs152-seed.g8 cd $PROJECT find . -name Hello*.scala -exec rm {} \;
sbt eclipseThen start Eclipse and import the project.
lab8
directory.import scala.util.parsing.combinator._ class SimpleLanguageParser extends JavaTokenParsers { def expr: Parser[Any] = term ~ opt(("+" | "-") ~ expr) def term: Parser[Any] = factor ~ opt(("*" | "/" ) ~ term) def factor: Parser[Any] = wholeNumber | "(" ~ expr ~ ")" } object Lab8 extends App { val parser = new SimpleLanguageParser val result = parser.parse(parser.expr, "3 - 4 * 5") println(result.get) }
factor
rule recurses back to the expr
rule. Give an example input to the parser that demonstrates this feature. What is your input? What is the output?SimpleLanguageParser
(and not to Lab8
):
def eval(x : Any) : Int = x match { case a ~ Some("+" ~ b) => eval(a) + eval(b) case a ~ Some("-" ~ b) => eval(a) - eval(b) case a ~ Some("*" ~ b) => eval(a) * eval(b) case a ~ Some("/" ~ b) => eval(a) / eval(b) case a ~ None => eval(a) case a : String => Integer.parseInt(a) case "(" ~ a ~ ")" => eval(a) }
In your main program, print the value computed by parser.eval(result.get)
. What output do you get when the parser input is 3 - 4 * 5? 3 * 4 - 5?
eval
function do? val x = 3 + 4 * y
In BNF, this would be
valdef ::= "val" identifier "=" expr
Add a valdef
type to the combinator parser that represents such a definition. (To see how to parse an identifier, go to the
scaladoc of JavaTokenParsers
and then click on the source link on the top of the file.)
What is the type that you added?
val x = 3 + 4
? Hint: Remember to call
parser.parse(parser.valdef, "val x = 3 + 4")
val x = 3 + 4 * y
? (Hint: Look closely at the output. Where is the y? Why?)