📄 lex_yy.c
字号:
if (next_char_p >= input_line + sizeof input_line) { /* Terminate input buffer with newline and string terminator in case they are missing. */ input_line[sizeof input_line - 2] = '\n'; input_line[sizeof input_line - 1] = '\0'; int_fatal(E_OVERRAN_INPUT_BUFFER); } next_char = *next_char_p++; }/* If the C compiler uses a different value for the internal representation of newline than what the lexer uses to build its tables, substitute the lexer's newline for the compiler's newline. This should be a rare thing, however, such as when the lexer included in the distribution, which was generated for a newline of 10, is used on a system such as the Mac where newlines may be represented internally by 13. Also see the explanation near the #define of MTR_NEWLINE.*/#if MTR_NEWLINE != '\n' if (next_char == '\n') next_char = MTR_NEWLINE;#endif last_char = next_char; return next_char;}#endif /* #if defined(ATT_SCANNER) || defined(MKS_SCANNER) *//* Read next line from input file, returning number of characters read. */static int my_yyinput(char *buf, int max_size){ if (fgets(buf, max_size, yyin) == NULL) buf[0] = '\0'; else /* This is where the input line is printed if display_print is TRUE. */ if (display_input) fputs(buf, out_fp); return strlen(buf);}#endif /* #if READ_LINE *//* Called by yacc at the end of a source file. If there are more files to process, open them and continue, else stop.*/int yywrap(){ 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -