📄 aicasm_scan.l
字号:
BEGIN MACROARGLIST; yylval.sym = symtable_get(yytext); unput('('); return T_SYMBOL; }<MACROARGLIST>{WORD} { yylval.str = yytext; return T_ARG; }<MACROARGLIST>{SPACE} ;<MACROARGLIST>[(,] { return yytext[0]; }<MACROARGLIST>[)] { string_buf_ptr = string_buf; BEGIN MACROBODY; return ')'; }<MACROARGLIST>. { snprintf(buf, sizeof(buf), "Invalid character " "'%c' in macro argument list", yytext[0]); stop(buf, EX_DATAERR); }<MACROCALLARGS>{SPACE} ;<MACROCALLARGS>\( { parren_count++; if (parren_count == 1) return ('('); *string_buf_ptr++ = '('; }<MACROCALLARGS>\) { parren_count--; if (parren_count == 0) { BEGIN INITIAL; return (')'); } *string_buf_ptr++ = ')'; }<MACROCALLARGS>{MCARG} { char *yptr; yptr = yytext; while (*yptr) *string_buf_ptr++ = *yptr++; }<MACROCALLARGS>\, { if (string_buf_ptr != string_buf) { /* * Return an argument and * rescan this comma so we * can return it as well. */ *string_buf_ptr = '\0'; yylval.str = string_buf; string_buf_ptr = string_buf; unput(','); return T_ARG; } return ','; }<MACROBODY>\\\n { /* Eat escaped newlines. */ ++yylineno; }<MACROBODY>\r ;<MACROBODY>\n { /* Macros end on the first unescaped newline. */ BEGIN INITIAL; *string_buf_ptr = '\0'; yylval.str = string_buf; ++yylineno; return T_MACROBODY; }<MACROBODY>{MBODY} { char *yptr; char c; yptr = yytext; while (c = *yptr++) { /* * Strip carriage returns. */ if (c == '\r') continue; *string_buf_ptr++ = c; } }{WORD}\( { char *yptr; char *ycopy; /* May be a symbol or a macro invocation. */ yylval.sym = symtable_get(yytext); if (yylval.sym->type == MACRO) { YY_BUFFER_STATE old_state; YY_BUFFER_STATE temp_state; ycopy = strdup(yytext); yptr = ycopy + yyleng; while (yptr > ycopy) unput(*--yptr); old_state = YY_CURRENT_BUFFER; temp_state = yy_create_buffer(stdin, YY_BUF_SIZE); yy_switch_to_buffer(temp_state); mm_switch_to_buffer(old_state); mmparse(); mm_switch_to_buffer(temp_state); yy_switch_to_buffer(old_state); mm_delete_buffer(temp_state); expand_macro(yylval.sym); } else { if (yylval.sym->type == UNINITIALIZED) { /* Try without the '(' */ symbol_delete(yylval.sym); yytext[yyleng-1] = '\0'; yylval.sym = symtable_get(yytext); } unput('('); return T_SYMBOL; } }{WORD} { yylval.sym = symtable_get(yytext); if (yylval.sym->type == MACRO) { expand_macro(yylval.sym); } else { return T_SYMBOL; } }. { snprintf(buf, sizeof(buf), "Invalid character " "'%c'", yytext[0]); stop(buf, EX_DATAERR); }%%typedef struct include { YY_BUFFER_STATE buffer; int lineno; char *filename; SLIST_ENTRY(include) links;}include_t;SLIST_HEAD(, include) include_stack;voidinclude_file(char *file_name, include_type type){ FILE *newfile; include_t *include; newfile = NULL; /* Try the current directory first */ if (includes_search_curdir != 0 || type == SOURCE_FILE) newfile = fopen(file_name, "r"); if (newfile == NULL && type != SOURCE_FILE) { path_entry_t include_dir; for (include_dir = search_path.slh_first; include_dir != NULL; include_dir = include_dir->links.sle_next) { char fullname[PATH_MAX]; if ((include_dir->quoted_includes_only == TRUE) && (type != QUOTED_INCLUDE)) continue; snprintf(fullname, sizeof(fullname), "%s/%s", include_dir->directory, file_name); if ((newfile = fopen(fullname, "r")) != NULL) break; } } if (newfile == NULL) { perror(file_name); stop("Unable to open input file", EX_SOFTWARE); /* NOTREACHED */ } if (type != SOURCE_FILE) { include = (include_t *)malloc(sizeof(include_t)); if (include == NULL) { stop("Unable to allocate include stack entry", EX_SOFTWARE); /* NOTREACHED */ } include->buffer = YY_CURRENT_BUFFER; include->lineno = yylineno; include->filename = yyfilename; SLIST_INSERT_HEAD(&include_stack, include, links); } yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); yylineno = 1; yyfilename = strdup(file_name);}static void next_substitution(struct symbol *mac_symbol, const char *body_pos, const char **next_match, struct macro_arg **match_marg, regmatch_t *match);voidexpand_macro(struct symbol *macro_symbol){ struct macro_arg *marg; struct macro_arg *match_marg; const char *body_head; const char *body_pos; const char *next_match; /* * Due to the nature of unput, we must work * backwards through the macro body performing * any expansions. */ body_head = macro_symbol->info.macroinfo->body; body_pos = body_head + strlen(body_head); while (body_pos > body_head) { regmatch_t match; next_match = body_head; match_marg = NULL; next_substitution(macro_symbol, body_pos, &next_match, &match_marg, &match); /* Put back everything up until the replacement. */ while (body_pos > next_match) unput(*--body_pos); /* Perform the replacement. */ if (match_marg != NULL) { const char *strp; next_match = match_marg->replacement_text; strp = next_match + strlen(next_match); while (strp > next_match) unput(*--strp); /* Skip past the unexpanded macro arg. */ body_pos -= match.rm_eo - match.rm_so; } } /* Cleanup replacement text. */ STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { free(marg->replacement_text); }}/* * Find the next substitution in the macro working backwards from * body_pos until the beginning of the macro buffer. next_match * should be initialized to the beginning of the macro buffer prior * to calling this routine. */static voidnext_substitution(struct symbol *mac_symbol, const char *body_pos, const char **next_match, struct macro_arg **match_marg, regmatch_t *match){ regmatch_t matches[2]; struct macro_arg *marg; const char *search_pos; int retval; do { search_pos = *next_match; STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) { retval = regexec(&marg->arg_regex, search_pos, 2, matches, 0); if (retval == 0 && (matches[1].rm_eo + search_pos) <= body_pos && (matches[1].rm_eo + search_pos) > *next_match) { *match = matches[1]; *next_match = match->rm_eo + search_pos; *match_marg = marg; } } } while (search_pos != *next_match);}intyywrap(){ include_t *include; yy_delete_buffer(YY_CURRENT_BUFFER); (void)fclose(yyin); if (yyfilename != NULL) free(yyfilename); yyfilename = NULL; include = include_stack.slh_first; if (include != NULL) { yy_switch_to_buffer(include->buffer); yylineno = include->lineno; yyfilename = include->filename; SLIST_REMOVE_HEAD(&include_stack, links); free(include); return (0); } return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -