卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章72459本站已运行430

从标准输入(stdin)读取数据

从标准输入(stdin)读取数据

对于那些不遵循 poj(jvm 上的 pascal)的人来说,它是一个编译器,将子集从 pascal 转换为 jasm(java 程序集),以便我们可以使用 jvm 作为执行环境。

在上一篇文章中,讨论了上下文(来自parser)和嵌套句子。在本出版物中,我们将讨论使用 pascalread/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。

下一步

在下一篇文章中,我们将完成该项目的目标之一:递归计算阶乘。

完整的项目代码

包含项目完整代码和文档的存储库在这里。

卓越飞翔博客
上一篇: php会话控制有哪些
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