-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParser.java
More file actions
141 lines (112 loc) · 3.98 KB
/
Copy pathParser.java
File metadata and controls
141 lines (112 loc) · 3.98 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
Laboratorio No. 3 - Recursive Descent Parsing
CC4 - Compiladores
Clase que representa el parser
Actualizado: agosto de 2021, Luis Cu
*/
import java.util.LinkedList;
import java.util.Stack;
public class Parser {
// Puntero next que apunta al siguiente token
private int next;
// Stacks para evaluar en el momento
private Stack<Double> operandos;
private Stack<Token> operadores;
// LinkedList de tokens
private LinkedList<Token> tokens;
// Funcion que manda a llamar main para parsear la expresion
public boolean parse(LinkedList<Token> tokens) {
this.tokens = tokens;
this.next = 0;
this.operandos = new Stack<Double>();
this.operadores = new Stack<Token>();
// Recursive Descent Parser
// Imprime si el input fue aceptado
System.out.println("Aceptada? " + S());
// Shunting Yard Algorithm
// Imprime el resultado de operar el input
// System.out.println("Resultado: " + this.operandos.peek());
// Verifica si terminamos de consumir el input
if(this.next != this.tokens.size()) {
return false;
}
return true;
}
// Verifica que el id sea igual que el id del token al que apunta next
// Si si avanza el puntero es decir lo consume.
private boolean term(int id) {
if(this.next < this.tokens.size() && this.tokens.get(this.next).equals(id)) {
// Codigo para el Shunting Yard Algorithm
/*
if (id == Token.NUMBER) {
// Encontramos un numero
// Debemos guardarlo en el stack de operandos
operandos.push( this.tokens.get(this.next).getVal() );
} else if (id == Token.SEMI) {
// Encontramos un punto y coma
// Debemos operar todo lo que quedo pendiente
while (!this.operadores.empty()) {
popOp();
}
} else {
// Encontramos algun otro token, es decir un operador
// Lo guardamos en el stack de operadores
// Que pushOp haga el trabajo, no quiero hacerlo yo aqui
pushOp( this.tokens.get(this.next) );
}
*/
this.next++;
return true;
}
return false;
}
// Funcion que verifica la precedencia de un operador
private int pre(Token op) {
/* TODO: Su codigo aqui */
/* El codigo de esta seccion se explicara en clase */
switch(op.getId()) {
case Token.PLUS:
return 1;
case Token.MULT:
return 2;
default:
return -1;
}
}
private void popOp() {
Token op = this.operadores.pop();
/* TODO: Su codigo aqui */
/* El codigo de esta seccion se explicara en clase */
if (op.equals(Token.PLUS)) {
double a = this.operandos.pop();
double b = this.operandos.pop();
// print para debug, quitarlo al terminar
System.out.println("suma " + a + " + " + b);
this.operandos.push(a + b);
} else if (op.equals(Token.MULT)) {
double a = this.operandos.pop();
double b = this.operandos.pop();
// print para debug, quitarlo al terminar
System.out.println("mult " + a + " * " + b);
this.operandos.push(a * b);
}
}
private void pushOp(Token op) {
/* TODO: Su codigo aqui */
/* Casi todo el codigo para esta seccion se vera en clase */
// Si no hay operandos automaticamente ingresamos op al stack
// Si si hay operandos:
// Obtenemos la precedencia de op
// Obtenemos la precedencia de quien ya estaba en el stack
// Comparamos las precedencias y decidimos si hay que operar
// Es posible que necesitemos un ciclo aqui, una vez tengamos varios niveles de precedencia
// Al terminar operaciones pendientes, guardamos op en stack
}
private boolean S() {
return E() && term(Token.SEMI);
}
private boolean E() {
return false;
}
/* TODO: sus otras funciones aqui */
}