对于那些不遵循 poj(jvm 上的 pascal)的人来说,它是一个编译器,将子集从 pascal 转换为 jasm(java 程序集),以便我们可以使用 jvm 作为执行环境。
在上一篇文章中,讨论了上下文(来自parser)和嵌套句子。在本出版物中,我们将讨论使用 pascal 的 read/readln 函数从标准输入 (stdin) 读取数据所需的更改。
当我们为 jvm 进行编译时,有必要详细说明这个令人难以置信的虚拟机的各个点的功能。因此,我多次详细介绍 jvm 的内部工作原理以及它的一些指令(操作码)。
从stdin(标准输入)读取数据
标准输入(stdin)是程序从中读取输入数据的流。到目前为止,我们仅支持stdout(标准输出)。
在这个commit中,实现了一个java程序来了解jvm如何处理stdin:
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); }
当我们反汇编 class 文件时,我们得到下面的程序集。不相关的片段被省略,并且产生汇编的原始片段(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。
下一步
在下一篇文章中,我们将完成该项目的目标之一:递归计算阶乘。
完整的项目代码
包含项目完整代码和文档的存储库在这里。
想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » 从标准输入(stdin)读取数据
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » 从标准输入(stdin)读取数据