考虑一种假设的编程语言,其中包含以下规则:
每个函数都以关键字“BEGIN”开头,然后是其名称 在每个函数的末尾,必须有关键字“END”。
要调用函数,在函数名称之前使用关键字“CALL”。关键字“EXECUTE”表示:“在没有其他函数帮助的情况下执行某些操作”。
“完成”这个词在我们的任务中不是我们关注的问题! 程序始终以行开头:“BEGIN Main”。
假设某些代码是根据上述规则编写的,并存储在名为“code.prog”的文件中。在此文件中,还假设每行开头都有“行号”。
编写一个读取此代码(code.prog)的C程序,并用行号打印执行。 对于这项工作,你应该为函数调用创建一个行号的堆栈。因此,另外,为每个“函数调用”和“函数结束”打印堆栈的内容。
EXAMPLE
code.prg // this is the file
1 BEGIN Fun1
2 CALL Fun2
3 EXECUTE
4 END
5 BEGIN Fun2
6 EXECUTE
7 END
8 BEGIN Main
9 EXECUTE
10 CALL Fun1
11 END
代码输出:
Execution Order of Lines:
8
9
10 Stack = 10
1
2 Stack = 2 10
5
6
7 Stack = 10
3
4 Stack =
11 --- END ---
答案 0 :(得分:1)
您应该知道如何解析和执行编程语言。 如果您需要更深入的信息,我建议您阅读Peter Van Roy撰写的“计算机编程的概念,模型和技术”。
您的编程语言由语法,语义和语用学构成。您的作业文本描述了编程语言的语法规则(语法)。这些规则对于在您的语言中编写有效的句子非常有用。 解释器可以理解有效句子,然后执行。 在执行期间,您基本上为每个句子分配语义含义。
以下是步骤:
BEGIN
是一个标记,CALL
是一个标记,函数名也是标记(函数标识符)。 tokenizer分析您的源代码(这是一个简单的字符串)并创建一个令牌列表。
Text files -> [TOKENIZER] -> sequence of token
BEGIN
标记开头,后跟identifier
标记,后跟一个或多个instruction
标记,以END
标记结尾。您必须创建解析树(https://en.wikipedia.org/wiki/Parse_tree)。解析树的节点是非终止符号,叶子是终结符号(令牌)。
Sequence of token -> [PARSER] -> Parse tree
实现:
标记生成器和解析器只是有限状态机。 解释器基本上是一个程序,它可以转换执行堆栈中的解析树,从中执行每个指令并执行。