📄 scan.l
字号:
{ int ret_val; /* Provide module information then fire the end-of-module trigger. */ int_mod.pp = mod_pp; int_mod.decisions = mod_decisions; int_mod.functions = mod_functions; int_mod.lines.total = yylineno - 1; int_mod.end = TRUE; fire_mod(); int_mod.end = FALSE; ZERO(int_mod); /* See whether there is another input file to process. */ if (next_cmd_line_file < cmd_line_argc && (input_file = get_next_input_file(&next_cmd_line_file)) != NULL) if (freopen(input_file, "r", yyin) != NULL) { /* Reinitialize yacc and lex. */ init_yacc(); init_lex(); /* See whether to use the original file name as provided on the command line rather than the file name that was provided. This is in case the output of the preprocessor is the input file and there are no line directives, but we'd like to use the name of the input to the preprocessor. */ input_file_orig_name = get_next_input_file_orig_name(&next_cmd_line_file_orig_n); if (input_file_orig_name == NULL) input_file_orig_name = input_file; /* Fire the beginning-of-module trigger. */ ZERO(int_mod); int_mod.begin = TRUE; fire_mod(); int_mod.begin = FALSE; /* Tell yacc to continue. */ ret_val = 0; } else { warn(W_CANNOT_OPEN_FILE, input_file); /* Fire the end-of-project trigger. */ int_prj.end = TRUE; fire_prj(); int_prj.end = FALSE; ZERO(int_prj); /* Tell yacc to stop. */ ret_val = 1; } else { /* Fire the end-of-project trigger. */ int_prj.end = TRUE; fire_prj(); int_prj.end = FALSE; ZERO(int_prj);#ifdef DEBUG_TYPEDEF /* Used for debugging typedef processing. */ typedef_symbol_table_dump();#endif /* Tell yacc to stop. */ ret_val = 1; } return ret_val;}/* The beginning of a comment has been detected. Handle until the entire comment has been consumed, then give control back over to lex.*/static void comment(void){ int c; /* If this was just a blank line, it now becomes a comment line. */ if (line_type == BLANK_LINE) line_type = COMMENT_LINE; /* Loop until input exhausted or end-of-comment reached. */ for ( ; (c = input()) != '\0'; ) if (c == '*') /* Could be end-of-comment. */ { int c1; if ((c1 = input()) == '/') break; /* Is end-of-comment. */ else unput(c1); /* False alarm. Not end-of-comment. */ } else if (c == MTR_NEWLINE) { INCR_YYLINENO; /* Provide line information then fire the end-of-line trigger. */ int_lin.number = yylineno; int_lin.is_comment = TRUE; int_lin.end = TRUE; fire_lin(); ZERO(int_lin); /* Reset these BOOLEANs for the next line. */ found_tab = FALSE; found_space = FALSE; /* Increment the number-of-comment-lines counter. */ ++int_mod.lines.com; }}/* Count various things associated with input tokens. All input, except for comments and preprocessor lines pass through here.*/static void count(void){ int i; for (i = 0; yytext[i] != '\0'; i++) switch (yytext[i]) { case MTR_NEWLINE: /* Provide line information then fire the end-of-line trigger. */ switch (line_type) { case BLANK_LINE: int_lin.is_white = TRUE; ++int_mod.lines.white; break; case COMMENT_LINE: int_lin.is_comment = TRUE; ++int_mod.lines.com; break; case CODE_LINE: int_lin.is_code = TRUE; ++int_mod.lines.code; break; default: int_fatal(E_LINE_TYPE); } /* Reset line_type for next line. Start off assuming blank line. */ line_type = BLANK_LINE; int_lin.number = yylineno; int_lin.end = TRUE; fire_lin(); ZERO(int_lin); /* Reset these BOOLEANs for the next line. */ found_tab = FALSE; found_space = FALSE; break; /* The next two cases are trying to figure out whether spaces and tabs are both being used for indention on the same line--a little pet peeve of mine. */ case '\t': if (line_type == BLANK_LINE && found_space) int_lin.is_mixed_indent = TRUE; found_tab = TRUE; break; case ' ': if (line_type == BLANK_LINE && found_tab) int_lin.is_mixed_indent = TRUE; found_space = TRUE; break; default: /* If not one of the above, special characters, there must be code on this line. */ if (isgraph(yytext[i])) line_type = CODE_LINE; }}/* Return whether the token in yytext[] is just an identifier or is a previously typedef'd name.*/static int check_type(void){ int type; /* looking_for_tag is set to TRUE only when the parser is looking for a struct, union, or enum tag. Since tags are in a separate name space, the current lexeme can never be a typedef type name and are therefore always an identifier. */ if (looking_for_tag) type = TK_IDENTIFIER; else /* If lexeme was previously defined as a typedef type name, return token for type name, else return token for identifier. Note that the parser puts identifiers in the typedef symbol table, not the lexer. */ type = typedef_symbol_table_find(yytext) ? TK_TYPE_NAME : TK_IDENTIFIER; return type;}/* Return pointer to current input token (lexeme). */char *token(void){ return yytext;}/* Return pointer to input buffer which contains current line. */char *line(void){#if READ_LINE && (defined(ATT_SCANNER) || defined(MKS_SCANNER)) return input_line;#else return "";#endif}/* Return current line nuber. */unsigned lineno(void){ return yylineno;}/* Return string with marker character indicating current position of parser. Note that this line always ends with a newline character.*/char *marker(void){#if READ_LINE && (defined(ATT_SCANNER) || defined(MKS_SCANNER)) static char marker_str[INPUT_LINE_MAX_LEN]; char *dst_p, *src_p; /* Replace all graphic characters in input buffer with space character. */ for (dst_p = marker_str, src_p = input_line; src_p < next_char_p && *src_p != '\0' && /* Leave room for marker character, newline, and '\0'. */ dst_p < marker_str + sizeof marker_str - 2; ++dst_p, ++src_p) *dst_p = isgraph(*src_p) ? ' ' : *src_p; if (dst_p == marker_str) strcpy(dst_p, "\n"); /* Nothing scanned in yet, so can't mark. */ else strcpy(&dst_p[-1], "-\n"); /* Terminate line with marker character. */ return marker_str;#else return "";#endif}/* Fire the lex trigger with nonstandard set to TRUE. */static void found_nonstandard(void){ int_lex.nonstandard = yytext[0]; fire_lex(); ZERO(int_lex);}/* Extract and return the line number out of the #line directive. */static unsigned extract_line_number(char *string){ return (unsigned)strtol(&string[strcspn(string, "0123456789")], NULL, 10);}/* Extract and return the file name out of the #line directive. If not present, return NULL.*/static char *extract_file_name(char *string){ char *start_of_file_name; /* File name is enclosed in quotes. Return NULL if no first quote. */ start_of_file_name = strchr(string, '"'); if (start_of_file_name != NULL) { char *end_of_file_name; ++start_of_file_name; /* Skip past first quote. */ /* If no trailing quote, return NULL. */ end_of_file_name = strchr(start_of_file_name, '"'); if (end_of_file_name == NULL) start_of_file_name = NULL; else { size_t file_name_length; static char return_buffer[MTR_YYTEXT_SIZE]; file_name_length = end_of_file_name - start_of_file_name; /* Copy file name between quotes. */ strncpy(return_buffer, start_of_file_name, file_name_length); return_buffer[file_name_length] = '\0'; /* Buffer is static, so it's still viable after returning. */ start_of_file_name = return_buffer; } } return start_of_file_name;}#ifdef MKS_SCANNER/* Just a memmove() for those implementations that are not quite Standard C.*/static void *my_memmove(void *s1, const void *s2, size_t n){ char *sc1 = s1; const char *sc2 = s2; if (sc2 < sc1 && sc1 < sc2 + n) for (sc1 += n, sc2 += n; n-- > 0; ) *--sc1 = *--sc2; else while (n-- > 0) *sc1++ = *sc2++; return s1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -