stmt_t parse_stmt_if(tokenizer_t t) { char * filename = cur_tok(t).filename; int line = cur_tok(t).line_num; eat_it(t, TOK_IF); eat_it(t, TOK_LPAREN); expr_t e = parse_expr(t); eat_it(t, TOK_RPAREN); stmt_t th = parse_stmt(t); stmt_t el = NULL; if(cur_tok(t).kind == TOK_ELSE) { eat_it(t, TOK_ELSE); el = parse_stmt(t); } return mk_stmt_if(filename, line, e, th, el); }
function parse_function(str_iter& iter) { token cur_tok; // str name; // type return_ty; function ret; cur_tok = token::eat(iter, token_kind::identifier); // name = cur_tok.data.identifier; token::eat(iter, token_kind::open_paren); token::eat(iter, token_kind::close_paren); token::eat(iter, token_kind::skinny_arrow); cur_tok = token::eat(iter, token_kind::identifier); /* return type */ // return_ty = resolve(cur_tok.data.identifier); token::eat(iter, token_kind::open_brace); // ret = function_new(name, return_ty); while (1) { statement cur_stmt; switch ((cur_stmt = parse_stmt(iter)).kind) { case Stmt_return: { function_add_stmt(&ret, cur_stmt); } break; case Stmt_none: { } return ret; } } }
struct t_value * exec_stmt(struct t_exec *exec) { struct t_value *res; struct t_token *token; debug(1, "%s(): Calling parse_stmt()\n", __FUNCTION__); if (parse_stmt(&exec->parser) < 0) { res = NULL; } else { debug(1, "%s(): Calling exec_run()\n", __FUNCTION__); if (exec_run(exec) < 0) { res = NULL; } else { res = list_pop(&exec->stack); } } token = parser_token(&exec->parser); if (!res) { while (token->type != TT_EOL && token->type != TT_EOF) { token = parser_next(&exec->parser); } } while (token->type == TT_EOL) { token = parser_next(&exec->parser); } return res; }
stmt_t parse_stmt_if(tokenizer_t t) { eat_it(t, TOK_IF); eat_it(t, TOK_LPAREN); expr_t e = parse_expr(t); eat_it(t, TOK_RPAREN); stmt_t body = parse_stmt(t); stmt_t else_body = NULL; if(cur_tok(t).kind == TOK_ELSE){ eat_it(t, TOK_ELSE); else_body = parse_stmt(t); }else{ // else はまだ空文 else_body = NULL; } return mk_stmt_if(t->filename, t->line, e, body, else_body); }
stmt_t parse_stmt_while(tokenizer_t t) { char *filename = cur_tok(t).filename; int line_num = cur_tok(t).line_num; eat_it(t, TOK_WHILE); eat_it(t, TOK_LPAREN); expr_t e = parse_expr(t); eat_it(t, TOK_RPAREN); stmt_t body = parse_stmt(t); return mk_stmt_while(filename, line_num, e, body); }
stmt_t parse_stmt_while(tokenizer_t t) { /** while(1) */ eat_it(t, TOK_WHILE); eat_it(t, TOK_LPAREN); expr_t e = parse_expr(t); eat_it(t, TOK_RPAREN); /** { ; ; ; } */ stmt_t body = parse_stmt(t); return mk_stmt_while(t->filename, t->line, e, body); }
void stmt_parse(Stmt* stmt) { Trace("stmt_parse"); assert(stmt_is_valid(stmt)); if (verbose >= VERB_VERBOSE) printf("Parsing %s %d\n", stmt->filename, stmt->lineno); parse_stmt(stmt); stmt->node = code_get_root(); }
stmt_t parse_comp_stmt(tokenizer_t t) { char * filename = cur_tok(t).filename; int line = cur_tok(t).line_num; eat_it(t, TOK_LBRACE); stmt_list_t c = mk_stmt_list(); var_decl_list_t d = parse_var_decl(t); stmt_t x; while(cur_tok(t).kind != TOK_RBRACE) { x = parse_stmt(t); stmt_list_add(c, x); } eat_it(t, TOK_RBRACE); return mk_stmt_compound(filename, line, d, c); }
// Parse a program. // // program ::= stmt-list // stmt-list ::= stmt ';' | stmt-list ';' stmt // Tree* parse_program(Parser& p) { Tree_seq* stmts = new Tree_seq(); while (not parse::end_of_stream(p)) { // Parse the next statement... if (Tree* s = parse_stmt(p)) stmts->push_back(s); else return nullptr; // ... and it's trailing ';' if (not parse::expect(p, semicolon_tok)) return nullptr; } return new Prog_tree(stmts); }
void parse_stmts() { switch(next_token.type) { case TT_TYPE_DOUBLE: case TT_TYPE_INT: case TT_TYPE_STRING: case TT_TYPE_AUTO: case TT_IDENTIFICATOR: case TT_KW_RETURN: case TT_KW_COUT: case TT_KW_CIN: case TT_BLOCK_START: case TT_KW_IF: case TT_KW_FOR: parse_stmt(); parse_stmts(); break; default: return; } }
stmt_t parse_stmt_compound(tokenizer_t t){ stmt_list_t list = mk_stmt_list(); var_decl_list_t decls = mk_var_decl_list(); eat_it(t, TOK_LBRACE); // printf("var_decl_list_add begin\n"); // printf("call: parse_stmt_compound\n"); while(1){ // 型宣言じゃなかったら修了 if(cur_tok(t).kind != TOK_INT){ break; }else{ // printf("var_decl_list_add\n"); var_decl_list_add(decls, parse_decl(t)); } } while(1){ if(cur_tok(t).kind != TOK_RBRACE){ // printf("stmt_list_add\n"); stmt_t s = parse_stmt(t); stmt_list_add(list, s); // printf("s->kind: %d\n", s->kind); }else{ // } でリスト終了 break; } } eat_it(t, TOK_RBRACE); stmt_t comp = mk_stmt_compound(t->filename, t->line, decls, list); return comp; }
LoadTedrc(char *tedname, int depth, int kdefmapno) { FILE *fp; char ss[8192],ibuf[2048],*tt,*uu,*vv,*ww,*xx; int len,i,j,lno; int hdef[128]; extern int X_inited; KEYDEF *kdef=kdefmap[kdefmapno]; int kdefno=kdefno_m[kdefmapno]; if ((fp=init_tedrc_fname(tedname, depth))==NULL) return 1; if (kdefno && !depth) { for(j=0;j<kdefno;j++) free(kdef[j].cmd); if (!kdefmapno) free_lang(); free(kdef); kdefmap[kdefmapno]=NULL; if (kdefmapno) { free(mode_str_m[kdefmapno]); mode_str_m[kdefmapno]=NULL; } kdef=NULL; } #if 0 printf("-- %d %d %s\n",depth, kdefmapno, ftedrc); #endif if (kdef==NULL) { MAX_KEY_DEF=280; if ((kdef=mmalloc(sizeof(KEYDEF)*MAX_KEY_DEF,"LoadTedrc"))==NULL) exit(1); kdefmap[kdefmapno]=kdef; kdefno_m[kdefmapno]=kdefno=0; } if (!depth) qsort(kmap,kname_no,sizeof(KEYMAP),qcmpxk); tedrcfname=tedname; lno=0; while (!feof(fp)) { int next_l; ss[0]=0; next_l=0; for(;;) { lno++; len=mfgets(ibuf,sizeof(ibuf),fp); if (!len) { next_l=1; break; } if (ibuf[len-1]=='\n') ibuf[--len]=0; if (!len) { next_l=1; break; } while (len && (ibuf[len-1]==' '||ibuf[len-1]==9)) len--; if (!len) { next_l=1; break; } if (ibuf[len-1]=='\\') { ibuf[len-1]=0; strcat(ss,ibuf); } else { strcat(ss,ibuf); break; } } if (next_l) continue; tt=skip_spc(ss); uu=to_spc(tt); vv=skip_spc(uu); *uu=0; if (tt[0]=='#') continue; if (!strcmp(tt,"d")) { ww=to_spc(vv); if (!(*vv)) lper(tedname,lno,"argument expected"); kdef[kdefno].klen=parse_key(tedname, lno,vv,ww,kdef[kdefno].kcode); if ((i=kcode_exist(kdefno,kdef,kdefno))<kdefno) free(kdef[i].cmd); xx=skip_spc(ww); kdef[i].cmd=strdup(parse_Cstr(tedname, lno,xx,&uu)); kdef[i].type=0; if (i==kdefno) incr_kdefno(&kdef,kdefmapno,&kdefno); continue; } else if (!strcmp(tt,"f")) { ww=to_spc(vv); if (!(*vv)) lper(tedname,lno,"argument expected"); kdef[kdefno].klen=parse_key(tedname, lno,vv,ww,kdef[kdefno].kcode); if ((i=kcode_exist(kdefno,kdef,kdefno))<kdefno) free(kdef[i].cmd); xx=skip_spc(ww); if (parse_stmt(tedname, lno,xx,&kdef[i].cmd,&kdef[i].type)) { if (i==kdefno) incr_kdefno(&kdef,kdefmapno,&kdefno); } continue; } if (kdefmapno) lper(tedname,lno,"%s for LoadKeyDefInto can accept 'f' and 'd' command only", tedname); if (!strcmp(tt,"s")) { ww=to_spc(vv); xx=skip_spc(ww); *ww=0; for(i=0;i<sizeof(locolor)/sizeof(locolor[0]);i++) if (!strcmp(vv,locolor[i].cname)) break; if (i==sizeof(locolor)/sizeof(locolor[0])) lper(tedname,lno,"Unknown Def color %s",vv); ww=to_spc(xx); *ww=0; strcpy(locolor[i].caddr,xx); } else if (!strcmp(tt,"set")) { ww=to_spc(vv); xx=skip_spc(ww); tt=to_spc(xx); if (!(*ww)) lper(tedname,lno,"argument expected"); *ww=0; for(i=0;i<sizeof(sets)/sizeof(sets[0]);i++) if (!strcmp(sets[i].sname,vv)) break; if (i==sizeof(sets)/sizeof(sets[0])) lper2(tedname,lno,"Unknown set %s",vv); else { *tt=0; *(sets[i].saddr)=atoi(xx); } } else if (!strcmp(tt,"lang") && !depth) { extern char DirectCommentChars[]; int keywcnt=3,LangIdx,ColIdx,AllocN=32,kwidx, MaxKeywordLen=0; char *ff; KW *kw; if (depth) p_err("cannot define 'lang' in include %s", tedname); tt=parse_Cstr(tedname, lno,vv,&uu); i=strlen(tt)+2; if ((vv=mmalloc(i,"LoadTedrc"))==NULL) exit(1); if ((kw=mmalloc(AllocN*sizeof(KW),"LoadTedrc 2"))==NULL) exit(1); LangExt[LangN]=strcat(strcpy(vv,tt)," "); kw[0].coloridx=ColorCnt; strcpy(pc_color[ColorCnt].fg_str,getstr(uu,&vv)); strcpy(pc_color[ColorCnt++].bg_str,getstr(vv,&uu)); uu=skip_spc(uu); DirectCommentChars[LangN]=*uu; kw[1].coloridx=ColorCnt; strcpy(pc_color[ColorCnt].fg_str,getstr(uu+1,&vv)); strcpy(pc_color[ColorCnt++].bg_str,getstr(vv,&uu)); kw[2].coloridx=ColorCnt; strcpy(pc_color[ColorCnt].fg_str,getstr(uu+1,&vv)); strcpy(pc_color[ColorCnt++].bg_str,getstr(vv,&uu)); for(;;) { if (!*uu) break; strcpy(pc_color[ColorCnt].fg_str,getstr(uu+1,&vv)); strcpy(pc_color[ColorCnt].bg_str,getstr(vv,&uu)); uu=skip_spc(uu); ww=tt=parse_Cstr(tedname, lno,uu,&vv); uu=vv; xx=tt+strlen(tt); for(;;) { char *pstr; tt=to_spc(ww); vv=skip_spc(tt); *(tt)=0; if (pstr=strchr(ww,'(')) { kw[keywcnt].arg=strdup(pstr); *pstr=0; } else kw[keywcnt].arg=0; kw[keywcnt].keyword=strdup(ww); if (strlen(ww) > MaxKeywordLen) MaxKeywordLen=strlen(ww); kw[keywcnt].coloridx=ColorCnt; #if 0 printf("%d %d %d %s\n",LangN,keywcnt, ColorCnt, kw[keywcnt].keyword); #endif keywcnt++; if (keywcnt+3>=AllocN) { AllocN+=32; if ((kw=mrealloc(kw,AllocN*sizeof(KW),"LoadTedrc 3"))==NULL) exit(1); } ww=vv; if (ww==xx) break; } ColorCnt++; } qsort(kw+3,keywcnt-3,sizeof(KW), kwcmp); LangKw[LangN]=kw; LangMaxKeywordLen[LangN]=MaxKeywordLen; LangKwN[LangN++]=keywcnt; if (LangN>=MaxLang) { error("Too many languages defined"); error("Remove unused language in tedrc or modify ted.h and recompile"); exit(1); } } else if (!strcmp(tt,"include")) { if (depth > 10) { error("include too many level ??"); continue; } ww=to_spc(vv); xx=skip_spc(ww); if (!(*vv)) lper(tedname,lno,"argument expected"); *ww=0; LoadTedrc(vv,depth+1,kdefmapno); tedrcfname=tedname; } else if (!strcmp(tt,"filebrowser")) { ww=to_spc(vv); xx=skip_spc(ww); if (!(*vv)) lper(tedname,lno,"argument expected"); init_reg_exp(vv); } else if (!strcmp(tt,"fontlist")) { ww=to_spc(vv); xx=skip_spc(ww); if (!(*vv)) lper(tedname,lno,"argument expected"); setFontList(vv); } else if (!strcmp(tt,"LoadKeyDefInto")) { int no; char mstr[16], *p; tt=parse_Cstr(tedname, lno,vv,&uu); if (!(*tt)) lper(tedname,lno,"file name expected"); ww=skip_spc(uu); if (!*ww) lper(tedname,lno,"Bind number expected"); no=*ww-'0'; if (no<=0 || no>=4) lper(tedname,lno,"Bind number must be less than 4 and greater than 0"); if ((p=strchr(tt,'.'))==NULL) { mode_str_m[no]=" "; } else { p++; if (! *p) mode_str_m[no]=strdup(" "); else mode_str_m[no]=strdup(p); } LoadTedrc(tt,0,no); } } fclose(fp); if (!depth) { kdefno=kdefno_m[kdefmapno]; qsort(kdef,kdefno,sizeof(kdef[0]),qcmp); bzero(hdef,sizeof(hdef)); bzero(kdefhash[kdefmapno],128*sizeof(int)); for(i=0;i<kdefno;i++) { j=KEYHASH(kdef[i].kcode[0]); if (hdef[j]) continue; hdef[j]=1; kdefhash[kdefmapno][j]=i; } kdefhash[kdefmapno][127]=kdefno; for(i=126;i>=0;i--) if (!hdef[i]) kdefhash[kdefmapno][i]=kdefhash[kdefmapno][i+1]; ReLoadTed=1; if (X_inited) alloc_pc_colors(); } return 0; }
/*------------------------------------------------------------------------- * Function: parse_stmt * * Purpose: Parses a statement which is a function name followed by * zero or more arguments. * * Return: Success: Ptr to parse tree. * * Failure: NIL, input consumed through end of line. * * Programmer: Robb Matzke * [email protected] * Dec 4 1996 * * Modifications: * * Robb Matzke, 11 Dec 1996 * If IMPLIED_PRINT is true then wrap the input in a call to the * `print' function if it isn't already obviously a call to `print'. * * Robb Matzke, 20 Jan 1997 * Turn off handling of SIGINT during parsing. * * Robb Matzke, 7 Feb 1997 * If the first thing on the line is a symbol which has a built in * function (BIF) as its f-value, and the BIF has the lex_special * property, then we call lex_special() to prepare the next token. * * Robb Matzke, 2000-06-28 * Signal handlers are registered with sigaction() since its behavior * is more consistent. * *------------------------------------------------------------------------- */ obj_t parse_stmt (lex_t *f, int implied_print) { char *lexeme, buf[1024], *s, *fmode; int tok, i; obj_t head=NIL, opstack=NIL, b1=NIL, retval=NIL, tmp=NIL; struct sigaction new_action, old_action; /* SIGINT should have the default action while we're parsing */ new_action.sa_handler = SIG_DFL; sigemptyset(&new_action.sa_mask); new_action.sa_flags = SA_RESTART; sigaction(SIGINT, &new_action, &old_action); tok = lex_token (f, &lexeme, false); /* * At the end of the file, return `(exit)'. */ if (TOK_EOF==tok) { lex_consume (f); if (f->f && isatty (fileno (f->f))) { printf ("exit\n"); retval = obj_new (C_CONS, obj_new (C_SYM, "exit"), NIL); goto done; } else { retval = obj_new (C_SYM, "__END__"); goto done; } } /* * For an empty line, eat the linefeed token and try again. */ if (TOK_EOL==tok) { lex_consume (f); retval = parse_stmt (f, implied_print); goto done; } /* * A statement begins with a function name. If the first token * is not a symbol then assume `print'. */ if (implied_print && TOK_SYM==tok) { head = obj_new (C_SYM, lexeme); if ((tmp=sym_fboundp (head))) { tmp = obj_dest (tmp); lex_consume (f); } else { obj_dest (head); head = obj_new (C_SYM, "print"); } } else if (implied_print) { head = obj_new (C_SYM, "print"); } else { head = &ErrorCell ; /*no function yet*/ } /* * Some functions take a weird first argument that isn't really a * normal token. Like `open' which wants the name of a file. We * call lex_special() to try to get such a token if it appears * next. */ if (head && &ErrorCell!=head && (tmp=sym_fboundp(head))) { if (bif_lex_special (tmp)) lex_special (f, false); tmp = obj_dest (tmp); } /* * Read the arguments... */ while (&ErrorCell!=(b1=parse_expr(f, false))) { opstack = obj_new(C_CONS, b1, opstack); } /* * Construct a function call which is the HEAD applied to the * arguments on the operand stack. */ b1 = F_reverse (opstack); opstack = obj_dest (opstack); if (&ErrorCell==head) { head = NIL; if (1==F_length(b1)) { retval = obj_copy (cons_head (b1), SHALLOW); b1 = obj_dest (b1); } else { retval = b1; b1 = NIL; } } else { retval = F_cons (head, b1); head = obj_dest (head); b1 = obj_dest (b1); } /* * A statement can end with `>' or `>>' followed by the name of * a file, or `|' followed by an unquoted shell command. Leading * and trailing white space is stripped from the file or command. */ tok = lex_token (f, &lexeme, false); if (TOK_RT==tok || TOK_RTRT==tok || TOK_PIPE==tok) { lex_consume (f); if (NULL==lex_gets (f, buf, sizeof(buf))) { out_errorn ("file name required after `%s' operator", lexeme); goto error; } lex_set (f, TOK_EOL, "\n"); for (s=buf; isspace(*s); s++) /*void*/; for (i=strlen(s)-1; i>=0 && isspace(s[i]); --i) s[i] = '\0'; if (!*s) { out_errorn ("file name required after `%s' operator", lexeme); goto error; } switch (tok) { case TOK_RT: lexeme = "Redirect"; fmode = "w"; break; case TOK_RTRT: lexeme = "Redirect"; fmode = "a"; break; case TOK_PIPE: lexeme = "Pipe"; fmode = "w"; break; default: abort(); } retval = obj_new (C_CONS, obj_new (C_SYM, lexeme), obj_new (C_CONS, retval, obj_new (C_CONS, obj_new (C_STR, s), obj_new (C_CONS, obj_new (C_STR, fmode), NIL)))); } /* * We should be at the end of a line. */ tok = lex_token (f, &lexeme, false); if (TOK_EOL!=tok && TOK_EOF!=tok) { s = lex_gets (f, buf, sizeof(buf)); if (s && strlen(s)>0 && '\n'==s[strlen(s)-1]) s[strlen(s)-1] = '\0'; out_errorn ("syntax error before: %s%s", lexeme, s?s:""); lex_consume(f); goto error; } else { lex_consume(f); } done: sigaction(SIGINT, &old_action, NULL); return retval; error: if (head) head = obj_dest (head); if (opstack) opstack = obj_dest (opstack); if (retval) retval = obj_dest (retval); sigaction(SIGINT, &old_action, NULL); return NIL; }
} FOLD_EXPR(t->expr, t->symtab); EAT(token_close_paren); } static stmt *parse_if(const struct stmt_ctx *const ctx) { stmt *t = stmt_new_wrapper(if, ctx->scope); struct stmt_ctx subctx = *ctx; EAT(token_if); parse_test_init_expr(t, &subctx); t->lhs = parse_stmt(&subctx); if(accept(token_else)) t->rhs = parse_stmt(&subctx); return t; } static stmt *parse_switch(const struct stmt_ctx *const ctx) { stmt *t = stmt_new_wrapper(switch, ctx->scope); struct stmt_ctx subctx = *ctx; subctx.break_target = t; subctx.switch_target = t;