当前位置:首页 » 编程软件 » pl0编译程序的源程序在哪

pl0编译程序的源程序在哪

发布时间: 2022-07-05 02:25:27

① Linux编译c语言,源程序文件放在什么路径

改名:mv hello hello.c
编译:首先cd到你源文件的那个目录下,这样省去了指定绝对路径的麻烦,比如cd到桌面,然后:gcc hello.c -o hello
运行:./hello

② 什么是文件的源程序怎样打开文件的源程序

1.理论上的概念
源代码是相对目标代码和可执行代码而言的。
源代码就是用汇编语言和高级语言写出来的地代码。
目标代码是指源代码经过编译程序产生的能被cpu直接识别二进制代码。
可执行代码就是将目标代码连接后形成的可执行文件,当然也是二进制的。
2.最直观的概念
在这个网页上右键鼠标,选择查看源文件.出来一个记事本,里面的内容就是此网页的源代码.
===================================================
关于两者的区别联系:
1.从字面意义上来讲,源文件是指一个文件,指源代码的集合.源代码则是一组具有特定意义的可以实现特定功能的字符(程序开发代码).
2."源代码"在大多数时候等于"源文件".
枫舞在上面说过"2.最直观的概念 在这个网页上右键鼠标,选择查看源文件.出来一个记事本,里面的内容就是此网页的源代码."这句话就体现了他们的关系,此处的源文件是指网页的源文件,而源代码就是源文件的内容,所以又可以称做网页的源代码..

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
枫舞添言:
1.枫舞有个好朋友认为“源代码”就是“原始人写出的代码”,枫舞一直也没有时间考察他的正确性 ^-^
2.枫舞忽然想起小时候造句,突发奇想给你造个句子肯定可以帮助理解..

关键词:源文件
造句:小赵,帮我把源文件拷贝到我的硬盘.复制两份.文件名定为file1.asp file2.asp
关键词:源代码
造句:小李,把源代码中的第8行删除.哦~源代码(源文件亦可)小赵发到我硬盘了,待会给你传过去.就是file1.asp.

③ 软件的源程序装在哪里

不管是什么语言写的,最终都会编译成二进制文件,在编译后的程序是找不到源代码的。除非是反编译程序来实现,当然像.net的程序是可以基本反编译的,反出来的代码和原来编译前的基本一致,像VB,VC等编程语言是没有反编译程序的,除了拿到作者的源代码,否则看不到源代码。

不过,有反汇编的方式,这个方式看到的是汇编代码,分析这些可以分析程序的行为等,这就不详细说了。

good luck

④ pl0怎么扩展++,--功能

那我给你网站吧,我找很久了.那个东西是很需要的
http://download.csdn.net/source/191218
PL/0语言是Pascal语言的一个子集,这里分析的PL/0的编译程序包括了对PL/0语
言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法分析和代码生成作为独立的子程序供语法分析程序调用。语法分析的同时,提供了出错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。
2.各功能模块描述

词法分析子程序分析:
词法分析子程序名为GETSYM,功能是从源程序中读出一个单词符号(TOTAKEN),把它的信息放入全局变量 SYM、ID和NUM中,字符变量放入CH中,语法分析器需要单词时,直接从这三个变量中获得。Getch过程通过反复调用Getch子过程从源程序过获取字符,并把它们拼成单词。GETCH过程中使用了行缓冲区技术以提高程序运行效率。
词法分析器的分析过程:调用GETSYM时,它通过GETCH过程从源程序中获得一个字符。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把SYM变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把SYM置为IDENT,把这个单词存入ID变量。查保留字表时使用了二分法查找以提高效率。如果Getch获得的字符是数字,则继续用Getch获取数字,并把它们拼成一个整数或实数,然后把SYM置为 INTEGER或REAL,并把拼成的数值放入NUM变量。如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把SYM则成相应的类型。如果遇到不合法的字符,把SYM置成NUL。

语法分析子程序分析:
语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语义生成相应三元代码,并提供了出错处理的机制。语法分析主要由分程序分析过程(BLOCK)、参数变量分析过程(ParaDeclaration)、参数变量处理过程(ParaGetSub)、数组处理过程(ParaGetSub)、常量定义分析过程(ConstDeclaration)、变量定义分析过程(Vardeclaration)、语句分析过程(Statement)、表达式处理过程(Expression)、项处理过程(Term)、因子处理过程(Factor)和条件处理过程(Condition)构成。这些过程在结构上构成一个嵌套的层次结构。除此之外,还有出错报告过程(Error)、代码生成过程(Gen)、测试单词合法性及出错恢复过程(Test)、登录名字表过程(Enter)、查询名字表函数(Position)以及列出类 PCODE代码过程(Listcode)作过语法分析的辅助过程。
由PL/0的语法图可知:一个完整的PL/0程序是由分程序和句号构成的。因此,本编译程序在运行的时候,通过主程序中调用分程序处理过程block来分析分程序部分(分程序分析过程中还可能会递归调用block过程),然后,判断最后读入的符号是否为句号。如果是句号且分程序分析中未出错,则是一个合法的PL/0程序,可以运行生成的代码,否则就说明源PL/0程序是不合法的,输出出错提示即可。
下面按各语法单元分析PL/0编译程序的运行机制。

