struct vars *parse_vars() { struct vars *v; v = malloc(sizeof(struct vars)); if (v == NULL) { perror("No memory"); return NULL; } v->decl = parse_decl(); if (v->decl == NULL) { free(v); return NULL; } if (get_token().type != T_SEP) { unget_token(); v->v = NULL; return v; } v->v = parse_vars(); if (v->v == NULL) { unget_token(); } return v; }
void parse(std::string text) throw (coord) { context ctx { text }; ctx.next = coord { 0, 1, 1 }; next_token(ctx); parse_decl(ctx); if (ctx.tag != END) throw ctx.start; }
static void parse_test_init_expr(stmt *t, struct stmt_ctx *ctx) { where here; where_cc1_current(&here); EAT(token_open_paren); /* if C99, we create a new scope here, for e.g. * if(5 > (enum { a, b })a){ return a; } return b; * "return b" can't see 'b' since its scope is only the if * * C90 drags the scope of the enum up to the enclosing block */ if(cc1_std >= STD_C99){ ctx->scope = t->symtab = symtab_new(t->symtab, &here); } if(parse_at_decl(ctx->scope, 1)){ decl *d; /* if we are at a type, push a scope for it, for * for(int i ...), if(int i = ...) etc */ symtable *init_scope = symtab_new(t->symtab, &here); t->flow = stmt_flow_new(init_scope); d = parse_decl( DECL_SPEL_NEED, 0, init_scope, init_scope); UCC_ASSERT(d, "at decl, but no decl?"); UCC_ASSERT( t->flow->for_init_symtab == init_scope, "wrong scope for stmt-init"); flow_fold(t->flow, &t->symtab); ctx->scope = t->symtab; /* `d' is added to the scope implicitly */ if(accept(token_comma)){ /* if(int i = 5, i > f()){ ... } */ t->expr = parse_expr_exp(ctx->scope, 0); }else{ /* if(int i = 5) -> if(i) */ t->expr = expr_new_identifier(d->spel); } }else{ t->expr = parse_expr_exp(t->symtab, 0); } FOLD_EXPR(t->expr, t->symtab); EAT(token_close_paren); }
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; }
int fcat_write_index_file(const char *dest, const char *src) { FILE *srcfd; FILE *destfd; struct token *t; int err = 0; struct decl **dec; struct token *curstd = NULL; struct token *curhead = NULL; unsigned long lines[4096] = { 0 }; int i; char buf[1024]; unsigned long count; fpos_t offsetpos; if ((srcfd = fopen(src, "r")) == NULL) { perror(src); return -1; } i = 0; count = 0; while (fgets(buf, sizeof buf, srcfd) != NULL) { lines[i++] = count; count += strlen(buf); } rewind(srcfd); if ((destfd = fopen(dest, "w")) == NULL) { perror(dest); (void) fclose(srcfd); return -1; } if (lex_nwcc(create_input_file(srcfd)) != 0) { (void) fprintf(stderr, "ERROR: Cannot lex function catalogue file\n"); return -1; } doing_fcatalog = 1; for (t = toklist; t != NULL; t = t->next) { if (t->type == TOK_IDENTIFIER && curhead == NULL) { /* Not typedef */ if (curstd == NULL) { /* A new standard definition */ curstd = t; if (expect_token(&t, TOK_COMP_OPEN, 0) != 0) { err = 1; break; } } else if (curhead == NULL) { /* A new header */ curhead = t; if (expect_token(&t, TOK_OP_STRUMEMB, 0) != 0) { err = 1; break; } /* XXX assume they all end with .h */ if (expect_token(&t, TOK_IDENTIFIER, 0) != 0) { err = 1; break; } /* XXX assume they all end with .h */ if (expect_token(&t, TOK_COMP_OPEN, 0) != 0) { err = 1; break; } } } else if (t->type == TOK_COMP_CLOSE) { if (curstd == NULL) { (void) fprintf(stderr, "%d: Unexpected closing brace\n", t->line); err = 1; break; } if (curhead != NULL) { curhead = NULL; } else { curstd = NULL; } } else { struct token *sav; fpos_t curpos; char *str; struct fcat_data_entry *dent; struct fcat_hash_entry *hent; unsigned long old_fcat_data_offset; int key; if (curstd == NULL) { (void) fprintf(stderr, "%d: Unexpected " "token `%s'\n", t->line, t->ascii); err = 1; break; } /* * Must be a declaration */ sav = t; new_scope(SCOPE_CODE); dec = parse_decl(&t, DECL_NOINIT); if (dec == NULL) { (void) fprintf(stderr, "%d: Cannot parse " "declaration at '%s'\n", t->line, t->ascii); err = 1; break; } /* Read the line containing the declaration */ fgetpos(srcfd, &curpos); fseek(srcfd, lines[sav->line], SEEK_SET); if (fgets(buf, sizeof buf, srcfd) != NULL) { /* printf(" on line '%s", buf);*/ } fsetpos(srcfd, &curpos); /* * Create a new data entry for this declaration * The format is: * standard,standard2,...;header;decl */ (void) strtok(buf, "\n"); str = n_xmalloc(strlen(buf) + strlen(curhead->data) + 128); sprintf(str, "%s;%s.h;%s;%s", (char *)curstd->data, (char *)curhead->data, dec[0]->dtype->name, buf); dent = n_xmalloc(sizeof *dent); dent->text = str; old_fcat_data_offset = fcat_data_offset; fcat_data_offset += strlen(str) + 1; /* +1 for newline */ /* Append data entry */ if (data_list_head == NULL) { data_list_head = data_list_tail = dent; } else { data_list_tail->next = dent; data_list_tail = dent; } /* Create hash entry */ hent = n_xmalloc(sizeof *hent); hent->name = dec[0]->dtype->name; sprintf(hent->offset, "%lu", old_fcat_data_offset); key = fcat_hash_name(hent->name); if (hash_table_head[key] == NULL) { hash_table_head[key] = hash_table_tail[key] = hent; } else { hash_table_tail[key]->next = hent; hash_table_tail[key] = hent; } hash_table_slot_length[key] += strlen(hent->name) + strlen(" \n") + strlen(hent->offset); } } /* * The slot length array now contains the length of each slot; Turn * that into a total offset (i.e. the sum of all preceding elements * is added to the length of each entry) */ for (i = 0; i < H_TABSIZE; ++i) { if (i > 0) { hash_table_slot_length[i] += hash_table_slot_length[i - 1]; } } /* * Now write all data. First comes the slot length header which * describes the size of the hash table slots. */ for (i = 0; i < H_TABSIZE; ++i) { fprintf(destfd, "%ld", hash_table_slot_length[i]); if (i + 1 < H_TABSIZE) { fprintf(destfd, ","); } else { fprintf(destfd, "\n"); } } /* * ... followed by the data start index. We first write an * ``empty'' line of spaces, and overwrite it with the real * offset when it is known */ fgetpos(destfd, &offsetpos); fprintf(destfd, " \n"); /* * ... followed by the hash slots containing the data pointers */ for (i = 0; i < H_TABSIZE; ++i) { struct fcat_hash_entry *e; for (e = hash_table_head[i]; e != NULL; e = e->next) { fprintf(destfd, "%s;%s\n", e->name, e->offset); } } /* * ... followed by the actual data entries */ { struct fcat_data_entry *d; fpos_t curpos; long bytes_written; fgetpos(destfd, &curpos); bytes_written = ftell(destfd); fsetpos(destfd, &offsetpos); fprintf(destfd, "%ld", bytes_written); fsetpos(destfd, &curpos); for (d = data_list_head; d != NULL; d = d->next) { fprintf(destfd, "%s\n", d->text); } } (void) fclose(srcfd); (void) fclose(destfd); /* XXX return err? */ (void) err; return 0; }
struct decl * fcat_lookup_builtin_decl(const char *name, char **header, int standard) { int key; char *slot_ptr; char *end_ptr; long found_offset = -1; static char headbuf[128]; (void) standard; if (idx_map == NULL) { return NULL; } if (strncmp(name, "__builtin_", sizeof "__builtin_" - 1) == 0) { name += sizeof "__builtin_" - 1; } key = fcat_hash_name(name); if (key == 0) { /* Is first entry */ slot_ptr = hash_slot_start; end_ptr = slot_ptr + idx_slot_offsets[0]; } else { /* After end of last entry */ slot_ptr = hash_slot_start + idx_slot_offsets[key - 1]; end_ptr = slot_ptr + (idx_slot_offsets[key] - idx_slot_offsets[key - 1]); } while (slot_ptr < end_ptr) { char *offset; offset = strchr(slot_ptr, ';'); if (offset != NULL) { *offset = 0; if (strcmp(slot_ptr, name) == 0) { /* Found */ found_offset = strtol(offset+1, NULL, 10); *offset = ';'; break; } *offset = ';'; } slot_ptr = strchr(slot_ptr, '\n'); if (slot_ptr == NULL) { break; } else { ++slot_ptr; } } if (found_offset != -1) { char *data_ptr = data_area_start + found_offset; char std[64]; char head[64]; char name[64]; char decl[128]; if (sscanf(data_ptr, "%63[^;];%63[^;];%63[^;];%127[^\n]", std, head, name, decl) != 4) { char *temp; if ((temp = strchr(data_ptr, '\n')) != NULL) { *temp = 0; } (void) fprintf(stderr, "ERROR: Malformed declaration " "line `%s'", data_ptr); if (temp != NULL) { *temp = '\n'; } } else { struct token *old_toklist = toklist; struct token *newtok; int rc; char fname[128]; FILE *fd; struct decl **dec; toklist = NULL; strncpy(headbuf, head, sizeof headbuf - 1); headbuf[sizeof headbuf - 1] = 0; *header = headbuf; fd = get_tmp_file("dummy", fname, "tmp"); fprintf(fd, "%s\n", decl); rewind(fd); doing_fcatalog = 1; rc = lex_nwcc(create_input_file(fd)); unlink(fname); newtok = toklist; toklist = old_toklist; if (rc == 0) { dec = parse_decl(&newtok, DECL_NOINIT); if (dec == NULL) { (void) fprintf(stderr, "%d: Cannot parse " "declaration at '%s'\n", newtok->line, newtok->ascii); } } doing_fcatalog = 0; if (dec != NULL) { return dec[0]; } else { return NULL; } } } return NULL; }
static char* parse_buf(pTHX_ PSTATE* p_state, char *beg, char *end, U32 utf8, SV* self) { char *s = beg; char *t = beg; char *new_pos; while (!p_state->eof) { /* * At the start of this loop we will always be ready for eating text * or a new tag. We will never be inside some tag. The 't' points * to where we started and the 's' is advanced as we go. */ while (p_state->literal_mode) { char *l = p_state->literal_mode; bool skip_quoted_end = (strEQ(l, "script") || strEQ(l, "style")); char inside_quote = 0; bool escape_next = 0; char *end_text; while (s < end) { if (*s == '<' && !inside_quote) break; if (skip_quoted_end) { if (escape_next) { escape_next = 0; } else { if (*s == '\\') escape_next = 1; else if (inside_quote && *s == inside_quote) inside_quote = 0; else if (*s == '\r' || *s == '\n') inside_quote = 0; else if (!inside_quote && (*s == '"' || *s == '\'')) inside_quote = *s; } } s++; } if (s == end) { s = t; goto DONE; } end_text = s; s++; /* here we rely on '\0' termination of perl svpv buffers */ if (*s == '/') { s++; while (*l && toLOWER(*s) == *l) { s++; l++; } if (!*l && (strNE(p_state->literal_mode, "plaintext") || p_state->closing_plaintext)) { /* matched it all */ token_pos_t end_token; end_token.beg = end_text + 2; end_token.end = s; while (isHSPACE(*s)) s++; if (*s == '>') { s++; if (t != end_text) report_event(p_state, E_TEXT, t, end_text, utf8, 0, 0, self); report_event(p_state, E_END, end_text, s, utf8, &end_token, 1, self); p_state->literal_mode = 0; p_state->is_cdata = 0; t = s; } } } } #ifdef MARKED_SECTION while (p_state->ms == MS_CDATA || p_state->ms == MS_RCDATA) { while (s < end && *s != ']') s++; if (*s == ']') { char *end_text = s; s++; if (*s == ']') { s++; if (*s == '>') { s++; /* marked section end */ if (t != end_text) report_event(p_state, E_TEXT, t, end_text, utf8, 0, 0, self); report_event(p_state, E_NONE, end_text, s, utf8, 0, 0, self); t = s; SvREFCNT_dec(av_pop(p_state->ms_stack)); marked_section_update(p_state); continue; } } } if (s == end) { s = t; goto DONE; } } #endif /* first we try to match as much text as possible */ while (s < end && *s != '<') { #ifdef MARKED_SECTION if (p_state->ms && *s == ']') { char *end_text = s; s++; if (*s == ']') { s++; if (*s == '>') { s++; report_event(p_state, E_TEXT, t, end_text, utf8, 0, 0, self); report_event(p_state, E_NONE, end_text, s, utf8, 0, 0, self); t = s; SvREFCNT_dec(av_pop(p_state->ms_stack)); marked_section_update(p_state); continue; } } } #endif s++; } if (s != t) { if (*s == '<') { report_event(p_state, E_TEXT, t, s, utf8, 0, 0, self); t = s; } else { s--; if (isHSPACE(*s)) { /* wait with white space at end */ while (s >= t && isHSPACE(*s)) s--; } else { /* might be a chopped up entities/words */ while (s >= t && !isHSPACE(*s)) s--; while (s >= t && isHSPACE(*s)) s--; } s++; if (s != t) report_event(p_state, E_TEXT, t, s, utf8, 0, 0, self); break; } } if (end - s < 3) break; /* next char is known to be '<' and pointed to by 't' as well as 's' */ s++; #ifdef USE_PFUNC new_pos = parsefunc[(unsigned char)*s](p_state, t, end, utf8, self); #else if (isHNAME_FIRST(*s)) new_pos = parse_start(p_state, t, end, utf8, self); else if (*s == '/') new_pos = parse_end(p_state, t, end, utf8, self); else if (*s == '!') new_pos = parse_decl(p_state, t, end, utf8, self); else if (*s == '?') new_pos = parse_process(p_state, t, end, utf8, self); else new_pos = 0; #endif /* USE_PFUNC */ if (new_pos) { if (new_pos == t) { /* no progress, need more data to know what it is */ s = t; break; } t = s = new_pos; } /* if we get out here then this was not a conforming tag, so * treat it is plain text at the top of the loop again (we * have already skipped past the "<"). */ } DONE: return s; }