【原创】自制编程语言-5 变量的赋值(1)

首先我们先看这个函数:

void put_value(const char *name){

for(int i=0;i<value_ptr;i++){

if(strcmp(value[i].name,s)==0){

if(value[i].type==0)printf("%d",value[i].vnum);

else printf("%s",value[i].vstring);

}

}

}

这个函数写得不是很好,因为首先根据变量名找变量的功能可能会在很多情况下使用到,每次都写一个for循环很麻烦,所以,我们可以单独把这个功能提取出来,写成一个函数的形式。

至于函数名,就叫getpos吧。pos是position的缩写。

int getpos(const char *vname){

for(int i=0;i<value_ptr;i++){

if(strcmp(value[i].name,vname)==0)return i;//下标

}

return -1;//未找到

}

根据变量名,反复的循环比较变量名,直到找到正确的数字,返回这个下标。如果没有,返回-1。

根据这段代码,我们就可以简化put_value。

void put_value(const char *name){

int i=getpos(name);

if(i==-1)error();

if(value[i].type==0)printf("%d",value[i].vnum);

else printf("%s",value[i].vstring);

}

我们来运行一下试试。结果应该还是正常的。接下来我们就进入正题,变量的赋值语句。一般的赋值语句应该都长成这样:

变量名 = 表达式

为了读入方便,这里规定:变量名和"="和后面的表达式中间必须加上空格,这样直接用scanf("%s")就可以读入了,不用人工分割单词。

else if(isvalue(s)){//变量的赋值语句

char sa[255],sb[255];

get_word(sa);get_word(sb);

if(strcmp(sa,"=")!=0)error();

if(value[getpos(s)].type==0)value[getpos(s)].vnum=getnum(sb);

else {

sb[strlen(sb)-1]='\0';//去掉最后的双引号

strcpy(value[getpos(s)].vstring,sb+1);//复制的时候去掉前面的双引号

}

}

首先读入sa和sb,s存放要赋值的变量,sa存放等号,sb存放后面的表达式。这里,分两种情况进行赋值。如果是数字,把表达式sb求出数字,放入value,如果是字符串,去掉前后引号放进去。

然后是getnum。这个函数需要实现表达式求值的功能。例如,

a = 1+2*3+4

这样的语句,必须根据运算优先级求出这样长的表达式。当然,我们一步一步来,先实现把一个字符串转换为常数的功能。

int getnum(const char *s){

int i;

sscanf(s,"%d",&i);

return i;

}

实际上,把一个字符串转换为常数非常简单,使用sscanf往字符串读入常数即可。关于sscanf的用法,可以自行在网上搜索。

我们用如下的代码测试一个:

dim a as int

dim str as string

a = 123

str = "hello"

print a

print str

exit

运行非常成功,输出“123hello”。完。

顺便把完整版代码贴一下,一共109行。

#include<bits/stdc++.h>
using namespace std;
char s[100];
struct VALUE{
        char name[30];//变量名
        int type;//类型,0表示int,1表示string
        int vnum;//int类型的数值
        char vstring[255];//string类型
};
int value_ptr=0;
struct VALUE value[1000];
void get_word(char *s){//读入单词
        scanf("%s",s);
}
void get_string(char *s){
        int i=0,flag=0;
        for(i=0;i<100;i++){
next:
                s[i]=getchar();
                if(flag==0 && s[i]==' ')goto next;
                else flag=1;
                if(s[i]=='\n')break;
        }
        s[i]='\0';//结束掉字符串
}
void error(){
        cout<<"Error in program.\n";
        exit(0);//退出程序
}
int isnumber(const char *s){
        for(int i=0;i<strlen(s);i++)
                if(s[i]<='0' || s[i]>='9')return 0;//不是数字字符
        return 1;
}
int isvalue(const char *s){
        for(int i=0;i<value_ptr;i++){
                if(strcmp(value[i].name,s)==0)return 1;
        }
        return 0;
}
int getpos(const char *vname){
        for(int i=0;i<value_ptr;i++){
                if(strcmp(value[i].name,vname)==0)return i;//下标
        }
        return -1;//未找到
}
void put_value(const char *name){
        int i=getpos(name);
        if(i==-1)error();
        if(value[i].type==0)printf("%d",value[i].vnum);
        else printf("%s",value[i].vstring);
}
int getnum(const char *s){
        int i;
        sscanf(s,"%d",&i);
        return i;
}
int main(int argc,char** argv){
        if(argc!=2){//有一个要解释的文件参数
                cout<<"Cannot find source file.\n";
                return 0;
        }
        freopen(argv[1],"r",stdin);
        for(;;){
                get_word(s);
                if(strcmp(s,"print")==0){//调用print输出
                        get_string(s);
                        if(isnumber(s))cout<<s;
                        else if(s[0]=='\"' && s[strlen(s)-1]=='\"'){
                                for(int i=1;i<strlen(s)-1;i++){
                                        if(s[i]=='\\' && s[i+1]=='n'){
                                                printf("\n");i++;
                                        }
                                        else printf("%c",s[i]);
                                }
                        }
                        else if(isvalue(s)){
                                put_value(s);
                        }
                        else error();
                }
                else if(strcmp(s,"exit")==0){//退出程序
                        return 0;
                }
                else if(strcmp(s,"dim")==0){//声明变量
                        char sa[255],sb[255],sc[255];
                        get_word(sa);get_word(sb);get_word(sc);
                        if(strcmp(sb,"as")!=0)error();
                        strcpy(value[value_ptr].name,sa);
                        if(strcmp(sc,"int")==0)value[value_ptr].type=0;
                        else if(strcmp(sc,"string")==0)value[value_ptr].type=1;
                        else error();
                        value_ptr++;
                }
                else if(isvalue(s)){//变量的赋值语句
                        char sa[255],sb[255];
                        get_word(sa);get_word(sb);
                        if(strcmp(sa,"=")!=0)error();
                        if(value[getpos(s)].type==0)value[getpos(s)].vnum=getnum(sb);
                        else {
                                sb[strlen(sb)-1]='\0';//去掉最后的双引号
                                strcpy(value[getpos(s)].vstring,sb+1);//复制的时候去掉前面的双引号
                        }
                }
                else{
                        error();
                }
        }
}

(0)

相关推荐