分程序处理过程:
语法分析开始后,首先调用分程序处理过程(Block)处理分程序。过程入口参数置为:0层、符号表位置0、出错恢复单词集合为句号、声明符或语句开始符。进入Block过程后,首先把局部数据段分配指针设为3,准备分配3个单元供运行期存放静态链SL、动态链DL 和返回地址RA。然后用Tx0记录下当前符号表位置并产生一条Jmp指令,准备跳转到主程序的开始位置,由于当前还没有知到主程序究竟在何处开始,所以 Jmp的目标暂时填为0,稍后再改。同时在符号表的当前位置记录下这个Jmp指令在代码段中的位置。在判断了嵌套层数没有超过规定的层数后,开始分析源程序。首先判断是否遇到了常量声明,如果遇到则开始常量定义,把常量存入符号表。接下去用同样的方法分析变量声明,变量定义过程中会用Dx变量记录下局部数据段分配的空间个数。然后如果遇到Procere保留字则进行过程声明和定义,声明的方法是把过程的名字和所在的层次记入符号表,过程定义的方法就是通过递归调用Block过程,因为每个过程都是一个分程序。由于这是分程序中的分程序,因此调用Block时需把当前的层次号Lev加一传递给Block 过程。分程序声明部分完成后,即将进入语句的处理,这时的代码分配指针CX的值正好指向语句的开始位置,这个位置正是前面的Jmp指令需要跳转到的位置。于是通过前面记录下来的地址值,把这个Jmp指令的跳转位置改成当前cx的位置。并在符号表中记录下当前的代码段分配地址和局部数据段要分配的大小(DX 的值)。生成一条INT指令,分配DX个空间,作为这个分程序段的第一条指令。下面就调用语句处理过程Statement分析语句。分析完成后,生成操作数为0的OPR指令,用于从分程序返回(对于0层的主程序来说,就是程序运行完成,退出)。
常量定义过程:
通过循环,反复获得标识符和对应的值,存入符号表。符号表中记录下标识符的名字和它对应的值。

变量定义过程:
与常量定义类似,通过循环,反复获得标识符,存入符号表。符号表中记录下标识符的名字、它所在的层及它在所在层中的偏移地址。

参变量定义过程:
类似变量定义,将参变量,存入符号表中。

参变量处理过程:
如果函数用参变量,依照形参的类型、个数,由实参进行赋值。

数组处理过程:
计算数组括号内的偏移值,存入栈顶用于后面生成的STOARR和LODARR指令调用实际的数组中元素的地址。

语句处理过程:
语句处理过程是一个嵌套子程序,通过调用表达式处理、项处理、因子处理等过程及递归调用自己来实现对语句的分析。语句处理过程可以识别的语句包括赋值语句、read语句、write语句、++语句、--语句、+=语句、-=语句、if-else-then语句、while语句、For语句、repeat 语句。当遇到begin/end语句时,就递归调用自己来分析。分析的同时生成相应的类PCODE指令。

赋值语句的处理:
首先获取赋值号左边的标识符,从符号表中找到它的信息,并确认这个标识符确为变量名。然后通过调用表达式处理过程算得赋值号右部的表达式的值并生成相应的指令保证这个值放在运行期的数据栈顶。最后通过前面查到的左部变量的位置信息,生成相应的STO指令,把栈顶值存入指定的变量的空间,实现了赋值操作。返回函数值也是用赋值语句进行返回值的储存。
对函数与过程调用的处理:
首先判断读入的标识符属性为FUNCTION或PROCEDURE,从符号表中找到此标识符,获得其所在层次和偏移地址。然后生成相应的cal指令。至于调用子过程所需的保护现场等工作是由类PCODE解释程序在解释执行cal指令时自动完成的。如果此标识符不在第0层而且是该层函数的函数名则作为返回值返回。

read语句的处理:
确定read语句语法合理的前提下(否则报错),由变量的类型生成相应的指令:
对于整型,第一条是16号操作的opr指令,实现从标准输入设备上读一个整数值,放在数据栈顶。如果读入是实数就报错,第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。
对于实型,第一条是15号操作的opr指令,实现从标准输入设备上读一个实数值,放在数据栈顶。第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。
对于字符型,第一条是20号操作的opr指令,实现从标准输入设备上读一个字符值,第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。

write语句的处理:
与read语句相似。在语法正确的前提下,生成指令:通过循环调用表达式处理过程分析write语句括号中的每一个表达式,生成相应指令保证把表达式的值算出并放到数据栈顶并生成指令,输出表达式的值,如果是数字类型则生成14号操作的opr指令,如果是字符类型则生成19号操作的opr指令。

