Skip to content
Snippets Groups Projects
Commit 43a742fb authored by Lior Spach's avatar Lior Spach
Browse files

Update parser.scala

parent 95a0a131
No related branches found
No related tags found
No related merge requests found
......@@ -11,48 +11,18 @@ class Arith extends JavaTokenParsers {
val rotStack = Tudo.proc.RotStack
val procStack = collection.mutable.Stack[Entrada]()
object paramCounter {
var paramCount = List[Int]()
def get = paramCount.last
def ++ =
if (paramCount.isEmpty) {
println(paramCount)
println("Empty ++ in paramCount")
sys.exit(1)
} else {
if (paramCount.size==1)
paramCount = Nil
else
paramCount = paramCount.init :+ (paramCount.last+1)
println("++")
}
def newCount = {
paramCount = paramCount :+ 0
println(paramCount)
}
def done = {
println("done")
paramCount match {
case xs if ! xs.isEmpty =>
val last = xs.last
if (xs.size==1) paramCount = Nil
else paramCount = xs.init
last
case Nil =>
println("Erro done() em paramCounter nulo"); sys.exit(1)
}
}
}
val paramCounterStack = collection.mutable.Stack[Int]()
def eh_param = procStack match {
case stack if ! stack.isEmpty =>
stack.top.isInstanceOf[Procedimento] || stack.top.isInstanceOf[Funcao]
case stack if ! stack.isEmpty => true
// stack.top.isInstanceOf[Procedimento] || stack.top.isInstanceOf[Funcao]
case _ => false
}
//PARSER
object PascalParser {
implicit class isola(s:String) {
implicit class isolavel(s:String) {
def iso = (s + "\\s").r ^^ { _.take(s.size) }
}
......@@ -63,16 +33,17 @@ class Arith extends JavaTokenParsers {
"program".iso ~> ident ~ programInOut <~ ";" ~ bloco ~ "." ^^
{ _ => fazTudo.encerraPrograma }
}
def bloco:Parser[Any] =
(opt(dec_rotulos) ~ opt(dec_vars) ^^
{ _ =>
if (nivelLexico==0) Tudo.aplica("DSVS R000");
if (nivelLexico==0) Tudo.aplica("DSVS R00");
else Tudo.aplica("DSVS "+Tudo.proc.RotStack.top)
nivelLexico+=1 } ) ~
(opt(dec_subrotinas) ^^
{ _ =>
nivelLexico-=1
if (nivelLexico==0) Tudo.aplica("R000: NADA")
if (nivelLexico==0) Tudo.aplica("R00: NADA")
else
if (Tudo.MEPA.last == "DSVS "+Tudo.proc.RotStack.top) {
//DSVS R003; R003: seguidos!
......@@ -96,12 +67,13 @@ class Arith extends JavaTokenParsers {
def tipo = "integer"
//SUB-ROTINAS
def dec_subrotinas = rep( (dec_proc | dec_func) <~ bloco ~ ";" ^^ { e => fazTudo.proc.saiProcFunc(nivelLexico); e} )
def dec_subrotinas = rep( (dec_proc | dec_func) <~ bloco ~ ";" ^^
{ e => fazTudo.proc.saiProcFunc(nivelLexico); e} )
def dec_proc = "procedure".iso ~> ident ~ opt(params_formais) <~ ";" ^^
{ case id ~ lstOptIds => fazTudo.proc.entraProc(id, lstOptIds, nivelLexico)}
{ case id ~ lstOptIds => fazTudo.proc.entraProc(id, lstOptIds, nivelLexico) }
def dec_func = "function".iso ~> ident ~ opt(params_formais) <~ ":" ~ tipo ~ ";" ^^
{ case id ~ lstOptIds => fazTudo.proc.entraFunc(id, lstOptIds, nivelLexico)}
{ case id ~ lstOptIds => fazTudo.proc.entraFunc(id, lstOptIds, nivelLexico) }
def params_formais = "(" ~> params ~ rep(";" ~> params) <~ ")" ^^ { s_xs => mkList(s_xs).map{case opt~id=>(opt,id)}}
def params = opt("var".iso) ~ lista_ident <~ ":" ~ tipo
......@@ -187,9 +159,36 @@ class Arith extends JavaTokenParsers {
def relacao = "<="|">="|"="|"<>"|"<"|">"
//EXPRESSOES
def lista_expr =
expr_simples ~ rep("," ~ expr_simples) ^^
{ mkList }
(expr_simples ^^ { foreachExpr }) ~
rep("," ~> (expr_simples ^^ { foreachExpr })) ^^ { mkList }
def foreachExpr(o:Object) = {
procStack.top.id match {
case "write" => fazTudo.aplica("IMPR")
case "read" => //ok
case _ =>
}
val isByRef = Tudo.isAtArgByRef()
inc_pCount
// Check for byRef args
o match {
case s:String => //Okey
case o =>
if ( procStack.top.id=="read" )
assert(false, "Função read recebendo uma expressão!")
else if (isByRef)
assert(false, "Parametro por referencia recebendo valor! Funcão/procedimento: " + procStack.top.id)
//else println("Okey")
}
o
}
def inc_pCount {
paramCounterStack.push(1+paramCounterStack.pop)
}
def expr_simples:Parser[Object] = termo ~ rep( ("+"|"-") ~ termo ) ^^
{
case t ~ lst if ! lst.isEmpty =>
......@@ -214,22 +213,73 @@ class Arith extends JavaTokenParsers {
def fator = ( "("~expr_simples~")" | chamaId | numero ) ^^ { case p:String => p; case _ => new AnyRef}
def getParamsCount(e:Entrada) = e match {
case f:Funcao => f.paramInfo
case p:Procedimento => p.paramInfo
case f:Funcao => f.paramInfo.size
case p:Procedimento => p.paramInfo.size
}
def ehProcFun(id:String) = {
TabelaSimb.getById(id) match {
case Some(e) => e.isInstanceOf[Procedimento] || e.isInstanceOf[Funcao]
case Some(e) =>
e.isInstanceOf[Procedimento] || e.isInstanceOf[Funcao]
case None => false
}
}
def assert(bool: => Boolean, errMsg:String) {
if ( ! bool ) {
println("Erro: " + errMsg)
sys.exit(1)
}
}
var passaId = ""
def entraId(id:String)
{
if (ehProcFun(id)) {
if ( TabelaSimb.getById(id).get.isInstanceOf[Funcao] )
Tudo.aplica("AMEM 1")
procStack.push(TabelaSimb.getById(id).get)
paramCounterStack.push(0)
} else if (id=="write" || id=="read") {
procStack.push(new Entrada(id))
paramCounterStack.push(0)
id match {
case "write" =>
case "read" =>
}
}
}
def saiId(id:String)
{
if (id=="write" || id=="read") {
procStack.pop
return
}
if (!procStack.isEmpty && procStack.top.id == "read"){
fazTudo.aplica("LEIT")
if (id != "read") fazTudo.atribuicao(id)
return
}
if ( ehProcFun(id) ) {
val proc = procStack.pop
val nParams = paramCounterStack.pop
assert(nParams == getParamsCount(proc),
"Número de parametros incorretos na chamada da função/procedimento "+id)
}
fazTudo.geraMepaDoId(id, nivelLexico)
}
def chamaId =
ident <~ opt("(" ~ lista_expr ~ ")") ^^ { id => fazTudo.chamaId(id, nivelLexico); id }
(ident ^^ { id => entraId(id); id }) <~ opt("(" ~ lista_expr ~ ")") ^^
{ id => saiId(id); id }
def numero = wholeNumber ^^ { case x => fazTudo.literal(x.toInt) }
......@@ -239,32 +289,60 @@ class Arith extends JavaTokenParsers {
object MyParser extends Arith {
def main(args: Array[String]) {
if (args.size != 2) {
println("./compilador [ArqEntrada] [NomeArquivoSaida]")
sys.exit(1)
}
val pascalSource = io.Source.fromFile(args(0)).getLines().mkString("\n")
parseAll(PascalParser.program, pascalSource)
val mp = Tudo.MEPA
val pw = new java.io.PrintWriter(args(1))
mp foreach pw.println
// if (args.size != 2) {
// println("./compilador [ArqEntrada] [NomeArquivoSaida]")
// sys.exit(1)
// }
// val pascalSource = io.Source.fromFile(args(0)).getLines().mkString("\n")
val pascalSource = ArqExemplos.exemplo8_10
println(parseAll(PascalParser.program, pascalSource))
Tudo.MEPA foreach println
// val mp = Tudo.MEPA
// val pw = new java.io.PrintWriter(args(1))
// mp foreach pw.println
}
//TODO: (-x)
//TODO: READ/WRITE COM DOIS PARAMETROS
//TODO: Verificar número correto de parametros ao chamar funcao
//TODO: function return as parameter/atribution
val noloopPascalProgram =
"""program exemplo12 (input,output);
var x: integer;
function p(a:integer; var t: integer):integer;
label 200;
var a,b:integer;
c:integer;
procedure q(var a:integer; y:integer);
begin
q(a,c+b+a+20);
write(b,a);
read(a,b)
end;
begin
p := p(20,a);
t := (23 div (x/2)) + b
end;
begin
x := p(x,x);
write(x)
end.
"""
val loopPascalProgram =
"""program exemplo12 (input,output);
var x: integer;
function p(var t: integer):integer;
label 200;
var a,b,c:integer;
var a,b:integer;
c:integer;
begin
while x>2 do begin
x := x+1;
p := p(t,a)
p := p(t-10)
end;
t := x - 20*4 - (23 div (x/2)) + b
end;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment