Skip to content

Commit 3371b51

Browse files
committed
Alterada a gramática da unidade de compilação para suportar escopos de arquivo inteiro. Desta forma ao declarar um programa por exemplo, se finalizar o nome do programa com um ponto e vírgula não será mais necessário delimitar o restante do programa com chaves.
1 parent a2e3aee commit 3371b51

17 files changed

+508
-455
lines changed

README.md

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,52 +16,51 @@ Uma nova gramática foi criada para ser aceita por este compilador, a sintaxe de
1616
A seguir, temos um exemplo simples de um programa escrito nessa linguagem:
1717

1818
```c++
19-
programa TesteUnidades
20-
{
21-
usando Sorts;
19+
programa TesteUnidades;
20+
21+
usando Sorts;
2222

23-
{
24-
// Teste da unidade padrão System:
23+
{
24+
// Teste da unidade padrão System:
2525
26-
var str:texto = "abcdefgh"; // string dinâmica contada por referência
27-
str = str + "1234567890";
28-
escrevaln "\"abcdefgh\" + \"1234567890\" = \"", str, '"';
26+
var str:texto = "abcdefgh"; // string dinâmica contada por referência
27+
str = str + "1234567890";
28+
escrevaln "\"abcdefgh\" + \"1234567890\" = \"", str, '"';
2929
30-
escrevaln "Tamanho do texto \"", str, "\" = ", str.tamanho;
30+
escrevaln "Tamanho do texto \"", str, "\" = ", str.tamanho;
3131
32-
var str2:char[16]; // string estática
33-
CopiaString("4567", str2);
34-
var str2Int:int;
35-
StringParaInt(str2, str2Int);
36-
escrevaln "StringParaInt(\"", str2, "\")=", str2Int;
32+
var str2:char[16]; // string estática
33+
CopiaString("4567", str2);
34+
var str2Int:int;
35+
StringParaInt(str2, str2Int);
36+
escrevaln "StringParaInt(\"", str2, "\")=", str2Int;
3737

38-
// saída esperada:
39-
// "abcdefgh" + "1234567890" = "abcdefgh1234567890"
40-
// Tamanho do texto "abcdefgh1234567890" = 18;
41-
// StringParaInt("4567")=4567
38+
// saída esperada:
39+
// "abcdefgh" + "1234567890" = "abcdefgh1234567890"
40+
// Tamanho do texto "abcdefgh1234567890" = 18;
41+
// StringParaInt("4567")=4567
4242

43-
// Teste da unidade Sorts:
44-
// teste de entrada: {9, -2, 6, 3)
43+
// Teste da unidade Sorts:
44+
// teste de entrada: {9, -2, 6, 3)
4545

46-
var a:int[4];
46+
var a:int[4];
4747

48-
para (var i:int = 0; i < 4; i++)
49-
{
50-
escrevaln "Digite um númeero inteiro para a[", i, "]";
51-
leia a[i];
52-
}
48+
para (var i:int = 0; i < 4; i++)
49+
{
50+
escrevaln "Digite um númeero inteiro para a[", i, "]";
51+
leia a[i];
52+
}
5353

54-
QuickSort(a, 0, 3);
54+
QuickSort(a, 0, 3);
5555

56-
escreva "{", a[0];
57-
para (var i:int = 1; i < 4; i++)
58-
escreva ", ", a[i];
56+
escreva "{", a[0];
57+
para (var i:int = 1; i < 4; i++)
58+
escreva ", ", a[i];
5959

60-
escrevaln "}";
60+
escrevaln "}";
6161

62-
// saída esperada:
63-
// {-2, 3, 6, 9)
64-
}
62+
// saída esperada:
63+
// {-2, 3, 6, 9)
6564
}
6665
```
6766

compiler/CompilerParser.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ private Statement ParseStatement()
858858
private BlockStatement ParseBlock()
859859
{
860860
BlockStatement result = new(lexer.CurrentInterval());
861+
861862
while (lexer.NextSymbol("}", false) == null)
862863
{
863864
Statement statement = ParseStatement();
@@ -951,7 +952,7 @@ private void AddImport(SourceInterval interval, string unityName)
951952
}
952953
}
953954