if-then-else语句的处理:
按if语句的语法,首先调用逻辑表达式处理过程处理if语句的条件,把相应的真假值放到数据栈顶。接下去记录下代码段分配位置(即下面生成的jpc指令的位置),然后生成条件转移jpc指令(遇0或遇假转移),转移地址未知暂时填0。然后调用语句处理过程处理 then语句后面的语句或语句块。then后的语句处理完后,如果遇到else,就调用语句处理过程处理else语句后面的语句或语句块,这时当前代码段分配指针的位置就应该是上面的jpc指令的转移位置。通过前面记录下的jpc指令的位置,把它的跳转位置改成当前的代码段指针位置,否则没遇到else,那么此时的当前代码段分配指针的位置也是上面jpc指令的转移位置,也是通过前面记录下的jpc位置指令的位置,把它的跳转到当前的代码段指针位置。

begin/end语句的处理:
通过循环遍历begin/end语句块中的每一个语句,通过递归调用语句分析过程分析并生成相应代码。

while语句的处理:
首先用cx1变量记下当前代码段分配位置,作为循环的开始位置。然后处理while语句中的条件表达式生成相应代码把结果放在数据栈顶,再用cx2变量记下当前位置,生成条件转移指令,转移位置未知,填0。通过递归调用语句分析过程分析do语句后的语句或语句块并生成相应代码。最后生成一条无条件跳转指令 jmp,跳转到cx1所指位置,并把cx2所指的条件跳转指令的跳转位置改成当前代码段分配位置。

Repeat语句的处理:
首先用CX1变量记下当前代码段分配位置,作为循环的开始位置。然后通过递归调用语句分析过程分析,直到遇到until保留字,如果未对应until则出错。调用条件表达式处理过程生成相应代码把结果放在数据栈顶,再生成条件转移指令,转移位置为上面记录的CX1。
For语句的处理:
按For语句的语法,首先对For后面的一个标识符进行初值的赋值过程(类似赋值语句处理),生成相应的代码。之后遇到TO或DOWNTO保留字,如果未对应则出错。用CX1变量记下当前代码段分配的位置,作为以后JMP循环的开始位置。对上面识别的标识符变量进行存取,与TO或DOWNTO后面的表达式进行比较,生成比较指令(TO为13、DOWNTO为11),再用CX2变量记下当前代码段分配的位置,生成JPC指令,跳转地址未知,之后可用CX2记录下的位置进行回填。然后处理DO保留字后的循环体,第一步递归调用语句分析过程,第二步将原先For后的标识符变量进行自加处理,生成相应代码,然后生成无条件跳转语句JMP跳转代码为CX1。最后将此时的代码段位置回填到JPC跳转指令上。

表达式、项、因子处理:
根据PL/0语法可知,表达式应该是由正负号或无符号开头、由若干个项以加减号连接而成。而项是由若干个因子以乘除号,mod、div符号或++、--符号连接而成,因子则可能是一个标识符或一个数字,或是一个以括号括起来的子表达式。根据这样的结构,构造出相应的过程,递归调用就完成了表达式的处理。把项和因子独立开处理解决了加减号与乘除号的优先级问题。在这几个过程的反复调用中,始终传递fsys变量的值,保证可以在出错的情况下跳过出错的符号,使分析过程得以进行下去。

逻辑表达式的处理:
首先判断是否为一元逻辑表达式:判奇偶。如果是,则通过调用表达式处理过程分析计算表达式的值,然后生成判奇指令。如果不是,则肯定是二元逻辑运算符,通过调用表达式处理过程依次分析运算符左右两部分的值,放在栈顶的两个空间中,然后依不同的逻辑运算符,生成相应的逻辑判断指令,放入代码段。

判断单词合法性与出错恢复过程分析:
本过程有三个参数,s1、s2为两个符号集合,n为出错代码。本过程的功能是:测试当前符号(即sym变量中的值)是否在s1集合中,如果不在,就通过调用出错报告过程输出出错代码n,并放弃当前符号,通过词法分析过程获取一下单词,直到这个单词出现在s1或s2集合中为止。
这个过程在实际使用中很灵活,主要有两个用法:
在进入某个语法单位时,调用本过程,检查当前符号是否属于该语法单位的开始符号集合。若不属于,则滤去开始符号和后继符号集合外的所有符号。
在语法单位分析结束时,调用本过程,检查当前符号是否属于调用该语法单位时应有的后继符号集合。若不属于,则滤去后继符号和开始符号集合外的所有符号。
通过这样的机制,可以在源程序出现错误时,及时跳过出错的部分,保证语法分析可以继续下去。
语法分析过程中调用的其它子过程相对比较简单,请参考源程序的注释。

