You are on page 1of 5

// Project name MP

// Create by: nhphung


// Create date: Aug 27, 2012
// Language: Scala
// Description: This file is about recognizer for MP language, see MP language s
pecification for more information
import scala.util.matching.Regex
import scala.util.parsing.combinator.lexical.StdLexical
import scala.util.parsing.combinator.token.StdTokens
import scala.util.parsing.input.CharArrayReader.EofCh
trait BKOOLTokens extends StdTokens {
// Adapted from StdTokens
case class FloatLit(chars: String) extends Token {
override def toString = "FloatLit: " + chars
}
case class IntLit(chars: String) extends Token {
override def toString = "IntLit: " + chars
}
case class BooleanLit(chars: String) extends Token {
override def toString = "BooleanLit: " + chars
}
case class BKStringLit(chars: String) extends Token {
override def toString = "String: " + chars
}
}
// TODO Copy your lexer here
class BKOOLLexer extends StdLexical with BKOOLTokens {
import scala.util.parsing.input.CharArrayReader.EofCh
def regex(r: Regex): Parser[String] = new Parser[String] {
def apply(in: Input) = {
val source = in.source
val offset = in.offset
(r findPrefixMatchOf (source.subSequence(offset, source.length))) match {
case Some(matched) =>
Success(source.subSequence(offset, offset + matched.end).toString,
in.drop(matched.end))
case None =>
Failure("string matching regex `" + r + "' expected but `" + in.first
+ "' found", in.drop(0))
}
}
}
// TODO student add code here to complete token
//-------------------------------------------------keyword--------------------
-------------------------------------
reserved ++= List(
"abstract", "bool", "break", "class", "continue", "do", "downto", "else", "e
xtends",
"float", "for", "if", "integer", "new", "repeat", "string", "then", "to",
"until", "while", "return", "true", "false", "void", "null", "self", "final"
)
//-------------------------------------------separator & operator-------------
-------------------------------------
delimiters ++= List("[", "]", "{", "}", "(", ")", ":", ";", ",", ".", "+",
"-", "*", "/", """\""", "%", ":=", "==", "<", ">",
"<=", ">=", "<>", "&&", "!", "||", "^", "new", "::", "=")
val str = """((\\[bfnt\"\\])|[^\n])"""
val string = """\"""" + str + """*?\""""
val unclosedString = """\"""" + str + """*"""
override def token: Parser[Token] = {
// Adapted from StdLexical
(
regex(string.r) ^^ { BKStringLit(_) }
|regex(unclosedString.r) ^^ ("Unclosed String: " + _) ^^ ErrorToken
| regex("[a-zA-Z_][a-zA-Z_0-9]*".r) ^^ {
case x => x match {
case "true" | "false" => { BooleanLit(x) }
case _ => { processIdent(x) }
}
}
| regex("([0-9]+)((\\.[0-9]*)?((E|e)(`+'|-)?([0-9]+)))|(([0-9]+\\.[0-9]*)(
(E|e)(`+'|-)?([0-9]+))?)".r) ^^ { FloatLit(_) }
| regex("[0-9]+".r) ^^ { IntLit(_) }
| EofCh ^^^ EOF
| delim)
}
//---------------------------------------------------comment------------------
-------------------------------
override def whitespace: Parser[Any] = rep(
whitespaceChar
| '(' ~ '*' ~ comment
| '(' ~ '*' ~> failure("unclosed comment")
| '#' ~ rep(chrExcept(EofCh, '\n')))
override protected def comment: Parser[Any] = (
'*' ~ ')' ^^ { case _ => ' ' }
| chrExcept(EofCh) ~ comment)
// end comment
}
import scala.util.parsing.combinator.token.StdTokens
import scala.util.parsing.combinator.syntactical.StdTokenParsers
class BKOOLRecognizer extends StdTokenParsers {
type Tokens = BKOOLTokens
val lexical = new BKOOLLexer
def getLexical: BKOOLLexer = lexical
def show(result: ParseResult[Any]): String = {
result match {
case Failure(msg, next) =>
"Error at line " + next.pos.line + " col " + next.pos.column
case Error(msg, next) =>
"Fatal error at line " + next.pos.line + " col " + next.pos.column
case _ => "Successful"
}
}
//
def parse(s: String) = phrase(program)(new lexical.Scanner(s))
// For BKOOLRecognizer, students may modify the following.
def program: Parser[Any] = rep(classdecl)
//def decl: Parser[Any] = (methoddecl | constdecl | vardecl | classdecl )
//------------------------------------------class declaration-----------------
------------------------------------
def classdecl: Parser[Any] = "class" ~ ident ~ opt("extends" ~ ident) ~ "{" ~
rep(list_of_member) ~ "}"
def list_of_member: Parser[Any] = methoddecl|attribute| amp //amp = abstract
method type
def attribute: Parser[Any] = (vardecl | constdecl)
def vardecl: Parser[Any] = rep(ident ~ ",") ~ ident ~ ":" ~ (Array_type | Prim
itive_type | Class_type) ~ ";" //Primitive_type doesnt have Void
def constdecl: Parser[Any] = "final" ~ (Primitive_type|Array_type) ~ ident ~ "
=" ~ (Expression|intlit|floatlit|boollit) ~ ";"
def amp: Parser[Any] = "abstract" ~ return_type ~ ident ~ "(" ~ list_of_parame
ter ~ ")" ~ ";"
def return_type: Parser[Any] = (Primitive_type | Array_type | Class_type | Voi
d_type)
def list_of_parameter: Parser[Any] = rep(vardecl)
def methoddecl: Parser[Any] = opt(return_type) ~ ident ~ "(" ~ list_of_paramet
er ~ ")" ~ "{" ~ body ~ "}"
def body: Parser[Any] = rep(vardecl | constdecl) ~ rep(Block_statement)
//------------------------------------------------Type------------------------
----------------------------------
def Primitive_type: Parser[Any] = "integer" | "float" | "bool" | "string"
def Void_type: Parser[Any] = "void"
def Array_type: Parser[Any] = element_type ~ "[" ~ intlit ~ "]"
def element_type: Parser[Any] = Primitive_type | Class_type
def Class_type: Parser[Any] = ident
//-----------------------------------------------------Expression-------------
------------------------------------
def Expression: Parser[Any] = (Member_access |Relational_expression |Arithmeti
c_expression|Boolean_expression | String_expression| Index_expression|Object_cre
ation) //| Self)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Arithmetic Expression~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def Arithmetic_expression: Parser[Any] = Binary_arith | Unary_arith
def Binary_arith: Parser[Any] = (arith_operand | Unary_arith) ~ binary_operato
r ~ Arithmetic_expression | (arith_operand | Unary_arith) ~ binary_operator ~ (a
rith_operand | Unary_arith)
def Unary_arith: Parser[Any] = unary_operator ~ (arith_operand | Unary_arith)
def binary_operator: Parser[Any] = "+" | "-" | "*" | "/" | "\\" | "%"
def unary_operator: Parser[Any] = "+" | "-"
def arith_operand: Parser[Any] = Index_expression|Member_access| ident | intli
t | floatlit
/*def Arithmetic_expression: Parser[Any] = Binary ~ A
def A: Parser[Any] = binary_operator ~ Binary ~ A?
def Binary: Parser[Any] = Unary_operator ~ Unary_operand
def Unary_operand: Parser[Any] = intlit | floatlit | ident
def Unary_operator: Parser[Any] = "+" | "-"
def binary_operator: Parser[Any] = "+" | "-" | "*" | "/" | "\\" | "%"
*/


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Boolean Expression~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def Boolean_expression: Parser[Any] = Binary_bool | Unary_bool
def Binary_bool: Parser[Any] = (operand_bool | Unary_bool) ~ Binary_operator_b
ool ~ Boolean_expression | (operand_bool | Unary_bool) ~ Binary_operator_bool ~
(operand_bool | Unary_bool)
def Unary_bool: Parser[Any] = Unary_operator_bool ~ (operand_bool | Unary_bool
)
def Binary_operator_bool: Parser[Any] = "&&" | "||"
def Unary_operator_bool: Parser[Any] = "!"
def operand_bool: Parser[Any] = boollit | ident

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Relational Expression~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def Relational_expression: Parser[Any] = Binary_rela | Unary_rela
def Binary_rela: Parser[Any] = (operand_rela | Unary_rela) ~ Binary_operator_r
ela ~ Relational_expression | (operand_rela | Unary_rela) ~ Binary_operator_rela
~ (operand_rela | Unary_rela)
def Unary_rela: Parser[Any] = (operand_rela) ~ Unary_operator_rela ~ Relationa
l_expression
def Binary_operator_rela: Parser[Any] = ">" | "<" | ">=" | "<="
def Unary_operator_rela: Parser[Any] = "==" | "<>"
def operand_rela: Parser[Any] = Primitive_type | ident

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~String Expression~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def String_expression: Parser[Any] = string_operand ~ A
def A: Parser[Any] = "^" ~ string_operand ~ A?
def string_operand: Parser[Any] = stringlit|ident//|member_access_expression


def Index_expression: Parser[Any] = ident ~ "[" ~ expression1 ~ "]"
def expression1: Parser[Any] = (Member_access|Arithmetic_expression|Index_exp
ression|intlit)


//def Member_access: Parser[Any] = ident ~ "." ~ (ident|"self") ~ opt("(" ~ o
pt(rep(Expression ~ ",") ~ (Expression|intlit|floatlit)) ~ ")")

def Member_access: Parser[Any] = (ident|"self") ~ "." ~ ident ~ opt(block_exp
ression)
def block_expression: Parser[Any] = "(" ~ list_expression ~ ")" | "(" ~ ")"
def list_expression: Parser[Any] = rep((Member_access|Arithmetic_expression|I
ndex_expression|intlit|floatlit) ~ "," )~ (Member_access|Arithmetic_expression|
Index_expression | intlit | floatlit)

def Object_creation: Parser[Any] = "new" ~ ident ~ "(" ~ opt(rep(Expression ~
",") ~ Expression) ~ ")"
// ----------------------------------------------------------------------------

def statement: Parser[Any] = Block_statement
def Block_statement: Parser[Any] = "{" ~ opt(rep(vardecl|constdecl) ~ opt(lis
t_of_statement)) ~ "}"
def list_of_statement: Parser[Any] = rep( (Assign_statement|if_statement|whil
e_statement|repeat_statement|for_statement|return_statement|method_statement) ~
";")

def Assign_statement: Parser[Any] = lhs ~ ":=" ~ (Expression|intlit|floatlit|
boollit)
def lhs: Parser[Any] = ident | Index_expression

def if_statement: Parser[Any] = "if" ~ booltype_expression ~ "then" ~ (list_o
f_statement|Block_statement) ~ opt("else" ~ list_of_statement|Block_statement)
def booltype_expression: Parser[Any] = Boolean_expression | Relational_expres
sion | Index_expression | Member_access | Object_creation

def while_statement: Parser[Any] = "while" ~ booltype_expression ~ "do" ~ (li
st_of_statement|Block_statement|("break" ~ ";")|("continue" ~ ";"))

def repeat_statement: Parser[Any] = "repeat" ~ (list_of_statement|Block_state
ment|("break"~";")|("continue" ~ ";")) ~ "until" ~ booltype_expression

def for_statement: Parser[Any] = "for" ~ integer_var ~ ":=" ~ integer_type_ex
pression ~ ("to"|"downto") ~ integer_type_expression ~ "do" ~ (list_of_statement
|Block_statement|("break"~";")|("continue" ~ ";"))
def integer_var: Parser[Any] = (Index_expression|Member_access|Object_creatio
n)
def integer_type_expression: Parser[Any] = (Arithmetic_expression|Index_expre
ssion|Member_access|Object_creation|intlit)

def return_statement: Parser[Any] = "return" ~ Expression ~ ";"

def method_statement: Parser[Any] = Member_access









def boollit: Parser[Any] = elem("boolean", _.isInstanceOf[lexical.BooleanLit])
def floatlit: Parser[Any] = elem("real", _.isInstanceOf[lexical.FloatLit])
def intlit: Parser[Any] = elem("integer", _.isInstanceOf[lexical.IntLit])

def stringlit: Parser[Any] = elem("string", _.isInstanceOf[lexical.BKStringLit
])

}

You might also like