In einem früheren Artikel habe ich dem Interpreter println hinzugefügt (http://qiita.com/quwahara/items/82067b00cbe1cb974e4a). Dabei haben wir Lexer die Funktion zum Analysieren von "(" und ")" hinzugefügt. Lassen Sie uns außerdem die Priorisierung von Operationen durch Klammern unterstützen.
Ich glaube nicht, dass es einer Erklärung bedarf, aber wenn Sie ein Programm wie das folgende haben, streben wir an, dass der Wert des Berechnungsergebnisses "a" "35" ist.
a = (3 + 4) * 5
Die Implementierung erfolgt für den Parser. Beachten Sie die aktuelle Methode der Syntaxanalyse, um zu überlegen, wo die Syntaxanalyse implementiert werden soll.
Nehmen Sie die Formel ohne Klammern als Beobachtungsziel. Achten Sie beim Parsen eines Ausdrucks ohne Klammern auf die Reihenfolge der 1-Token und darauf, welche Methode sie behandelt.
a = 1 + 2
Das "1" -Token ist das dritte in der Liste der Token und wird von Parsers "lead ()" - Methode verarbeitet.
Betrachten Sie als Nächstes den folgenden Ausdruck mit Klammern, denen Sie entsprechen möchten, und vergleichen Sie ihn mit dem Ausdruck ohne Klammern.
Das dritte Token im Ausdruck in Klammern ist (
.
a = (3 + 4)
Aus der vorherigen Beobachtung geht hervor, dass sich das "(" - Token an derselben Position befindet wie das "1" -Token
Sie können erwarten, dass das Token (
in der Methode lead ()
angezeigt wird.
Und da (
3 + 4nach dem
Token ein normaler Ausdruck ist,
Es kann mit der Methode expression ()
analysiert werden.
Und wenn Sie bestätigen, dass am Ende eine schließende Klammer )
steht, können Sie anscheinend die Syntax analysieren.
Fahren Sie mit der Implementierung fort.
Parser.java
Eine Implementierung von Parser.java.
Der Prozess zum Priorisieren von Klammern wurde dem Teil von "<-Add" hinzugefügt.
Überprüfen Sie zunächst, ob das Token "(" in der Methode "lead ()" angezeigt wird.
Halten Sie das Analyseergebnis des Ausdrucks in Klammern mit "Token expr = expression (0)".
Verwenden Sie dann consumer (") ")
, um sicherzustellen, dass eine schließende Klammer vorhanden ist.
Der Rückgabewert ist das beibehaltene Analyseergebnis.
Das ist alles für die Korrespondenz.
Parser.java
private Token lead(Token token) throws Exception {
if (factorKinds.contains(token.kind)) {
return token;
} else if(token.kind.equals("paren") && token.value.equals("(")) { // <-- Add
Token expr = expression(0);
consume(")");
return expr;
} else {
throw new Exception("The token cannot place there.");
}
}
Interpreter.java
Eine Implementierung von Interpreter.java.
Spiegelt es die Entsprechung priorisierter Klammern wider?
String text =" a = (3 + 4) * 5 ";
wurde in einen Ausdruck mit Klammern geändert.
In der Standardausgabe sollte "35" angezeigt werden.
Interpreter.java
public static void main(String[] args) throws Exception {
String text = "a = (3 + 4) * 5"; // <-- Update
text += "println(a)";
List<Token> tokens = new Lexer().init(text).tokenize();
List<Token> blk = new Parser().init(tokens).block();
new Interpreter().init(blk).run();
// --> 35
}
Das ist alles für die Implementierung. Vielen Dank.
Die vollständige Quelle finden Sie hier.
Calc https://github.com/quwahara/Calc/tree/article-5-parenthesis/Calc/src/main/java
Es gibt einen Folgeartikel.
** Unterstützt einmalige Operationen ** http://qiita.com/quwahara/items/4069d47b511e4d11f44b
Recommended Posts