类PCODE代码解释执行过程分析:
这个过程模拟了一台可以运行类PCODE指令的栈式计算机。它拥有一个栈式数据段用于存放运行期数据、拥有一个代码段用于存放类PCODE程序代码。同时还拥用数据段分配指针、指令指针、指令寄存器、局部段基址指针等寄存器。
解释执行类PCODE代码时,数据段存储分配方式如下:
对于源程序的每一个过程(包括主程序),在被调用时,首先在数据段中开辟三个空间,存放静态链SL、动态链DL和返回地址RA。静态链记录了定义该过程的直接外过程(或主程序)运行时最新数据段的基地址。动态链记录调用该过程前正在运行的过程的数据段基址。返回地址记录了调用该过程时程序运行的断点位置。对于主程序来说,SL、DL和RA的值均置为0。静态链的功能是在一个子过程要引用它的直接或间接父过程(这里的父过程是按定义过程时的嵌套情况来定的,而不是按执行时的调用顺序定的)的变量时,可以通过静态链,跳过个数为层差的数据段,找到包含要引用的变量所在的数据段基址,然后通过偏移地址访问它。
在过程返回时,解释程序通过返回地址恢复指令指针的值到调用前的地址,通过当前段基址恢复数据段分配指针,通过动态链恢复局部段基址指针。实现子过程的返回。对于主程序来说,解释程序会遇到返回地址为0的情况,这时就认为程序运行结束。
解释程序过程中的base函数的功能,就是用于沿着静态链,向前查找相差指定层数的局部数据段基址。这在使用sto、lod、stoArr、lodArr等访问局部变量的指令中会经常用到。
类PCODE代码解释执行的部分通过循环和简单的case判断不同的指令,做出相应的动作。当遇到主程序中的返回指令时,指令指针会指到0位置,把这样一个条件作为终至循环的条件,保证程序运行可以正常的结束

⑤ 求一个c语言编写的pl0编译器

