-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.dart
98 lines (82 loc) · 2.67 KB
/
main.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import 'dart:io';
void main(List<String> args) async{
if(args.length < 1){
print("Utilize dart main.dart caminhoEntrada");
return;
}
String caminhoEntrada = args[0];
String entrada = await lerArquivo(caminhoEntrada);
List<Regra> regrasCalculadora = [Regra(exp: RegExp(r"^[0-9]+[.][0-9]+"), nome: "numero real"),
Regra(exp: RegExp(r"^[0-9]+"), nome: "numero"),
Regra(exp: RegExp(r"^[+]"), nome: "operador de adição"),
Regra(exp: RegExp(r"^[-]"), nome: "operador de subtração"),
Regra(exp: RegExp(r"^[*]"), nome: "operador de multiplicação"),
Regra(exp: RegExp(r"^[/]"), nome: "operador de divisão"),
Regra(exp: RegExp(r"^[ ]"), nome: "espaço em branco"),
Regra(exp: RegExp(r"^[)]"), nome: "fecha parenteses"),
Regra(exp: RegExp(r"^[(]"), nome: "abre parenteses"),
];
Tokenizador t = Tokenizador(regras: regrasCalculadora);
var result = t.analisar(entrada);
for(var k in result.keys){
print("${k?.nome ?? "erro"}: ${result[k].fold("", (p, n) => p + n.valor + ", ")}");
}
}
class Tokenizador {
List<Regra> regras;
Tokenizador({this.regras});
Map<Regra, List<Token>> analisar(String entrada,{ bool imprimirDados = false}) {
Map<Regra, List<Token>> tokens = Map();
for(Regra r in regras){
tokens[r] = <Token>[];
}
tokens[null] = <Token>[];
while(!entrada.isEmpty){
if(imprimirDados) ("Analisando $entrada");
Token atual;
for(Regra r in regras){
var match = r.exp.firstMatch(entrada);
if(imprimirDados) print("Match para regra ${r.nome}: ${match?.pattern}");
if(match != null && (atual == null || atual.inicio > match.start)){
atual = Token(regra: r, valor: match.group(0), inicio: match.start, fim: match.end);
}
}
if(atual == null){
tokens[null].add(Token(valor: entrada.substring(0, 1)));
entrada = entrada.substring(1, entrada.length);
}
else {
tokens[atual.regra].add(atual);
if(atual.inicio != 0){
tokens[null].add(Token(valor: entrada.substring(0, atual.inicio)));
}
entrada = entrada.substring(atual.fim, entrada.length);
}
}
return tokens;
}
}
class Token {
int inicio;
int fim;
final String valor;
final Regra regra;
Token({this.valor, this.regra, this.inicio, this.fim});
String toString(){
return "$regra -> $valor";
}
}
class Regra {
final RegExp exp;
final String nome;
bool seAplica(String alvo){
return exp.hasMatch(alvo);
}
const Regra({this.exp, this.nome});
String toString(){
return "$nome : ${exp.pattern}";
}
}
Future<String> lerArquivo(String caminho) {
return new File(caminho).readAsString();
}