/* A Little C interpreter. */
#include "stdio.h"
#include "setjmp.h"
#include "math.h"
#include "ctype.h"
#include "stdlib.h"
#include "string.h"
#define NUM_FUNC 100
#define NUM_GLOBAL_VARS 100
#define NUM_LOCAL_VARS 200
#define NUM_BLOCK 100
#define ID_LEN 31
#define FUNC_CALLS 31
#define NUM_PARAMS 31
#define PROG_SIZE 10000
#define LOOP_NEST 31
enum tok_types {DELIMITER,IDENTIFIER,NUMBER,KEYWORD,TEMP,STRING ,BLOCK};
/* add additional C deyword tokens here */
enum tokens {ARG,CHAR,INT,IF,ELSE,FOR,DO,WHILE,SWITCH,RETURN,EOL,FINISHED,END};
/* add additoinal double operators here (such as ->) */
enum double_ops {LT=1,LE,GT,GE,EQ,NE};
/* These are the constants used to call sntx_err() when a syntax error
occurs. Add more if you like.
NOTE:SYNTAX is a generic error message used when nothing else seems
appropriate.
*/
enum error_msg
{SYNTAX,UNBAL_PARENS,NO_EXP,EQUALS_EXPECTED,NOT_VAR,PARAM_ERR,
SEMI_EXPECTED,UNBAL_BRACES,FUNC_UNDEF,TYPE_EXPECTED,NEST_FUNC,
RET_NOCALL,PAREN_EXPECTED,WHILE_EXPECTED,QUOTE_EXPECTED,NOT_TEMP,
TOO_MANY_LVARS};
char *prog; /* current location in source code */
char *p_buf; /* points to start of program buffer */
jmp_buf e_buf; /* hold environment for longjmp() */
/* An array of these structures will hold the info
associated with global variables.
*/
struct var_type {
char var_name[ID_LEN];
int var_type;
int value;
} global_vars[NUM_GLOBAL_VARS];
struct var_type local_var_stack[NUM_LOCAL_VARS];
struct func_type {
char func_name[ID_LEN];
char *loc; /* location of entry point in file */
}func_table[NUM_FUNC];
int call_stack[NUM_FUNC];
struct commands { /* keyword lookup table */
char command[20];
char tok;
}table[]={ /* Commands must be entered lowercase */
"if",IF, /* in this table. */
"else",ELSE,
"for",FOR,
"do",DO,
"while",WHILE,
"char",CHAR,
"int",INT,
"return",RETURN,
"end",END,
"",END /* mark end of table */
};
char token[80];
char token_type,tok;
int functos; /* index to top of function call stack */
int func_index; /* index into function table */
int gvar_index; /* index into global variable table */
int lvartos; /* index into local variable stack */
int ret_value; /* function return value */
void print(void),prescan(void);
void decl_global(void),call(void),putback(void);
void decl_local(void),local_push(struct var_type i);
void eval_exp(int *value),sntx_err(int error);
void exec_if(void),find_eob(void),exec_for(void);
void get_params(void),get_args(void);
void exec_while(void),func_push(int i),exec_do(void);
void assign_var(char *var_name,int value);
int load_program(char *p,char *fname),find_var(char *s);
void interp_block(void),func_ret(void);
int func_pop(void),is_var(char *s),get_token(void);
char *find_func(char *name);
main(int argc,char *argv[])
{
if(argc!=2) {
printf("usage: littlec <filename>\n");
exit(1);
}
/* allocate memory for the program */
if((p_buf=(char *) malloc(PROG_SIZE))==NULL) {
printf("allocation failure");
exit(1);
}
/* load the program to execute */
if(!load_program(p_buf,argv[1])) exit(1);
if(setjmp(e_buf)) exit(1); /* initialize long jump buffer */
/* set program pointer to start of program buffer */
prog=p_buf;
prescan(); /* find the location of all functions
and global variables in the program */
gvar_index=0; /* initialize global variable index */
lvartos=0; /* initialize local variable stack index */
functos=0; /* initialize the CALL stack index */
/* setup call to main() */
prog=find_func("main"); /* find program starting point */
prog--; /* back up to opening ( */
strcpy(token,"main");
call(); /* call main() to start interpreting */
}
/* Interpret a single statement or block of code. When
interp_block() returns from its initial call, the final
brace ( or a return) in main() has been encountered.
*/
void interp_block(void)
{
int value;
char block=0;
do {
token_type=get_token();
/* If interpreting single statement, return
on first semicolon.
*/
/* see what kind of token is up */
if(token_type==IDENTIFIER) {
/* Not a keyword, so process expression. */
putback(); /* restore token to input stream for
further processing by eval_exp() */
eval_exp(&value); /* process the expression */
if(*token!=';') sntx_err(SEMI_EXPECTED);
}
else if(token_type==BLOCK) { /* if block delimiter */
if(*token=='{') /* is a block */
block=1; /* interpreting block, not statement */
else return; /* is a }, so return */
}
else /* is keyword */
switch(tok) {
case CHAR:
case INT: /* declare local variables */
putback();
decl_local();
break;
case RETURN: /* return from function call */
func_ret();
return;
case IF: /* process an if statement */
exec_if();
break;
case ELSE: /* process an else statement */
find_eob(); /* find end of else block
and continue execution */
break;
case WHILE: /* process a while loop */
exec_while();
break;
case DO: /* process a do-while loop */
exec_do();
break;
case FOR:
exec_for(); /* process a for loop */
break;
case END:
exit(0);
}
}while(tok!=FINISHED && block);
}
/* Load a program. */
load_program(char *p,char *fname)
{
FILE *fp;
int i=0;
if((fp=fopen(fname,"rb"))==NULL) return 0;
i=0;
do {
*p=getc(fp);
p++;i++;
}while(!feof(fp) && i<PROG_SIZE);
*(p-2)='\0'; /* null terminate the program */
fclose(fp);
return 1;
}
/* Find the location of all functions in the program
and store global variables. */
void prescan(void)
{
char *p;
char temp[32];
int brace=0; /* When 0,this var tells us that current
source position is outside of
any function. */
p=prog;
func_index=0;
do {
while(brace) { /* bypass code inside functions */
get_token();
if(*token=='{') brace++;
if(*token=='}') brace--;
}
get_token();
if(tok==CHAR || tok==INT) { /* is global var */
putback();
decl_global();
}
else if(token_type==IDENTIFIER) {
strcpy(temp,token);
get_token();
if(*token=='(') { /* must be assume a function */
func_table[func_index].loc=prog;
strcpy(func_table[func_index].func_name,temp);
func_index++;
while(*prog!=')') prog++;
prog++;
/* prog points to opening curly brace of function */
}
else putback();
}
else if(*token=='{') brace++;
}while(tok!=FINISHED);
prog=p;
}
/* Return the entry point of the specified function.
Return NULL if not found.
*/
char *find_func(char *name)
{
register int i;
for(i=0;i<func_index;i++)
if(!strcmp(name,func_table[i].func_name)) return func_table[i].loc;
return NULL;
}
/* Declare a global variable. */
void decl_global(void)
{
get_token(); /* get type */
global_vars[gvar_index].var_type=tok;
global_vars[gvar_index].value=0; /* init to 0 */
do { /* process comma-separated list */
get_token(); /* get name */
strcpy(global_vars[gvar_index].var_name,token);
get_token();
gvar_index++;
}while(*token==',');
if(*token!=';') sntx_err(SEMI_EXPECTED);
}
/* Declare a local variable. */
void decl_local(void)
{
struct var_type i;
get_token(); /* get type */
i.var_type=tok;
i.value=0; /* init to 0 */
do { /* process comma-separated list */
get_token(); /* get var name */
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
用C语言编的一个小解释器,可以执行C程序的!算是可以执行C程序的C程序吧! 选自最新C语言精华(第三版) Herbert Schildt著- A small interpreter arranges which with the C language, may carry out the C procedure! Is may carry out C the procedure C procedure! (Master) writes oh!
资源推荐
资源详情
资源评论
收起资源包目录
interpreter_of_little_C.rar (3个子文件)
interpreter_of_little_C
PARSER.C 8KB
TCLIB.C 3KB
LITTLEC.C 14KB
共 3 条
- 1
资源评论
- s_peach2014-04-23找了好久,效果还不错。
清钟沁桐
- 粉丝: 189
- 资源: 68
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功