Für diejenigen, die POJ (Pascal auf der JVM) nicht befolgen: Es handelt sich um einen Compiler, der eine Teilmenge von Pascal in JASM umwandelt ( Java Assembly), damit wir die JVM als Ausführungsumgebung verwenden können.
Im letzten Beitrag wurden Kontexte (vom Parser) und verschachtelte Sätze besprochen. In dieser Veröffentlichung werden wir über die Änderungen sprechen, die notwendig sind, um das Lesen von Daten aus der Standardeingabe (stdin) mithilfe der Funktion read/readln von Pascal zu ermöglichen .
Während wir für die JVM kompilieren, ist es notwendig, die Funktionsweise verschiedener Punkte dieser unglaublichen virtuellen Maschine im Detail zu beschreiben. Daher erläutere ich an verschiedenen Stellen die interne Funktionsweise der JVM sowie einige ihrer Anweisungen (Opcodes).
Standardeingabe (stdin) ist der Stream, aus dem ein Programm seine Eingabedaten liest. Bisher haben wir nur stdout (Standardausgabe) unterstützt.
In diesem Commit wurde ein Java-Programm implementiert, um zu verstehen, wie die JVM mit stdin:
umgeht
public class InputData { public static String name; public static int age; public static void main(String[] args) { name = System.console().readLine(); age = Integer.parseInt(System.console().readLine()); System.out.println("You entered string " + name); }
Wenn wir die Datei Klasse zerlegen, erhalten wir die Assembly unten. Irrelevante Snippets wurden weggelassen und der ursprüngliche Snippet (in Java), der zu assembly führte, wurde mit „;;“:
eingefügt
1: public class InputData { 2: ;; public static String name; 3: public static name java/lang/String 4: 5: ;; public static int age; 6: public static age I 7: 8: public static main([java/lang/String)V { 9: ;; name = System.console().readLine(); 10: invokestatic java/lang/System.console()java/io/Console 11: invokevirtual java/io/Console.readLine()java/lang/String 12: putstatic InputData.name java/lang/String 13: 14: ;; age = Integer.parseInt(System.console().readLine()); 15: invokestatic java/lang/System.console()java/io/Console 16: invokevirtual java/io/Console.readLine()java/lang/String 17: invokestatic java/lang/Integer.parseInt(java/lang/String)I 18: putstatic InputData.age I 19: 20: ;; System.out.println("You entered string " + name); 21: getstatic java/lang/System.out java/io/PrintStream 22: getstatic InputData.name java/lang/String 23: invokedynamic makeConcatWithConstants(java/lang/String)java/lang/String { invokestatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants(java/lang/invoke/MethodHandles$Lookup, java/lang/String, java/lang/invoke/MethodType, java/lang/String, [java/lang/Object)java/lang/invoke/CallSite ["You entered string "] } 24: 25: invokevirtual java/io/PrintStream.println(java/lang/String)V 26: 27: return } }
Anhand dieses Beispiels konnte festgestellt werden, dass zum Lesen von Daten aus stdin die Anweisung System.console().readLine() verwendet werden musste (Zeilen 11 und 16). ). Und da readLine() einen String zurückgibt, war zum Lesen von Zahlen eine Konvertierung mit der Funktion Integer.parseInt (Zeile 17) erforderlich.
Das heißt, aus dem Pascal-Programm unten:
program NameAndAge; var myname: string; myage: integer; begin write('What is your name? '); readln(myname); write('How old are you? '); readln(myage); writeln; writeln('Hello ', myname); writeln('You are ', myage, ' years old'); end.
POJ wurde angepasst, um den folgenden JASM zu generieren:
// Code generated by POJ 0.1 public class name_and_age { ;; var myname: string; public static myname java/lang/String ;; var myage: integer; public static myage I ;; procedure main public static main([java/lang/String)V { ;; write('What is your name? '); getstatic java/lang/System.out java/io/PrintStream ldc "What is your name? " invokevirtual java/io/PrintStream.print(java/lang/String)V ;; readln(myname); invokestatic java/lang/System.console()java/io/Console invokevirtual java/io/Console.readLine()java/lang/String putstatic name_and_age.myname java/lang/String ;; write('How old are you? '); getstatic java/lang/System.out java/io/PrintStream ldc "How old are you? " invokevirtual java/io/PrintStream.print(java/lang/String)V ;; readln(myage); invokestatic java/lang/System.console()java/io/Console invokevirtual java/io/Console.readLine()java/lang/String invokestatic java/lang/Integer.parseInt(java/lang/String)I putstatic name_and_age.myage I ;; writeln; getstatic java/lang/System.out java/io/PrintStream invokevirtual java/io/PrintStream.println()V ;; writeln('Hello ', myname); getstatic java/lang/System.out java/io/PrintStream ldc "Hello " invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream getstatic name_and_age.myname java/lang/String invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream invokevirtual java/io/PrintStream.println()V ;; writeln('You are ', myage, ' years old'); getstatic java/lang/System.out java/io/PrintStream ldc "You are " invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream getstatic name_and_age.myage I invokevirtual java/io/PrintStream.print(I)V getstatic java/lang/System.out java/io/PrintStream ldc " years old" invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream invokevirtual java/io/PrintStream.println()V return } }
Dieser Commit implementiert die notwendigen Änderungen am POJ-Parser.
Hier ist die vollständige PR.
In der nächsten Veröffentlichung werden wir eines der Ziele dieses Projekts erreichen: die rekursive Berechnung der Fakultät.
Das Repository mit dem vollständigen Code und der Dokumentation des Projekts finden Sie hier.
Das obige ist der detaillierte Inhalt vonDaten aus der Standardeingabe lesen (stdin). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!