// pl0 compiler source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "set.h"
#include "pl0.h"
//////////////////////////////////////////////////////////////////////
// print error message.
void error(n)
{
int i;
printf(" ");
for (i = 1; i <= cc - 1; i++)
printf(" ");
fprintf(outfile, " ");
fprintf(outfile, "^\n");
printf("^\n");
fprintf(outfile, "Error %3d: %s\n", n, err_msg[n]);
printf("Error %3d: %s\n", n, err_msg[n]);
err++;
} // error
//////////////////////////////////////////////////////////////////////
void getch(void)
{
if (cc == ll)
{
if (feof(infile))
{
printf("\nPROGRAM INCOMPLETE\n");
exit(1);
}
ll = cc = 0;
fprintf(outfile, "%5d ", cx);
printf("%5d ", cx);
while ( (!feof(infile)) // added & modified by alex 01-02-09
&& ((ch = getc(infile)) != '\n'))
{
fprintf(outfile, "%c", ch);
printf("%c", ch);
line[++ll] = ch;
} // while
fprintf(outfile, "\n");
printf("\n");
line[++ll] = ' ';
}
ch = line[++cc];
} // getch
//////////////////////////////////////////////////////////////////////
// gets a symbol from input stream.
void getsym(void)
{
int i, k;
char a[MAXIDLEN + 1];
while (ch == ' '|| ch == '\t')
// modified by yzhang 02-03-12,add some white space
getch();
if (isalpha(ch))
{ // symbol is a reserved word or an identifier.
k = 0;
do
{
if (k < MAXIDLEN)
a[k++] = ch;
getch();
}
while (isalpha(ch) || isdigit(ch));
a[k] = 0;
strcpy(id, a);
word[0] = id;
i = NRW;
while (strcmp(id, word[i--]));
if (++i)
sym = wsym[i]; // symbol is a reserved word
else
sym = SYM_IDENTIFIER; // symbol is an identifier
}
else if (isdigit(ch))
{ // symbol is a number.
k = num = 0;
sym = SYM_NUMBER;
do
{
num = num * 10 + ch - '0';
k++;
getch();
}
while (isdigit(ch));
if (k > MAXNUMLEN)
error(25); // The number is too great.
}
else if (ch == ':')
{
getch();
if (ch == '=')
{
sym = SYM_BECOMES; // :=
getch();
}
else
{
sym = SYM_NULL; // illegal?
}
}
else if (ch == '>')
{
getch();
if (ch == '=')
{
sym = SYM_GEQ; // >=
getch();
}
else
{
sym = SYM_GTR; // >
}
}
else if (ch == '<')
{
getch();
if (ch == '=')
{
sym = SYM_LEQ; // <=
getch();
}
else if (ch == '>')
{
sym = SYM_NEQ; // <>
getch();
}
else
{
sym = SYM_LES; // <
}
}
else
{ // other tokens
i = NSYM;
csym[0] = ch;
while (csym[i--] != ch);
if (++i)
{
sym = ssym[i];
getch();
}
else
{
printf("Fatal Error: Unknown character.\n");
fprintf(outfile, "Fatal Error: Unknown character.\n");
exit(1);
}
}
} // getsym
//////////////////////////////////////////////////////////////////////
// generates (assembles) an instruction.
void gen(int x, int y, int z)
{
if (cx > CXMAX)
{
fprintf(outfile, "Fatal Error: Program too long.\n");
printf("Fatal Error: Program too long.\n");
exit(1);
}
code[cx].f = x;
code[cx].l = y;
code[cx++].a = z;
} // gen
//////////////////////////////////////////////////////////////////////
// tests if error occurs and skips all symbols that do not belongs to s1 or s2.
void test(symset s1, symset s2, int n)
{
symset s;
if (! inset(sym, s1))
{
showset(s1);
showset(s2);
printf("sym=%d, id=%s\n", sym, id);
error(n);
s = uniteset(s1, s2);
while(! inset(sym, s))
getsym();
destroyset(s);
}
} // test
//////////////////////////////////////////////////////////////////////
int dx; // data allocation index
// enter object(constant, variable or procedre) into table.
void enter(int kind)
{
mask* mk;
// added by yzhang 02-02-28
if ( position(id)> 0 ){
error(26); //Redeclared identifier.
}
// end
tx++;
strcpy(table[tx].name, id);
table[tx].kind = kind;
switch (kind)
{
case ID_CONSTANT:
if (num > MAXADDRESS)
{
error(25); // The number is too great.
num = 0;
}
table[tx].value = num;
break;
case ID_VARIABLE:
mk = (mask*) &table[tx];
mk->level = level;
mk->address = dx++;
break;
case ID_PROCEDURE:
mk = (mask*) &table[tx];
mk->level = level;
break;
} // switch
} // enter
//////////////////////////////////////////////////////////////////////
// locates identifier in symbol table.
int position(char* id)
{
int i;
strcpy(table[0].name, id);
i = tx + 1;
while (strcmp(table[--i].name, id) != 0);
return i;
} // position
//////////////////////////////////////////////////////////////////////
void constdeclaration()
{
if (sym == SYM_IDENTIFIER)
{
getsym();
if (sym == SYM_EQU || sym == SYM_BECOMES)
{
if (sym == SYM_BECOMES)
error(1); // Found ':=' when expecting '='.
getsym();
if (sym == SYM_NUMBER)
{
enter(ID_CONSTANT);
getsym();
}
else
{
error(2); // There must be a number to follow '='.
}
}
else
{
error(3); // There must be an '=' to follow the identifier.
}
}
else //added by yzhang 02-02-28
error(4); // There must be an identifier to follow 'const', 'var', or 'procere'.
} // constdeclaration
//////////////////////////////////////////////////////////////////////
void vardeclaration(void)
{
if (sym == SYM_IDENTIFIER)
{
enter(ID_VARIABLE);
getsym();
}
else
{
error(4); // There must be an identifier to follow 'const', 'var', or 'procere'.
}
} // vardeclaration
//////////////////////////////////////////////////////////////////////
void listcode(int from, int to)
{
int i;

printf("\n");
fprintf(outfile, "\n");
for (i = from; i < to; i++)
{
printf("%5d %s\t%d\t%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
fprintf(outfile, "%5d %s\t%d\t%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
}
printf("\n");
fprintf(outfile, "\n");
} // listcode
//////////////////////////////////////////////////////////////////////
void factor(symset fsys)
{
void expression();
int i;
symset set;

test(facbegsys, fsys, 24); // The symbol can not be as the beginning of an expression.
while (inset(sym, facbegsys))
{
if (sym == SYM_IDENTIFIER)
{
if ((i = position(id)) == 0)
{
error(11); // Undeclared identifier.
}
else
{
switch (table[i].kind)
{
mask* mk;
case ID_CONSTANT:
gen(LIT, 0, table[i].value);
break;
case ID_VARIABLE:
mk = (mask*) &table[i];
gen(LOD, level - mk->level, mk->address);
break;
case ID_PROCEDURE:
error(21); // Procere identifier can not be in an expression.
break;
} // switch
}
getsym();
}
else if (sym == SYM_NUMBER)
{
if (num > MAXADDRESS)
{
error(25); // The number is too great.
num = 0;
}
gen(LIT, 0, num);
getsym();
}
else if (sym == SYM_LPAREN)
{
getsym();
set = uniteset(createset(SYM_RPAREN, SYM_NULL), fsys);
expression(set);
destroyset(set);
if (sym == SYM_RPAREN)
{
getsym();
}
else
{
error(22); // Missing ')'.
}
}
else // added by yzhang 02-02-28
test(fsys, createset(SYM_LPAREN, SYM_NULL), 23);
} // while
} // factor
//////////////////////////////////////////////////////////////////////
void term(symset fsys)
{
int mulop;
symset set;

set = uniteset(fsys, createset(SYM_TIMES, SYM_SLASH, SYM_NULL));
factor(set);
while (sym == SYM_TIMES || sym == SYM_SLASH)
{
mulop = sym;
getsym();
factor(set);
if (mulop == SYM_TIMES)
{
gen(OPR, 0, OPR_MUL);
}
else
{
gen(OPR, 0, OPR_DIV);
}
} // while
destroyset(set);
} // term
//////////////////////////////////////////////////////////////////////
void expression(symset fsys)
{
int addop;
symset set;
set = uniteset(fsys, createset(SYM_PLUS, SYM_MINUS, SYM_NULL));
if (sym == SYM_PLUS || sym == SYM_MINUS)
{
addop = sym;
getsym();
term(set);
if (addop == SYM_MINUS)
{
gen(OPR, 0, OPR_NEG);
}
}
else
{
term(set);
}
while (sym == SYM_PLUS || sym == SYM_MINUS)
{
addop = sym;
getsym();
term(set);
if (addop == SYM_PLUS)
{
gen(OPR, 0, OPR_ADD);
}
else
{
gen(OPR, 0, OPR_MIN);
}
} // while
destroyset(set);
} // expression
//////////////////////////////////////////////////////////////////////
void condition(symset fsys)
{
int relop;
symset set;
if (sym == SYM_ODD)
{
getsym();
expression(fsys);
gen(OPR, 0, 6);
}
else
{
set = uniteset(relset, fsys);
expression(set);
destroyset(set);
if (! inset(sym, relset))
{
error(20);
}
else
{
relop = sym;
getsym();
expression(fsys);
switch (relop)
{
case SYM_EQU:
gen(OPR, 0, OPR_EQU);
break;
case SYM_NEQ:
gen(OPR, 0, OPR_NEQ);
break;
case SYM_LES:
gen(OPR, 0, OPR_LES);
break;
case SYM_GEQ:
gen(OPR, 0, OPR_GEQ);
break;
case SYM_GTR:
gen(OPR, 0, OPR_GTR);
break;
case SYM_LEQ:
gen(OPR, 0, OPR_LEQ);
break;
} // switch
} // else
} // else
} // condition
//////////////////////////////////////////////////////////////////////
void statement(symset fsys)
{
int i, cx1, cx2;
symset set1, set;
if (sym == SYM_IDENTIFIER)
{ // variable assignment
mask* mk;
if (! (i = position(id)))
{
error(11); // Undeclared identifier.
}
else if (table[i].kind != ID_VARIABLE)
{
error(12); // Illegal assignment.
i = 0;
}
getsym();
if (sym == SYM_BECOMES)
{
getsym();
}
else
{
error(13); // ':=' expected.
}
expression(fsys);
mk = (mask*) &table[i];
if (i)
{
gen(STO, level - mk->level, mk->address);
}
}
else if (sym == SYM_CALL)
{ // procere call
getsym();
if (sym != SYM_IDENTIFIER)
{
error(14); // There must be an identifier to follow the 'call'.
}
else
{
if (! (i = position(id)))
{
error(11); // Undeclared identifier.
}
else if (table[i].kind == ID_PROCEDURE)
{
mask* mk;
mk = (mask*) &table[i];
gen(CAL, level - mk->level, mk->address);
}
else
{
error(15); // A constant or variable can not be called.
}
getsym();
} // else
}
else if (sym == SYM_IF)
{ // if statement
getsym();
set1 = createset(SYM_THEN, SYM_DO, SYM_NULL);
set = uniteset(set1, fsys);
condition(set);
destroyset(set1);
destroyset(set);
if (sym == SYM_THEN)
{
getsym();
}
else
{
error(16); // 'then' expected.
}
cx1 = cx;
gen(JPC, 0, 0);
statement(fsys);
code[cx1].a = cx;
}
else if (sym == SYM_BEGIN)
{ // block
getsym();
set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL);
set = uniteset(set1, fsys);
statement(set);
while (sym == SYM_SEMICOLON || inset(sym, statbegsys))
{
if (sym == SYM_SEMICOLON)
{
getsym();
}
else
{
error(10);
}
statement(set);
} // while
destroyset(set1);
destroyset(set);
if (sym == SYM_END)
{
getsym();
}
else
{
error(17); // ';' or 'end' expected.
}
}
else if (sym == SYM_WHILE)
{ // while statement
cx1 = cx;
getsym();
set1 = createset(SYM_DO, SYM_NULL);
set = uniteset(set1, fsys);
condition(set);
destroyset(set1);
destroyset(set);
cx2 = cx;
gen(JPC, 0, 0);
if (sym == SYM_DO)
{
getsym();
}
else
{
error(18); // 'do' expected.
}
statement(fsys);
gen(JMP, 0, cx1);
code[cx2].a = cx;
}
else //added by yzhang 02-02-28
test(fsys, phi, 19);
} // statement

//////////////////////////////////////////////////////////////////////
void block(symset fsys)
{
int cx0; // initial code index
mask* mk;
int block_dx;
int savedTx;
symset set1, set;
dx = 3;
block_dx = dx;
mk = (mask*) &table[tx];
mk->address = cx;
gen(JMP, 0, 0);
if (level > MAXLEVEL)
{
error(32); // There are too many levels.
}
do
{
if (sym == SYM_CONST)
{ // constant declarations
getsym();
do
{
constdeclaration();
while (sym == SYM_COMMA)
{
getsym();
constdeclaration();
}
if (sym == SYM_SEMICOLON)
{
getsym();
}
else
{
error(5); // Missing ',' or ';'.
}
}
while (sym == SYM_IDENTIFIER);
} // if
if (sym == SYM_VAR)
{ // variable declarations
getsym();
do
{
vardeclaration();
while (sym == SYM_COMMA)
{
getsym();
vardeclaration();
}
if (sym == SYM_SEMICOLON)
{
getsym();
}
else
{
error(5); // Missing ',' or ';'.
}
}
while (sym == SYM_IDENTIFIER);
block_dx = dx; // modified by yzhang 02-03-15
} // if
while (sym == SYM_PROCEDURE)
{ // procere declarations
getsym();
if (sym == SYM_IDENTIFIER)
{
enter(ID_PROCEDURE);
getsym();
}
else
{
error(4); // There must be an identifier to follow 'const', 'var', or 'procere'.
}
if (sym == SYM_SEMICOLON)
{
getsym();
}
else
{
error(5); // Missing ',' or ';'.
}
level++;
savedTx = tx;
set1 = createset(SYM_SEMICOLON, SYM_NULL);
set = uniteset(set1, fsys);
block(set);
destroyset(set1);
destroyset(set);
tx = savedTx;
level--;
if (sym == SYM_SEMICOLON)
{
getsym();
set1 = createset(SYM_IDENTIFIER, SYM_PROCEDURE, SYM_NULL);
set = uniteset(statbegsys, set1);
test(set, fsys, 6);
destroyset(set1);
destroyset(set);
}
else
{
error(5); // Missing ',' or ';'.
}
} // while
set1 = createset(SYM_IDENTIFIER, SYM_NULL);
set = uniteset(statbegsys, set1);
test(set, declbegsys, 7);
destroyset(set1);
destroyset(set);
}
while (inset(sym, declbegsys));
code[mk->address].a = cx;
mk->address = cx;
cx0 = cx;
gen(INT, 0, block_dx);
set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL);
set = uniteset(set1, fsys);
statement(set);
destroyset(set1);
destroyset(set);
gen(OPR, 0, OPR_RET); // return
test(fsys, phi, 8); // test for error: Follow the statement is an incorrect symbol.
listcode(cx0, cx);
} // block
//////////////////////////////////////////////////////////////////////
int base(int stack[], int currentLevel, int levelDiff)
{
int b = currentLevel;

while (levelDiff--)
b = stack[b];
return b;
} // base
//////////////////////////////////////////////////////////////////////
// interprets and executes codes.
void interpret()
{
int pc; // program counter
int stack[STACKSIZE];
int top; // top of stack
int b; // program, base, and top-stack register
instruction i; // instruction register
printf("Begin executing PL/0 program.\n");
fprintf(outfile, "Begin executing PL/0 program.\n");
pc = 0;
b = 1;
top = 3;
stack[1] = stack[2] = stack[3] = 0;
do
{
i = code[pc++];
switch (i.f)
{
case LIT:
stack[++top] = i.a;
break;
case OPR:
switch (i.a) // operator
{
case OPR_RET:
top = b - 1;
pc = stack[top + 3];
b = stack[top + 2];
break;
case OPR_NEG:
stack[top] = -stack[top];
break;
case OPR_ADD:
top--;
stack[top] += stack[top + 1];
break;
case OPR_MIN:
top--;
stack[top] -= stack[top + 1];
break;
case OPR_MUL:
top--;
stack[top] *= stack[top + 1];
break;
case OPR_DIV:
top--;
if (stack[top + 1] == 0)
{
fprintf(stderr, "Runtime Error: Divided by zero.\n");
fprintf(stderr, "Program terminated.\n");
continue;
}
stack[top] /= stack[top + 1];
break;
case OPR_ODD:
stack[top] %= 2;
break;
case OPR_EQU:
top--;
stack[top] = stack[top] == stack[top + 1];
break;
case OPR_NEQ:
top--;
stack[top] = stack[top] != stack[top + 1];
case OPR_LES:
top--;
stack[top] = stack[top] < stack[top + 1];
break;
case OPR_GEQ:
top--;
stack[top] = stack[top] >= stack[top + 1];
case OPR_GTR:
top--;
stack[top] = stack[top] > stack[top + 1];
break;
case OPR_LEQ:
top--;
stack[top] = stack[top] <= stack[top + 1];
} // switch
break;
case LOD:
stack[++top] = stack[base(stack, b, i.l) + i.a];
break;
case STO:
stack[base(stack, b, i.l) + i.a] = stack[top];
//printf("%d\n", stack[top]);
fprintf(outfile, "%d\n", stack[top]);
top--;
break;
case CAL:
stack[top + 1] = base(stack, b, i.l);
// generate new block mark
stack[top + 2] = b;
stack[top + 3] = pc;
b = top + 1;
pc = i.a;
break;
case INT:
top += i.a;
break;
case JMP:
pc = i.a;
break;
case JPC:
if (stack[top] == 0)
pc = i.a;
top--;
break;
} // switch
}
while (pc);
//printf("End executing PL/0 program.\n");
fprintf(outfile, "End executing PL/0 program.\n");
} // interpret
//////////////////////////////////////////////////////////////////////
void main ()
{
FILE* hbin;
char s[80],*finddot;
int i;
symset set, set1, set2;
printf("Please input source file name: "); // get file name to be compiled
scanf("%s", s);
if ((infile = fopen(s, "r")) == NULL)
{
printf("File %s can't be opened.\n", s);
exit(1);
}
#if 1 // added by yzhang 02-02-28
// open the output file
finddot = strchr(s,'.');
if (finddot!=NULL){
strcpy(finddot, ".out");
}else{
strcat(s, ".out");
printf("%s\n", s);
}
printf("Output File is %s\n", s);
if ((outfile = fopen(s, "w")) == NULL)
{
printf("File %s can't be opened.\n", s);
exit(1);
}
#endif

phi = createset(SYM_NULL);
relset = createset(SYM_EQU, SYM_NEQ, SYM_LES, SYM_LEQ, SYM_GTR, SYM_GEQ, SYM_NULL);

// create begin symbol sets
declbegsys = createset(SYM_CONST, SYM_VAR, SYM_PROCEDURE, SYM_NULL);
statbegsys = createset(SYM_BEGIN, SYM_CALL, SYM_IF, SYM_WHILE, SYM_NULL);
facbegsys = createset(SYM_IDENTIFIER, SYM_NUMBER, SYM_LPAREN, SYM_NULL);
err = cc = cx = ll = 0; // initialize global variables
ch = ' ';
kk = MAXIDLEN;
getsym();
set1 = createset(SYM_PERIOD, SYM_NULL);
set2 = uniteset(declbegsys, statbegsys);
set = uniteset(set1, set2);
block(set);
destroyset(set1);
destroyset(set2);
destroyset(set);
destroyset(phi);
destroyset(relset);
destroyset(declbegsys);
destroyset(statbegsys);
destroyset(facbegsys);
if (sym != SYM_PERIOD)
error(9); // '.' expected.
if (err == 0)
{
hbin = fopen("hbin.txt", "w");
for (i = 0; i < cx; i++)
fwrite(&code[i], sizeof(instruction), 1, hbin);
fclose(hbin);
}
if (err == 0)
interpret();
else
printf("There are %d error(s) in PL/0 program.\n", err);
listcode(0, cx);

// close all files, added by yzhang, 02-02-28
fclose(infile);
fclose(outfile);
} // main
//////////////////////////////////////////////////////////////////////
// eof pl0.c

