Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pascal-compiler
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Harbor Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Lior Spach
pascal-compiler
Commits
4dc0ee36
Commit
4dc0ee36
authored
10 years ago
by
Lior Spach
Browse files
Options
Downloads
Patches
Plain Diff
Add type support! (Tested)
parent
11afea5d
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/main/scala/other/Parser.scala
+28
-13
28 additions, 13 deletions
src/main/scala/other/Parser.scala
src/main/scala/other/TabelaSimb.scala
+11
-0
11 additions, 0 deletions
src/main/scala/other/TabelaSimb.scala
src/main/scala/other/Tudo.scala
+65
-24
65 additions, 24 deletions
src/main/scala/other/Tudo.scala
with
104 additions
and
37 deletions
src/main/scala/other/Parser.scala
+
28
−
13
View file @
4dc0ee36
...
@@ -5,6 +5,9 @@ import sun.java2d.pipe.SpanShapeRenderer.Simple
...
@@ -5,6 +5,9 @@ import sun.java2d.pipe.SpanShapeRenderer.Simple
import
other.Tudo.rotulos
import
other.Tudo.rotulos
import
com.sun.org.apache.xml.internal.serializer.ToStream.BoolStack
import
com.sun.org.apache.xml.internal.serializer.ToStream.BoolStack
case
class
ids_t
(
ids
:
List
[
String
],
tipo
:
String
)
case
class
dec_param
(
byRef
:
Boolean
,
ids
:
List
[
String
],
tipo
:
String
)
class
Arith
extends
JavaTokenParsers
{
class
Arith
extends
JavaTokenParsers
{
//CONTROLE etc.
//CONTROLE etc.
val
fazTudo
=
Tudo
val
fazTudo
=
Tudo
...
@@ -40,11 +43,19 @@ class Arith extends JavaTokenParsers {
...
@@ -40,11 +43,19 @@ class Arith extends JavaTokenParsers {
}
}
def
bloco
:
Parser
[
Any
]
=
def
bloco
:
Parser
[
Any
]
=
(
opt
(
dec_rotulos
)
~
opt
(
dec_vars
)
^^
(
opt
(
dec_rotulos
)
~
(
opt
(
dec_tipos
)
^^
{
case
Some
(
tipos
)
=>
//Add to table
TabelaSimb
.
insere
(
tipos
.
map
{
t
=>
Tipo
(
t
)
})
case
None
=>
//fine
})~
opt
(
dec_vars
)
^^
{
_
=>
{
_
=>
if
(
nivelLexico
==
0
)
Tudo
.
aplica
(
"DSVS R00"
);
if
(
nivelLexico
==
0
)
Tudo
.
aplica
(
"DSVS R00"
);
else
Tudo
.
aplica
(
"DSVS "
+
Tudo
.
proc
.
RotStack
.
top
)
else
Tudo
.
aplica
(
"DSVS "
+
Tudo
.
proc
.
RotStack
.
top
)
nivelLexico
+=
1
}
)
~
nivelLexico
+=
1
})
~
(
opt
(
dec_subrotinas
)
^^
(
opt
(
dec_subrotinas
)
^^
{
_
=>
{
_
=>
nivelLexico
-=
1
nivelLexico
-=
1
...
@@ -64,24 +75,30 @@ class Arith extends JavaTokenParsers {
...
@@ -64,24 +75,30 @@ class Arith extends JavaTokenParsers {
def
dec_rotulos
=
"label"
.
iso
~>
"""\d+"""
.
r
~
rep
(
","
~>
"""\d+"""
.
r
)
<~
";"
^^
def
dec_rotulos
=
"label"
.
iso
~>
"""\d+"""
.
r
~
rep
(
","
~>
"""\d+"""
.
r
)
<~
";"
^^
{
case
x
~
xs
=>
fazTudo
.
insereRotulos
(
x
::
xs
,
nivelLexico
)
}
{
case
x
~
xs
=>
fazTudo
.
insereRotulos
(
x
::
xs
,
nivelLexico
)
}
//TIPOS
def
dec_tipos
=
"type"
.
iso
~>
(
def_tipo
<~
";"
)
~
rep
(
def_tipo
<~
";"
)
^^
{
mkList
}
def
def_tipo
=
ident
<~
"="
~
"integer"
def
tipo
=
ident
//VARIAVEIS
//VARIAVEIS
def
dec_vars
=
"var"
.
iso
~>
dec_var
~
rep
(
";"
~>
dec_var
)
<~
";"
^^
def
dec_vars
=
"var"
.
iso
~>
dec_var
~
rep
(
";"
~>
dec_var
)
<~
";"
^^
{
case
xs
~
xss
=>
fazTudo
.
insereIntVars
(
xs
:::
xss
.
flatten
,
nivelLexico
)
}
{
case
xss
=>
fazTudo
.
insereIntVars
(
mkList
(
xss
)
,
nivelLexico
)
}
def
dec_var
=
lista_ident
<~
":"
~
tipo
def
dec_var
=
(
lista_ident
<~
":"
)
~
tipo
^^
{
case
ids
~
t
=>
ids_t
(
ids
,
t
)}
def
lista_ident
=
ident
~
rep
(
","
~>
ident
)
^^
{
mkList
}
def
lista_ident
=
ident
~
rep
(
","
~>
ident
)
^^
{
mkList
}
def
tipo
=
"integer"
//SUB-ROTINAS
//SUB-ROTINAS
def
dec_subrotinas
=
rep
(
(
dec_proc
|
dec_func
)
<~
bloco
~
";"
^^
def
dec_subrotinas
=
rep
(
(
dec_proc
|
dec_func
)
<~
bloco
~
";"
^^
{
e
=>
fazTudo
.
proc
.
saiProcFunc
(
nivelLexico
);
e
}
)
{
e
=>
fazTudo
.
proc
.
saiProcFunc
(
nivelLexico
);
e
}
)
def
dec_proc
=
"procedure"
.
iso
~>
ident
~
opt
(
params_formais
)
<~
";"
^^
def
dec_proc
=
"procedure"
.
iso
~>
ident
~
opt
(
params_formais
)
<~
";"
^^
{
case
id
~
lst
OptIds
=>
fazTudo
.
proc
.
entraProc
(
id
,
lst
OptIds
,
nivelLexico
)
}
{
case
id
~
lst
DecParam
=>
fazTudo
.
proc
.
entraProc
(
id
,
lst
DecParam
,
nivelLexico
)
}
def
dec_func
=
"function"
.
iso
~>
ident
~
opt
(
params_formais
)
<
~
":"
~
tipo
~
";"
^^
def
dec_func
=
"function"
.
iso
~>
ident
~
opt
(
params_formais
)
~
(
":"
~
>
tipo
)
<
~
";"
^^
{
case
id
~
lst
OptIds
=>
fazTudo
.
proc
.
entraFunc
(
id
,
lst
OptIds
,
nivelLexico
)
}
{
case
id
~
lst
DecParam
~
tipo
=>
fazTudo
.
proc
.
entraFunc
(
id
,
lst
DecParam
,
nivelLexico
,
tipo
)
}
def
params_formais
=
"("
~>
params
~
rep
(
";"
~>
params
)
<~
")"
^^
{
s_xs
=>
mkList
(
s_xs
).
map
{
case
opt
~
id
=>(
opt
,
id
)}
}
def
params_formais
=
"("
~>
params
~
rep
(
";"
~>
params
)
<~
")"
^^
{
mkList
}
def
params
=
opt
(
"var"
.
iso
)
~
lista_ident
<
~
":"
~
tipo
def
params
=
opt
(
"var"
.
iso
)
~
lista_ident
~
(
":"
~
>
tipo
)
^^
{
case
v
~
ids
~
tipo
=>
dec_param
(
v
.
isDefined
,
ids
,
tipo
)}
//COMANDOS
//COMANDOS
def
comando_composto
:
Parser
[
Any
]
=
"begin"
.
iso
~
comando
~
rep
(
";"
~
comando
)
~
"end"
def
comando_composto
:
Parser
[
Any
]
=
"begin"
.
iso
~
comando
~
rep
(
";"
~
comando
)
~
"end"
...
@@ -389,12 +406,10 @@ object MyParser extends Arith {
...
@@ -389,12 +406,10 @@ object MyParser extends Arith {
sys
.
exit
(
1
)
sys
.
exit
(
1
)
}
}
val
pascalSource
=
io
.
Source
.
fromFile
(
args
(
0
)).
getLines
().
mkString
(
"\n"
)
val
pascalSource
=
io
.
Source
.
fromFile
(
args
(
0
)).
getLines
().
mkString
(
"\n"
)
// val pascalSource = ArqExemplos.p
try
try
println
(
parseAll
(
PascalParser
.
program
,
pascalSource
))
println
(
parseAll
(
PascalParser
.
program
,
pascalSource
))
catch
{
case
e
:
Exception
=>
println
(
"Erro no programa"
);
sys
.
exit
(
1
)
}
catch
{
case
e
:
Exception
=>
println
(
"Erro no programa"
);
sys
.
exit
(
1
)
}
val
mp
=
Tudo
.
MEPA
val
mp
=
Tudo
.
MEPA
// mp foreach println
val
pw
=
new
java
.
io
.
PrintWriter
(
"MEPA"
)
val
pw
=
new
java
.
io
.
PrintWriter
(
"MEPA"
)
mp
foreach
pw
.
println
mp
foreach
pw
.
println
pw
.
close
pw
.
close
...
...
This diff is collapsed.
Click to expand it.
src/main/scala/other/TabelaSimb.scala
+
11
−
0
View file @
4dc0ee36
...
@@ -9,6 +9,7 @@ case class Procedimento(override val id:String, paramInfo:List[Param],
...
@@ -9,6 +9,7 @@ case class Procedimento(override val id:String, paramInfo:List[Param],
case
class
Param
(
override
val
id
:
String
,
desloc
:
Int
,
byRef
:
Boolean
,
nvLex
:
Int
,
tipo
:
String
=
"integer"
)
extends
Entrada
(
id
)
case
class
Param
(
override
val
id
:
String
,
desloc
:
Int
,
byRef
:
Boolean
,
nvLex
:
Int
,
tipo
:
String
=
"integer"
)
extends
Entrada
(
id
)
case
class
Var
(
override
val
id
:
String
,
desloc
:
Int
,
nvLex
:
Int
,
tipo
:
String
=
"integer"
)
extends
Entrada
(
id
)
case
class
Var
(
override
val
id
:
String
,
desloc
:
Int
,
nvLex
:
Int
,
tipo
:
String
=
"integer"
)
extends
Entrada
(
id
)
case
class
Label
(
override
val
id
:
String
,
rotulo
:
String
,
nvLex
:
Int
,
var
used
:
Boolean
=
false
,
var
put
:
Boolean
=
false
)
extends
Entrada
(
id
)
case
class
Label
(
override
val
id
:
String
,
rotulo
:
String
,
nvLex
:
Int
,
var
used
:
Boolean
=
false
,
var
put
:
Boolean
=
false
)
extends
Entrada
(
id
)
case
class
Tipo
(
override
val
id
:
String
)
extends
Entrada
(
id
)
object
TabelaSimb
{
object
TabelaSimb
{
...
@@ -45,6 +46,16 @@ object TabelaSimb {
...
@@ -45,6 +46,16 @@ object TabelaSimb {
}
}
}
}
def
existeTipo
(
tipo
:
String
)
:
Boolean
=
{
if
(
tipo
==
"integer"
)
return
true
table
.
exists
{
e
=>
e
match
{
case
t
:
Tipo
=>
if
(
t
.
id
==
tipo
)
true
else
false
case
_
=>
false
}}
}
@tailrec
@tailrec
def
numVarsLocais
(
nvLex
:
Int
,
count
:
Int
=
0
,
rest
:
List
[
Entrada
]
=
table
)
:
Int
=
rest
match
{
def
numVarsLocais
(
nvLex
:
Int
,
count
:
Int
=
0
,
rest
:
List
[
Entrada
]
=
table
)
:
Int
=
rest
match
{
case
(
v
:
Var
)
::
xs
=>
numVarsLocais
(
nvLex
,
count
+
1
,
xs
)
case
(
v
:
Var
)
::
xs
=>
numVarsLocais
(
nvLex
,
count
+
1
,
xs
)
...
...
This diff is collapsed.
Click to expand it.
src/main/scala/other/Tudo.scala
+
65
−
24
View file @
4dc0ee36
...
@@ -15,25 +15,47 @@ object Tudo {
...
@@ -15,25 +15,47 @@ object Tudo {
num
match
{
num
match
{
case
dig
if
num
<
10
=>
"0"
+
dig
case
dig
if
num
<
10
=>
"0"
+
dig
case
dezena
if
num
<
100
=>
""
+
dezena
case
dezena
if
num
<
100
=>
""
+
dezena
case
bigge
r
if
num
>=
100
=>
""
+
bigge
r
case
maio
r
if
num
>=
100
=>
""
+
maio
r
}
}
)
)
}
}
}
}
def
insereIntVars
(
vars
:
List
[
String
],
nivelLexico
:
Int
)
=
{
def
insereIntVars
(
vars_t
:
List
[
ids_t
],
nivelLexico
:
Int
)
=
{
val
orgSize
=
vars
.
size
var
desloc
=
0
//Garante que os tipos existem
if
(
orgSize
==
vars
.
distinct
.
size
)
{
val
lst_tipos
=
vars_t
.
map
{
case
ids_t
(
_
,
t
)
=>
t
}
TabelaSimb
insere
vars
.
map
{
id
=>
val
tipo_invalido
=
lst_tipos
.
distinct
.
find
{
t
=>
!
TabelaSimb
.
existeTipo
(
t
)
}
//Ache um que não existe
val
v
=
Var
(
id
,
desloc
,
nivelLexico
);
desloc
+=
1
;
v
tipo_invalido
match
{
case
Some
(
invalido
)
=>
//Erro
println
(
"Erro: Tipo não declarado na declaração de variáveis: "
+
invalido
)
sys
.
exit
(
1
)
case
None
=>
//Ok
}
}
aplica
(
"AMEM "
+
orgSize
)
//end
}
else
{
//Garante nenhuma repetição de id
val
listaIds
=
vars_t
.
map
{
case
ids_t
(
ids
,
_
)
=>
ids
}.
flatten
val
totalAMEM
=
listaIds
.
size
if
(
listaIds
.
distinct
.
size
!=
listaIds
.
size
)
{
println
(
"Erro: declaração de variáveis:"
)
println
(
"Erro: declaração de variáveis:"
)
println
(
" identificadores já declarados para parametros ou var: "
+
vars
.
diff
(
vars
.
distinct
).
mkString
(
" "
))
println
(
" identificadores já declarados para parametros ou var: "
+
listaIds
.
diff
(
listaIds
.
distinct
).
mkString
(
" "
))
sys
.
exit
(
1
)
sys
.
exit
(
1
)
}
}
//end
var
desloc
=
0
vars_t
.
foreach
{
case
ids_t
(
varsId
,
tipo
)
=>
TabelaSimb
insere
varsId
.
map
{
id
=>
desloc
+=
1
Var
(
id
,
desloc
-
1
,
nivelLexico
,
tipo
)
}
}
aplica
(
"AMEM "
+
totalAMEM
)
}
}
def
geraMepaDoId
(
id
:
String
,
nvLexAtual
:
Int
)
:
Unit
=
def
geraMepaDoId
(
id
:
String
,
nvLexAtual
:
Int
)
:
Unit
=
...
@@ -116,10 +138,10 @@ object Tudo {
...
@@ -116,10 +138,10 @@ object Tudo {
rotulo
rotulo
}
}
def
entraProc
(
id
:
String
,
param
s
:
Option
[
List
[
(
Option
[
String
]
,
List
[
String
])]
],
nivelLexico
:
Int
)
:
Unit
=
{
def
entraProc
(
id
:
String
,
dec_p
s
:
Option
[
List
[
dec_param
]
],
nivelLexico
:
Int
)
:
Unit
=
{
val
rotulo
=
entraProcFun
(
nivelLexico
)
val
rotulo
=
entraProcFun
(
nivelLexico
)
param
s
match
{
dec_p
s
match
{
case
Some
(
lstParams
)
if
!
lstParams
.
isEmpty
=>
case
Some
(
lstParams
)
if
!
lstParams
.
isEmpty
=>
val
ps
=
retornaParamsLst
(
lstParams
,
nivelLexico
)
val
ps
=
retornaParamsLst
(
lstParams
,
nivelLexico
)
TabelaSimb
.
insere
(
Procedimento
(
id
,
ps
,
nivelLexico
,
rotulo
)
)
TabelaSimb
.
insere
(
Procedimento
(
id
,
ps
,
nivelLexico
,
rotulo
)
)
...
@@ -135,14 +157,19 @@ object Tudo {
...
@@ -135,14 +157,19 @@ object Tudo {
}
}
}
}
def
entraFunc
(
id
:
String
,
params
:
Option
[
List
[(
Option
[
String
]
,
List
[
String
])]
],
nivelLexico
:
Int
)
:
Unit
=
{
def
entraFunc
(
id
:
String
,
dec_ps
:
Option
[
List
[
dec_param
]],
nivelLexico
:
Int
,
tipo
:
String
)
:
Unit
=
{
val
rotulo
=
entraProcFun
(
nivelLexico
)
val
rotulo
=
entraProcFun
(
nivelLexico
)
if
(
!
TabelaSimb
.
existeTipo
(
tipo
)
){
}
param
s
match
{
dec_p
s
match
{
case
Some
(
lstParams
)
if
!
lstParams
.
isEmpty
=>
case
Some
(
lstParams
)
if
!
lstParams
.
isEmpty
=>
val
ps
=
retornaParamsLst
(
lstParams
,
nivelLexico
)
val
ps
=
retornaParamsLst
(
lstParams
,
nivelLexico
)
val
desloc
=
-
4
-
ps
.
size
val
desloc
=
-
4
-
ps
.
size
TabelaSimb
.
insere
(
Funcao
(
id
,
ps
,
desloc
,
nivelLexico
,
rotulo
)
)
TabelaSimb
.
insere
(
Funcao
(
id
,
ps
,
desloc
,
nivelLexico
,
rotulo
,
tipo
)
)
ps
.
foreach
{
param
=>
ps
.
foreach
{
param
=>
if
(
TabelaSimb
.
temParamOuVarComMesmoId
(
param
.
id
))
{
if
(
TabelaSimb
.
temParamOuVarComMesmoId
(
param
.
id
))
{
println
(
"Erro: Parâmetros com mesmo nome na função "
+
id
+
": "
+
param
.
id
)
println
(
"Erro: Parâmetros com mesmo nome na função "
+
id
+
": "
+
param
.
id
)
...
@@ -155,14 +182,26 @@ object Tudo {
...
@@ -155,14 +182,26 @@ object Tudo {
}
}
}
}
def
retornaParamsLst
(
params
:
List
[(
Option
[
String
]
,
List
[
String
])],
nivelLexico
:
Int
)
:
List
[
Param
]
=
{
def
retornaParamsLst
(
params
:
List
[
dec_param
],
nivelLexico
:
Int
)
:
List
[
Param
]
=
{
var
desloc
=
-
3
-
params
.
map
(
_
.
_2
.
size
).
sum
var
desloc
=
-
3
-
params
.
map
{
_
.
ids
.
size
}.
sum
//Verifica tipos
var
todosTipos
=
params
.
map
{
_
.
tipo
}.
distinct
val
invalido
=
todosTipos
.
find
{
t
=>
!
TabelaSimb
.
existeTipo
(
t
)
}
invalido
match
{
case
Some
(
inv
)
=>
//Erro
println
(
"Erro: Tipo não declarado na declaração de parametros: "
+
inv
)
sys
.
exit
(
1
)
case
None
=>
//Ok
}
//end
params
.
flatMap
{
params
.
flatMap
{
case
(
varOpt
,
idlst
)
=>
case
dec_param
(
byRef
,
idlst
,
tipo
)
=>
idlst
map
{
id
=>
idlst
map
{
id
=>
val
p
=
Param
(
id
,
desloc
,
varOpt
.
isDefined
,
nivelLexico
)
desloc
+=
1
desloc
+=
1
p
Param
(
id
,
desloc
-
1
,
byRef
,
nivelLexico
,
tipo
)
}
}
}
}
}
}
...
@@ -172,6 +211,7 @@ object Tudo {
...
@@ -172,6 +211,7 @@ object Tudo {
case
v
:
Var
=>
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
+
1
)
case
v
:
Var
=>
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
+
1
)
case
p
:
Procedimento
=>
if
(
p
.
nvLex
>
nvLex
)
{
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
)}
else
count
case
p
:
Procedimento
=>
if
(
p
.
nvLex
>
nvLex
)
{
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
)}
else
count
case
f
:
Funcao
=>
if
(
f
.
nvLex
>
nvLex
)
{
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
)}
else
count
case
f
:
Funcao
=>
if
(
f
.
nvLex
>
nvLex
)
{
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
)}
else
count
case
t
:
Tipo
=>
TabelaSimb
.
drop
;
contaVariaveis
(
nvLex
,
count
)
case
r
:
Label
=>
case
r
:
Label
=>
if
(!
r
.
used
)
{
println
(
"Warning: rótulo nunca usado: "
+
r
.
id
)}
if
(!
r
.
used
)
{
println
(
"Warning: rótulo nunca usado: "
+
r
.
id
)}
TabelaSimb
.
drop
TabelaSimb
.
drop
...
@@ -192,6 +232,7 @@ object Tudo {
...
@@ -192,6 +232,7 @@ object Tudo {
table
.
dropWhile
{
table
.
dropWhile
{
case
p
:
Procedimento
=>
if
(
p
.
nvLex
>
nivelLexico
)
true
else
false
case
p
:
Procedimento
=>
if
(
p
.
nvLex
>
nivelLexico
)
true
else
false
case
f
:
Funcao
=>
if
(
f
.
nvLex
>
nivelLexico
)
true
else
false
case
f
:
Funcao
=>
if
(
f
.
nvLex
>
nivelLexico
)
true
else
false
case
t
:
Tipo
=>
true
case
r
:
Label
=>
case
r
:
Label
=>
if
(
r
.
used
)
{
//Se rótulo nunca usado
if
(
r
.
used
)
{
//Se rótulo nunca usado
println
(
"Warning: rótulo nunca usado: "
+
r
.
id
)
println
(
"Warning: rótulo nunca usado: "
+
r
.
id
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment