关于Basic程序解释器及编译原理的简单化(1)---Basic器的语法分析及主要代码
这就是Basic解释器的主代码,其中用到上节讲的词法提取get_token()和代数式求值get_exp(int *result)函数.
这一节的代码更简单,就是随心所欲地将得到的token组装.
譬如在get_token后如果token装PRINT,你就调用一次get_token将下一个token答应出来就是了,很简单的,或许你自己也能搞定的.
在下一节你,我会给你完整的C++封装好了的源代码.
/* A tiny BASIC interpreter */
#include <stdio.h>
#include <setjmp.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#define NUM_LAB 100
#define LAB_LEN 10
#define FOR_NEST 25
#define SUB_NEST 25
#define PROG_SIZE 10000
#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6
#define PRINT 1
#define INPUT 2
#define IF 3
#define THEN 4
#define FOR 5
#define NEXT 6
#define TO 7
#define GOTO 8
#define EOL 9
#define FINISHED 10
#define GOSUB 11
#define RETURN 12
#define END 13
char *prog; /* holds expression to be analyzed */
jmp_buf e_buf; /* hold environment for longjmp() */
int variables[26]= { /* 26 user variables,A-Z */
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0
};
struct commands { /* keyword lookup table */
char command[20];
char tok;
} table[] = { /* command must be entered lowercase */
"print",PRINT, /* in this table */
"input",INPUT,
"if",IF,
"then",THEN,
"goto",GOTO,
"for",FOR,
"next",NEXT,
"to",TO,
"gosub",GOSUB,
"return",RETURN,
"end",END,
NULL,END
};
char token[80];
char token_type,tok;
struct label {
char name [LAB_LEN];
char *p; /* point to place to go in source */
};
struct label label_table[NUM_LAB];
char *find_label(),*gpop();
struct for_stack {
int var; /* counter variable */
int target; /* target value */
char *loc;
} fstack[FOR_NEST]; /* stack for FOR/NEXT loop */
struct for_stack fpop();
char *gstack[SUB_NEST]; /* stack for gosub */
int ftos; /* index to top of FOR stack */
int gtos; /* index to top of GOSUB */
void print(),scan_labels(),find_eol(),exec_goto();
void gosub(),greturn(),gpush(),label_init(),fpush();
/* Load a program */
load_program (char *p,char *fname)
{
FILE *fp;
int i=0;
if (!(fp=fopen(fname,"rb"))) return 0;
i=0;
do {
*p = getc(fp);
p++;i++;
} while (!feof(fp)&&i<PROG_SIZE);
*(p-2) = '