⑥ 编译程序安装在计算机的哪里

举例来说:

当你使用C编写代码,使用编译器编译后,即生成了可执行程序。当可执行程序被操作系统的加载器加载到内存、并准备好必要的数据后从代码段开始执行,这时的代码段代码已经是机器码了,无须编译。当然,可执行程序里的所有数据并非都是代码,有些是写给操作系统看的,以使操作系统能为程序的执行做好必要准备。

至于说DOS命令,分为外部命令和内部命令。外部命令和一般的可执行程序没有区别,他以可执行程序文件的形式存在。没有这个文件就不能运行这个命令;内部命令是固化在操作系统中的代码模块,一般以DLL文件的形式存在。至于哪个DLL文件包含特定的内部命令的代码,就必须查资料了。

CPU所支持的指令集,是由CPU的物理设计决定的,并不是说有什么指令存放在CPU上。

当然,如果是解释性的语言。那么,可执行程序是一边被解释(编译)一边被执行的。所以他的速度要慢些。并且必须安装对应的编译(解释)程序。比如JAVA。

⑦ 编译程序和解释程序具体在哪具体是哪个文件

说是编译程序和解释程序,但是并不是具体的某个文件,它们是固化了的东西。

⑧ 如何将经过编译后的程序得到它的源程序

不太可能,因为编译后的程序是机器语言,最多还原成汇编语言,不可能还原成高级语言的源程序。
就好像香肠不可能还原成猪,最多只能还原成肉末一样。

