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

1/3

parent d98247b9
No related branches found
No related tags found
No related merge requests found
package other
import scala.util.parsing.combinator._
import sun.java2d.pipe.SpanShapeRenderer.Simple
import other.Tudo.rotulos
class Arith extends JavaTokenParsers {
//CONTROLE etc.
val fazTudo = Tudo
var nivelLexico = 0
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)
}
}
}
def eh_param = procStack match {
case stack if ! stack.isEmpty =>
stack.top.isInstanceOf[Procedimento] || stack.top.isInstanceOf[Funcao]
case _ => false
}
//PARSER
object PascalParser {
implicit class isola(s:String) {
def iso = (s + "\\s").r ^^ { _.take(s.size) }
}
//PROGRAM
def program = {
def programInOut = "(" ~> repsep(ident,",") <~ ")"
fazTudo.iniciaPrograma
"program".iso ~> ident ~ programInOut <~ ";" ~ bloco ~ "." ^^
{ _ => fazTudo.encerraPrograma }
}
def bloco:Parser[Any] =
(opt(dec_rotulos) ~ opt(dec_vars) ^^
{ _ =>
if (nivelLexico==0) Tudo.aplica("DSVS R000");
else Tudo.aplica("DSVS "+Tudo.proc.RotStack.top)
nivelLexico+=1 } ) ~
(opt(dec_subrotinas) ^^
{ _ =>
nivelLexico-=1
if (nivelLexico==0) Tudo.aplica("R000: NADA")
else
if (Tudo.MEPA.last == "DSVS "+Tudo.proc.RotStack.top) {
//DSVS R003; R003: seguidos!
Tudo.rotulos.--
Tudo.proc.RotStack.pop()
Tudo.MEPA.remove(Tudo.MEPA.size - 1)
} else
Tudo.aplica(Tudo.proc.RotStack.pop()+": NADA")
}
) ~ comando_composto
//ROTULOS
def dec_rotulos = "label".iso ~> """\d+""".r ~ rep("," ~> """\d+""".r) <~ ";" ^^
{ case x~xs => fazTudo.insereRotulos(x::xs, nivelLexico) }
//VARIAVEIS
def dec_vars = "var".iso ~> dec_var ~ rep(";" ~> dec_var) <~ ";" ^^
{ case xs~xss => fazTudo.insereIntVars(xs ::: xss.flatten, nivelLexico) }
def dec_var = lista_ident <~ ":" ~ tipo
def lista_ident = ident ~ rep( "," ~> ident ) ^^ { mkList }
def tipo = "integer"
//SUB-ROTINAS
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)}
def dec_func = "function".iso ~> ident ~ opt(params_formais) <~ ":" ~ tipo ~ ";" ^^
{ 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
//COMANDOS
def comando_composto:Parser[Any] = "begin".iso ~ comando ~ rep(";" ~ comando) ~ "end"
def comando = opt("""\d+""".r <~ ":" ^^ { rot => fazTudo.entraRotulo(rot,nivelLexico) }) <~ comando_sem_rotulo
def comando_sem_rotulo:Parser[Any] = desvio | atribuicao | repeticao |
condicional | comando_composto | chamaId | expr_simples
def atribuicao = ident <~ ":=" ~ expr_simples ^^
{ case id => fazTudo.atribuicao(id) }
def desvio = "goto".iso ~> """\d+""".r ^^ { rot => fazTudo.gotoRotulo(rot,nivelLexico) }
def condicional =
("if".iso ~ boolexpr ^^ { e =>
val r = Tudo.rotulos.geraRotulo
Tudo.aplica("DSVF "+r)
rotStack.push(r)
e
}) ~
"then".iso ~
(comando_sem_rotulo ^^ { _ => Tudo.aplica(rotStack.pop+": NADA") }) ~
opt(
("else".iso ^^ { _ =>
val gotoElse = Tudo.MEPA.remove(Tudo.MEPA.size - 1)//.takeWhile {_!=':'}
//rotStack.push(fim_if)
rotStack.push(rotulos.geraRotulo)
Tudo.aplica("DSVS "+rotStack.top) //Vai pro fim do if
Tudo.aplica(gotoElse)
})
~ (comando_sem_rotulo ^^ { _ => Tudo.aplica(rotStack.pop+": NADA") })
)
def repeticao =
(("while" ^^ { _=>
val rotLoop = rotulos.geraRotulo
Tudo.aplica(rotLoop+": NADA")
rotStack.push(rotLoop)
}) ~ boolexpr ~ "do" ^^ { _ =>
val rotFim = rotulos.geraRotulo
Tudo.aplica("DSVF "+rotFim)
rotStack.push(rotFim)
}) ~ comando_sem_rotulo ^^ { _=>
val rotFim = rotStack.pop
val rotLoop = rotStack.pop
Tudo.aplica("DSVS "+rotLoop)
Tudo.aplica(rotFim+": NADA")
}
def amem1ForFunctions(id:String) {
val opt = TabelaSimb.getById(id)
opt match {
case Some(fun) if fun.isInstanceOf[Funcao] => Tudo.aplica("AMEM 1")
case _ => //Dont care
}
}
//EXPRESSOES BOOLEANAS
def boolexpr:Parser[Unit] =
(
"(" ~> boolexpr_simples ~> rep( ("and"|"or") <~ boolexpr_simples ) <~ ")" |
boolexpr_simples ~> rep ( ("and"|"or") <~ boolexpr )
) ^^
{ lst => lst.reverse.foreach { case "and" => fazTudo.aplica("CONJ")
case "or" => fazTudo.aplica("DISJ")}
}
def boolexpr_simples =
(
expr_simples ~> relacao <~ expr_simples |
"(" ~ expr_simples ~> relacao <~ expr_simples ~ ")"
) ^^
{
case "=" => fazTudo.aplica("CMIG")
case "<>" => fazTudo.aplica("CMDG")
case "<=" => fazTudo.aplica("CMEG")
case ">=" => fazTudo.aplica("CMAG")
case "<" => fazTudo.aplica("CMME")
case ">" => fazTudo.aplica("CMMA")
}
def relacao = "<="|">="|"="|"<>"|"<"|">"
//EXPRESSOES
def lista_expr =
expr_simples ~ rep("," ~ expr_simples) ^^
{ mkList }
def expr_simples:Parser[Object] = termo ~ rep( ("+"|"-") ~ termo ) ^^
{
case t ~ lst if ! lst.isEmpty =>
lst.reverse.foreach {
case ("+" ~ t) => fazTudo.aplica("SOMA")
case ("-" ~ t) => fazTudo.aplica("SUBT")
case _ => println("op???")
}
new AnyRef
case t ~ Nil => t
}
def termo = fator ~ rep( ("*"|"div"|"/") ~ fator ) ^^
{ case fat~lst if ! lst.isEmpty =>
lst.map{ case ~(str,_) => str }.reverse.foreach {
case "*" => fazTudo.aplica("MULT")
case "div"|"/" => fazTudo.aplica("DIVI")
}
new AnyRef
case fat ~ Nil => fat
}
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
}
def ehProcFun(id:String) = {
TabelaSimb.getById(id) match {
case Some(e) => e.isInstanceOf[Procedimento] || e.isInstanceOf[Funcao]
case None => false
}
}
var passaId = ""
def chamaId =
ident <~ opt("(" ~ lista_expr ~ ")") ^^ { id => fazTudo.chamaId(id, nivelLexico); id }
def numero = wholeNumber ^^ { case x => fazTudo.literal(x.toInt) }
}
}
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
}
//TODO: (-x)
//TODO: READ/WRITE COM DOIS PARAMETROS
//TODO: Verificar número correto de parametros ao chamar funcao
val loopPascalProgram =
"""program exemplo12 (input,output);
var x: integer;
function p(var t: integer):integer;
label 200;
var a,b,c:integer;
begin
while x>2 do begin
x := x+1;
p := p(t,a)
end;
t := x - 20*4 - (23 div (x/2)) + b
end;
begin
x := p(x);
write(x)
end.
"""
val simplePascalProgram =
"""program exemplo12 (input,output);
var x: integer;
function p(var t: integer):integer;
label 200;
var a,b,c:integer;
begin
200: if t>3 and (p(x)<4 or t=-1) and t>=1 then
write(t);
read(x);
goto 200;
t := x - 20*4 - (23 div (x/2)) + b;
p := t
end;
begin
x := p(x);
write(x)
end.
"""
val complexPascalProgram =
"""program exemplo12 (input,output);
var x: integer;
procedure p(var t: integer);
label 100,200;
var s : integer;
function f(z:integer):integer;
begin
if z=1 then z:=2;
if z<0 and 10>2 then goto 200
else if z=0 then f:=2
else f:=f(z-2)*z+1
end;
begin
100: s:=f(t); t:=s;
if t<x then goto 100;
200: x:=x-1
end;
procedure r;
procedure q;
var y:integer;
begin read(y); p(y); write(y) end;
begin q end;
begin read(x); r 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