954-
private bool ParseDeclaration()
955+
private bool ParseDeclaration(bool endsWithBraces = true)
955956
{
956957
Keyword kw = lexer.NextKeyword(false);
957958
if (kw != null)
@@ -1010,7 +1011,9 @@ private bool ParseDeclaration()
10101011
return true;
10111012
}
10121013

1013-
lexer.NextSymbol("}", true, "Declaração ou '}' esperados.");
1014+
if (endsWithBraces)
1015+
lexer.NextSymbol("}", true, "Declaração ou '}' esperados.");
1016+
10141017
return false;
10151018
}
10161019

@@ -1063,9 +1066,18 @@ private CompilationUnity ParseCompilationUnity(string fileName, TextReader input
10631066
if (!isUnity)
10641067
program = unity;
10651068

1066-
lexer.NextSymbol("{");
1069+
bool endsWithBraces;
1070+
if (!lexer.IsNextSymbol("{"))
1071+
{
1072+
lexer.NextSymbol(";", true, "Declaração, '{' ou ';' esperados.");
1073+
endsWithBraces = false;
1074+
}
1075+
else
1076+
{
1077+
endsWithBraces = true;
1078+
}
10671079

1068-
while (ParseDeclaration())
1080+
while (ParseDeclaration(endsWithBraces))
10691081
{
10701082
}
10711083

@@ -1102,9 +1114,18 @@ private void ParseCompilationUnity(CompilationUnity unity)
11021114
if (unity.Name != name)
11031115
throw new CompilerException(id.Interval, "Nome da unidade é diferente do nome do arquivo.");
11041116

1105-
lexer.NextSymbol("{");
1117+
bool endsWithBraces;
1118+
if (!lexer.IsNextSymbol("{"))
1119+
{
1120+
lexer.NextSymbol(";", true, "Declaração, '{' ou ';' esperados.");
1121+
endsWithBraces = false;
1122+
}
1123+
else
1124+
{
1125+
endsWithBraces = true;
1126+
}
11061127

1107-
while (ParseDeclaration())
1128+
while (ParseDeclaration(endsWithBraces))
11081129
{
11091130
}
11101131

compiler/lexer/Lexer.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,18 @@ public Token NextToken()
749749
return result;
750750
}
751751

