【原创】【自制编程语言】1.从argv[1]开始

x33g5p2x  于2022-05-08 转载在 其他  
字(2.4k)|赞(0)|评价(0)|浏览(377)

第1天:从argv[1]开始

先从命令行参数讲起吧。

现今的人们,尤其是写大型的项目,一般都用IDE。我们没那么高级,只是先从一个编译器做起,不需要IDE。对于编译器的调用,本质就是给一个源代码进去,经过对源代码进行分析,然后出来一个结果。那么对于源代码文件,传送给编译器,一般使用命令行参数。

C:\> gcc test.c -o test

一般我们调用都是直接写一个exe的名称,这里,在名称后面加上的各种东西了例如"test.c","-o",这些就叫做参数。而在调用exe的时候,加上的参数一般称为命令行参数。参数就是告知编译器一些信息的。

如何获取这些参数呢?对于C和C++,获取命令行参数是直接通过main函数获取的:

int main(int argc,char** argv){
    
}

把main函数声明成这种形式,就能获取命令行参数。其中,argc表示参数的数量,argv是一个指针数组(指针的指针),写法是char** argv,也有写作char *argv[]的,两种方式含义相同,其中从argv[0]开始一直到argv[argc-1],都是字符串,保存的就是参数。

一般来说,argv[0]存放这个exe的名称,而argv[1]开始就是第一个参数了,我们可以通过调用argv[1]来获取我们需要编译的代码。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;

int main(int argc,char** argv){
	if(argc!=2){
		printf("The syntax of the command is incorrect.\n");
		exit(1);
	}
	FILE *fp=fopen(argv[1],"r");
	
	
	return 0;
}

代码的主体结构就是这样了。

然后,我们就可以开始正式读入我们的东西了。在此之前,为了方便我们的后续,也是为了仿制汇编语言更加像一些,我决定在里面做一些东西:寄存器。

寄存器其实在汇编语言里面有很多,例如EAX,EBX,ESI,EDI,SS,DS,CS等,毕竟我们只是乱做,寄存器其实也是汇编里面非常接近硬件的东西,(话说C可以内嵌汇编,也就是说这些东西一定程度上我们还是可能实现的)我们就没必要设太多,就设:

eax ebx ecx edx esi edi ebp esp

对了,还有一个eip,用于存放指令的地址,这里我们就不是指令了,而是读入的语句(或者说单词),我们把读入的单词全部放入数组,用eip变量指向这个数组就可以了,eip主要是在后面写跳转的时候用处比较大,现在暂时无法体现出来。

使用一个循环来读入所有的单词,我们这里由于实现的东西比较简单,其实也不需要做词法/句法上的判断,至于词法/句法执行时再做判断,这样也轻松一些。(其实不就是懒

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef string Word;
int eax,ebx,ecx,edx,esi,edi;
int *ebp,*esp;
Word *eip;

Word wd[32768+10];

int main(int argc,char** argv){
	if(argc!=2){
		printf("The syntax of the command is incorrect.\n");
		exit(1);
	}
	FILE *fp=fopen(argv[1],"r");
	eip=wd;
	for(;;){
		char s[100];
		int i=fscanf(fp,"%s",s);
		if(i==EOF)break;
		*eip=s;++eip;//*eip就是读取的指令单词 ,存储在wd数组中 
	}
	
	
	return 0;
}

我们规定使用"end"字符串来结束代码,经过简单的加工,最终写出来的代码是这样的:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef string Word;
int eax,ebx,ecx,edx,esi,edi;
int *ebp,*esp;
Word *eip;

Word wd[32768+10];
Word getword(){
	return *(eip++);
}

int main(int argc,char** argv){
	if(argc!=2){
		printf("The syntax of the command is incorrect.\n");
		exit(1);
	}
	FILE *fp=fopen(argv[1],"r");
	eip=wd;
	for(;;){
		char s[100];
		int i=fscanf(fp,"%s",s);
		if(i==EOF)break;
		*eip=s;++eip;//*eip就是读取的指令单词 ,存储在wd数组中 
	}
	eip=wd;
	
	for(;;){
		Word s=getword(); 
		if(s=="end"){
			exit(0);
		}
	}
	
	return 0;
}

未完待续。

相关文章