struct prog *parse(void) { lookahead[0] = gettok(); lookahead[1] = gettok(); struct prog *prog = parse_prog(); freetok(tok); freetok(lookahead[0]); freetok(lookahead[1]); return prog; }
/** * コンパイルを行う * @param char *file 書き出すファイル名 * @return int 成否 */ int compile(char *file) { ProgPtr pp = NULL; TEnvPtr tenv = NULL; TC_TypePtr ttp = NULL; TyType t = UNKNOWN_TYPE; FILE *ofp = NULL; char mes[MESSAGE_MAX_BUF_SIZE] = ""; char ofile[FILE_NAME_MAX_SIZE] = ""; char ext[] = ".j"; /* 構文解析を実行 */ pp = prog_alloc(); if(0 == parse_prog(pp)) return 0; tenv = tenv_alloc(); if( NULL != (ttp = typing_prog(tenv, pp)) ) { t = norm(ttp)->t; } else { printf("typing error.\n"); return 0; } strncpy_s(ofile, FILE_NAME_MAX_SIZE, file, strlen(file)); strncat_s(ofile, FILE_NAME_MAX_SIZE, ext, strlen(ext)); if( 0 != fopen_s(&ofp, ofile, "w") ) { perror("fopen_s"); return 0; } fprintf_s(ofp, ".class public %s\n", file); fprintf_s(ofp, ".super java/lang/Object\n", file); codegen_prog(ofp, file, t, pp, fenvc_alloc()); fclose(ofp); return 1; }
int main(int argc, char *argv[]) { fp = fopen(argv[1], "r"); prog = new_list(1000); read_file(fp, prog); parse_prog(prog); return 0; }
/* parse program arguments (builtins are also parsed this way first) */ static void parse_prog(cmds* cmd, prog_args* prog) { switch(lookahead.kind) { /* end of program arguments? */ case AMP: prog->background=true; case SEP: case END: case STROKE: return; /* redirections? */ case IN: case OUT: parse_redirection(prog); break; /* argument? */ case IDE: argv_add(prog,get_ide()); break; default: raise_error(PARSER_INVALID_STATE); } /* parse next program argument */ scan(); parse_prog(cmd,prog); }
/* distinguish builtin commands from parsed program arguments */ static void parse_cmd(cmds* cmd, prog_args* prog) { char* path = NULL; /* path for cd */ char* name = NULL; /* name of environment variable */ char* value = NULL; /* value of environment variable */ int id = -1; /* job id */ parse_prog(cmd, prog); /* any command supplied? */ if (prog->argc==0) raise_error(PARSER_MISSING_COMMAND); /* exit command? */ if (!strcmp(prog->argv[0],"exit")) { /* used in pipe? */ if (cmd->kind!=PROG) raise_error(PARSER_ILLEGAL_COMBINATION); /* make exit command */ argv_free(prog); cmd->kind=EXIT; return; } /* cd command */ if (!strcmp(prog->argv[0],"cd")) { /* used in pipe? */ if (cmd->kind==PIPE) raise_error(PARSER_ILLEGAL_COMBINATION); /* make cd command */ if (prog->argc>=2) { path = strdup(prog->argv[1]); if (path==NULL) raise_error(PARSER_MALLOC); } argv_free(prog); cmd->kind=CD; cmd->cd.path=path; return; } /* unset an environment variable */ if (!strcmp(prog->argv[0],"unsetenv")) { /* used in pipe? */ if (cmd->kind==PIPE) raise_error(PARSER_ILLEGAL_COMBINATION); /* enough args? */ if (prog->argc<2) raise_error(PARSER_MISSING_ARGUMENT); /* make env command */ name = strdup(prog->argv[1]); if (name==NULL) raise_error(PARSER_MALLOC); argv_free(prog); cmd->kind=ENV; cmd->env.name=name; cmd->env.value=NULL; return; } /* set an environment variable */ if (!strcmp(prog->argv[0],"setenv")) { /* used in pipe? */ if (cmd->kind==PIPE) raise_error(PARSER_ILLEGAL_COMBINATION); /* enough args? */ if (prog->argc<3) raise_error(PARSER_MISSING_ARGUMENT); /* make env command */ name = strdup(prog->argv[1]); if (name==NULL) raise_error(PARSER_MALLOC); value = strdup(prog->argv[2]); if (value==NULL) { free(name); raise_error(PARSER_MALLOC); } argv_free(prog); cmd->kind=ENV; cmd->env.name=name; cmd->env.value=value; return; } /* request job infos */ if (!strcmp(prog->argv[0],"jobs")) { /* used in pipe? */ if (cmd->kind==PIPE) raise_error(PARSER_ILLEGAL_COMBINATION); /* make job command */ if (prog->argc>=2) id=get_int(prog->argv[1]); argv_free(prog); cmd->kind=JOB; cmd->job.kind=INFO; cmd->job.id=id; return; } /* continue a stopped job in background */ if (!strcmp(prog->argv[0],"bg")) { /* used in pipe? */ if (cmd->kind==PIPE) raise_error(PARSER_ILLEGAL_COMBINATION); /* make job command */ if (prog->argc>=2) id=get_int(prog->argv[1]); argv_free(prog); cmd->kind=JOB; cmd->job.kind=BG; cmd->job.id=id; return; } /* continue a job in foreground */ if (!strcmp(prog->argv[0],"fg")) { /* used in pipe? */ if (cmd->kind==PIPE) raise_error(PARSER_ILLEGAL_COMBINATION); /* make job command */ if (prog->argc>=2) id=get_int(prog->argv[1]); argv_free(prog); cmd->kind=JOB; cmd->job.kind=FG; cmd->job.id=id; return; } /* check input for input redirection in pipe */ if (cmd->kind==PIPE && prog->input != NULL) { raise_error(PARSER_ILLEGAL_REDIRECTION); } }