752+
public bool IsNextToken()
753+
{
754+
var token = NextToken();
755+
if (token == null)
756+
{
757+
PreviusToken();
758+
return false;
759+
}
760+
761+
return true;
762+
}
763+
752764
public NumericLiteral NextNumber(bool throwException = true, string errorMessage = null)
753765
{
754766
Token token = NextToken();
@@ -773,6 +785,11 @@ public NumericLiteral NextNumber(bool throwException = true, string errorMessage
773785
return (NumericLiteral) token;
774786
}
775787

788+
public bool IsNextNumber()
789+
{
790+
return NextNumber(false) != null;
791+
}
792+
776793
public Symbol NextSymbol(bool throwException = true, string errorMessage = null)
777794
{
778795
Token token = NextToken();
@@ -797,6 +814,11 @@ public Symbol NextSymbol(bool throwException = true, string errorMessage = null)
797814
return (Symbol) token;
798815
}
799816

817+
public bool IsNextSymbol()
818+
{
819+
return NextSymbol(false) != null;
820+
}
821+
800822
public Symbol NextSymbol(string expectedValue, bool throwException = true, string errorMessage = null)
801823
{
802824
Token token = NextToken();
@@ -831,6 +853,11 @@ public Symbol NextSymbol(string expectedValue, bool throwException = true, strin
831853
return symbol;
832854
}
833855

856+
public bool IsNextSymbol(string expectedValue)
857+
{
858+
return NextSymbol(expectedValue, false) != null;
859+
}
860+
834861
public Keyword NextKeyword(bool throwException = true, string errorMessage = null)
835862
{
836863
Token token = NextToken();
@@ -855,6 +882,11 @@ public Keyword NextKeyword(bool throwException = true, string errorMessage = nul
855882
return (Keyword) token;
856883
}
857884

885+
public bool IsNextKeyword()
886+
{
887+
return NextKeyword(false) != null;
888+
}
889+
858890
public Keyword NextKeyword(string expectedValue, bool throwException = true, string errorMessage = null)
859891
{
860892
Token token = NextToken();
@@ -889,6 +921,11 @@ public Keyword NextKeyword(string expectedValue, bool throwException = true, str
889921
return keyword;
890922
}
891923

924+
public bool IsNextKeyword(string expectedValue)
925+
{
926+
return NextKeyword(expectedValue, false) != null;
927+
}
928+
892929
public Identifier NextIdentifier(bool throwException = true, string errorMessage = null)
893930
{
894931
Token token = NextToken();
@@ -913,6 +950,11 @@ public Identifier NextIdentifier(bool throwException = true, string errorMessage
913950
return (Identifier) token;
914951
}
915952

953+
public bool IsNextIdentifier()
954+
{
955+
return NextIdentifier(false) != null;
956+
}
957+
916958
public Identifier NextIdentifier(string expectedValue, bool throwException = true, string errorMessage = null)
917959
{
918960
Token token = NextToken();
@@ -947,6 +989,11 @@ public Identifier NextIdentifier(string expectedValue, bool throwException = tru
947989
return variable;
948990
}
949991

992+
public bool IsNextIdentifier(string expectedValue)
993+
{
994+
return NextIdentifier(expectedValue, false) != null;
995+
}
996+
950997
public Token PreviusToken()
951998
{
952999
if (tokenIndex < 0)

examples/Binario.sl

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
1-
programa Binario
1+
programa Binario;
2+
23
{
3-
{
4-
var n:int;
4+
var n:int;
55

6-
escrevaln "Digite um número inteiro:";
7-
leia n;
6+
escrevaln "Digite um número inteiro:";
7+
leia n;
88

9-
escreva "Seu valor em binário é ";
9+
escreva "Seu valor em binário é ";
1010

11-
var i:int;
12-
var b:bool = falso;
13-
para (i = 31; i >= 0; i = i - 1)
11+
var i:int;
12+
var b:bool = falso;
13+
para (i = 31; i >= 0; i = i - 1)
14+
{
15+
se ((n & (1 << i)) != 0)
1416
{
15-
se ((n & (1 << i)) != 0)
16-
{
17-
b = verdade;
18-
escreva 1;
19-
}
20-
senão se (b)
21-
escreva 0;
17+
b = verdade;
18+
escreva 1;
2219
}
23-
24-
se (!b)
20+
senão se (b)
2521
escreva 0;
26-
27-
escrevaln;
2822
}
23+
24+
se (!b)
25+
escreva 0;
26+
27+
escrevaln;
2928
}

examples/NumerosPerfeitos.sl

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
1-
programa NumerosPerfeitos
1+
programa NumerosPerfeitos;
2+
3+
função É_Divisor(a:int, b:int):bool
24
{
3-
função É_Divisor(a:int, b:int):bool
4-
{
5-
retorne b % a == 0;
6-
}
5+
retorne b % a == 0;
6+
}
77

8-
função É_Perfeito(n:int):bool
8+
função É_Perfeito(n:int):bool
9+
{
10+
var soma:int = 0;
11+
var i:int;
12+
para (i = 1; i < n; i = i + 1)
913
{
10-
var soma:int = 0;
11-
var i:int;
12-
para (i = 1; i < n; i = i + 1)
13-
{
14-
se (É_Divisor(i, n))
15-
soma += i;
16-
}
17-
18-
retorne soma == n;
14+
se (É_Divisor(i, n))
15+
soma += i;
1916
}
17+
18+
retorne soma == n;
19+
}
2020

21-
{
22-
var n:int;
21+
{
22+
var n:int;
2323

24-
escrevaln "Digite um número inteiro:";
25-
leia n;
24+
escrevaln "Digite um número inteiro:";
25+
leia n;
2626

27-
se (É_Perfeito(n))
28-
escrevaln n, " é perfeito.";
29-
senão
30-
escrevaln n, " não é perfeito.";
31-
}
27+
se (É_Perfeito(n))
28+
escrevaln n, " é perfeito.";
29+
senão
30+
escrevaln n, " não é perfeito.";
3231
}

examples/OláMundo.sl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
programa OláMundo
1+
programa OláMundo;
2+
23
{
3-
{
4-
escrevaln "Olá mundo!";
5-
}
4+
escrevaln "Olá mundo!";
65
}

0 commit comments

Comments
 (0)