⑨ 怎么查看文件的源程序

打开浏览器→查看→源文件
找FLASH源文件会比较麻烦因为一些FLASH都把源文件隐藏
可以这样找
打开浏览器→查看→源文件→编辑→查找下一个
输入flash查找到前面是http开头以jtp结尾就是了

⑩ 请问visualc++6.0编译生成的源程序文件在哪儿

源程序文件 要不就是没有,要不就是a那个文件,就是标注c_file那个。
生成的可执行程序在debug这个文件夹下边。

热点内容
苹果手机备忘录怎么加密 发布:2024-05-19 18:57:57 浏览:15
光荣脚本 发布:2024-05-19 18:57:48 浏览:997
pythonjson字符串 发布:2024-05-19 18:51:43 浏览:253
什么是服务器厂商介绍 发布:2024-05-19 18:50:09 浏览:370
服务器网卡硬件型号怎么看 发布:2024-05-19 18:36:41 浏览:665
修改pve服务器ip 发布:2024-05-19 18:31:52 浏览:468
微信密码忘记了如何取出里面的钱 发布:2024-05-19 18:27:35 浏览:329
vs2005反编译 发布:2024-05-19 18:26:34 浏览:364
ug启动语言脚本 发布:2024-05-19 18:25:57 浏览:874
缓存服务器技术 发布:2024-05-19 18:25:56 浏览:885