大家好,我们老师让我们做一个logo乌龟绘图程序,具体要求如下:
Basic statement for turtle
FD, BK
RT, LT
PU, PD
SETPC
HOME, CLEAN
Repeat (5)
REPEAT
Procedure (5)
TO
Save & load procedures(5)
SAVE
LOAD
Procedure with variable (5)
TO
Variable (5)
MAKE
Output (5)
PRINT
TO CIR :LEN
REPEAT 90 [ FD :LEN RT 4 ]
END
TO MAIN
PU BK 30 PD
REPEAT 18 [CIR 4 CIR 3 CIR 2 RT 20 ]
END
Expression (10)
+-*/=
Flow control (10)
IF
WAIT
THROW
OUTPUT
Compare & logic (5)
><=
AND OR NOT
TO MAIN
CLEAN PU HOME ST SETPC 12 PD
MAKE "L 10 MAKE "S 80
SETPOS [0 -140]
SZ :L :S
END
TO SZ :CC :CD
TEST :CC=1
IFTRUE [
FD :CD
LT 30 FD :CD BK :CD RT 30
RT 30 FD :CD BK :CD LT 30
BK :CD
STOP
]
IFFALSE [
FD :CD
LT 30 SZ :CC-1 :CD*0.75 RT 30
RT 45 SZ :CC-1 :CD*0.75 LT 45
BK :CD
]
END
Word & list
WORD
SENTENCE (SE)
FIRST
BUTFIRST
LAST
BUTLAST
THING
READLIST
我现在很困惑,牛人能给我一些提示吗?谢谢!
下面是一些提示:
char cmdline[MAXLINE];
do {
gets(cmdline);
} while ( parse(cmdline) ); // 0说明命令为bye
入口:
cmd=“FD 10 RT 90”
取第一个单词:
op=“FD”
cmd=“10 RT 90”
分派到doFD函数处理
…
doFD返回cmd=“RT 90”
继续循环
void parse(char* cmd) {
while ( *cmd) {
char* op=cmd;
cmd = get_word(cmd);
if ( strcmp(op,”FD”)==0 )
cmd = doFD(cmd);
else
…
}
}
char* get_word(char* cmd) {
while(*cmd++) {
if ( isspace(*cmd) ) {
*cmd=0;
break;
}
}
}
用层叠的if…else…语句
if ( strcmp(op,”FD”)==0 )
cmd = doFD(cmd);
else
…
char*[] opl = {
“FD”,”RT”…
}
num=-1;
for (i=0; i<…; ++i )
if ( strcmp(op, opl[i]) ==0 ) {
num=i;
break;
}
switch (num) {
case 0:cmd=doFD(cmd);break;
…
}
struct {
char* op;
char* (fun)(char*);
}opl[] = {
{“FD”,doFD},{“RT”,doRT}…
}
for (i=0; i<…; ++i )
if ( strcmp(op, opl[i].op) ==0 ) {
cmd = opl[i].fun(cmd);
break;
}
取参数
取第一个词
转换为int
执行
所有单参数的命令均可如此操作
char* doFD(char* cmd) {
int dis=0;
char* para = cmd;
cmd = get_word(cmd);
dis = atoi(para);
…
return cmd;
}
REPEAT 4 [FD 10 RT 90]
先取第一个词,记录为循环的次数rpt
然后扫描后面的字符串,找到一对[]
注意[]可能有嵌套
for (i=0; i<rpt; ++i ) {
复制[]中的内容到rc
parse(rc);
}
TO CIR
REPEAT 36 [FD 10 RT 10]
END
TO后面的一个词是过程的名字
以后到END为止,所有的内容记录在这个过程的字符串里
struct procedure {
char* name;
char* body;
};
在doTo()中,读入输入行,记录在body中,直到输入END
在doTo()中设置全局变量标志开始记录过程,在主框架中根据该标志记录输入行到一个全局变量中,直到读到END
在parse()中,遇到不认识的op,到doDOTO
doDOTO从一个全局的过程列表里struct procedure* pro_list;寻找该op
找到的话,将body复制一份,交给parse()
struct procedure {
char* name;
char* body;
struct procedure* next;
};
全局变量
struct procedure* pro_lise;
记录所有的过程
在doDOTO中:
for ( p = pro_list; p; p=p->next ) {
if ( strcmp(op, p->name) ==0 ) {
char* tmp = (char*)malloc((strlen(p->body)+1);
strcpy(tmp,p->body);
parse(tmp);
break;
}
}
MAKE “A 100
FD :A
字:双引号开头的一个单词
变量:冒号开头的一个单词
布尔:TRUE/FALSE
数:不区分整数、浮点数
字:双引号开头的一个单词
表:[]括起来的字符串,可能有空格,也可能有其他表或数,如
[This is 12 list [ab c]]
struct value {
char* name;
int type;
// 0=null, 1=bool, 2=number, 3=word
char* cont;
struct value* next;
};
命令处理函数里的get_word()替换为get_value()
char* get_value(char* cmd, struct value* v);
取第一个词,看第一个字符
FD 90 是数字:制造一个value 变量记录这个数字
PRINT “A 是” :制造一个value 变量记录这个字
FD :A 是: :调用get_var() 得到这个变量的值
FD CAL 是字母:
是TRUE 或FALSE :制造一个value 变量记录这个值
调用这个过程,从过程得到返回值
struct value* var_list;记录所有的全局变量
struct value* get_var(char* name);返回一个变量的值
MAKE有两个参数,第一个是变量的名字,第二个是变量的值
首先get_var()试图找到这个变量,如果
有:则改变value结构的内容,注意要先free
无:则加入一个新的value结构
MAKE ”A “ABC
MAKE :A “LALALA
在过程中MAKE的变量,或
出现在过程名字后面的变量
TO CIR :R
在doDOTO()中建立一个变量列表,保存所有本地变量,函数运行结束时清除
在doTO()中,将过程名称后面的变量记录在struct procedure中
在doDOTO()中进行参数初始化
struct procedure {
char* name;
char* body;
int number_of_parameters;
char** array_of_parameters;
struct procedure* next;
};
在doDOTO中
struct value* local_var=0;
for (i=0;i<number_of_parameters;i++) {
struct value v;
v.name赋值为array_of_parameters[i];
cmd=get_value(cmd,&v);
在local_var列表中加入v
}
在过程中遇到:时,先在本地变量列表中寻找,再到全局变量列表中寻找
为此:
设立全局变量struct value* cur_local_var;
在get_var() 中先看cur_local_var ,再看var_list
在doDOTO 中,先设cur_local_var 为自己的,结束时设为0
希望高手能给一些具体实现的指导,万分感谢!