POJ (JVM 上の Pascal) をフォローしていない人のために説明すると、これは サブセット を Pascal から JASM に変換するコンパイラーです ( Java アセンブリ) を使用して、JVM を実行環境として使用できるようにします。
前回の投稿では、コンテキスト (パーサー から) とネストされた文について説明しました。この出版物では、Pascal の read/readln 関数を使用して、標準入力 (stdin) からデータを読み取れるようにするために必要な変更について説明します。 .
JVM 用にコンパイルしているので、この素晴らしい仮想マシンのさまざまな点の機能を詳しく説明する必要があります。したがって、私はさまざまな機会に、JVM の内部機能とその命令 (オペコード) の一部について詳しく説明します。
標準入力 (stdin) は、プログラムが入力データを読み取るストリームです。これまでは stdout (標準出力) のみをサポートしていました。
この commit では、JVM が stdin をどのように処理するかを理解するために Java プログラムが実装されました。
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); }
ファイルクラスを逆アセンブルすると、以下のアセンブリが得られます。無関係なスニペットは省略され、アセンブリ を生成した元のスニペット (Java 内) が ";;":
とともに挿入されました。
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 } }
この例では、stdin からデータを読み取るには、System.console().readLine() 命令を使用する必要があることがわかりました (11 行目と 16 行目) )。 readLine() は文字列を返すため、数値を読み取るには関数 Integer.parseInt (17 行目) を使用して変換する必要がありました。
つまり、以下の Pascal プログラムから:
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 は次の JASM を生成するように調整されました:
// 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 } }
このコミットは、POJ パーサーに必要な変更を実装します。
これが完全な PR です。
次の出版物では、このプロジェクトの目的の 1 つである階乗を再帰的に計算することを完了します。
プロジェクトの完全なコードとドキュメントが含まれるリポジトリはここにあります。
以上が標準入力 (stdin) からのデータの読み取りの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。