📄 lexi.c
字号:
return (ident); } /* end of switch */ } /* end of if (found_it) */ if (*buf_ptr == '(' && parser_state_tos->tos <= 1 && parser_state_tos->ind_level == 0 && parser_state_tos->paren_depth == 0) { /* We have found something which might be the name in a function definition. */ register char *tp; int paren_count = 1; /* Skip to the matching ')'. */ for (tp = buf_ptr + 1; paren_count > 0 && tp < in_prog + in_prog_size; tp++) { if (*tp == '(') paren_count++; if (*tp == ')') paren_count--; /* Can't occur in parameter list; this way we don't search the whole file in the case of unbalanced parens. */ if (*tp == ';') goto not_proc; } if (paren_count == 0) { while (isspace (*tp)) tp++; /* If the next char is ';' or ',' or '(' we have a function declaration, not a definition. I've added '=' to this list to keep from breaking a non-valid C macro from libc. -jla */ if (*tp != ';' && *tp != ',' && *tp != '(' && *tp != '=') { parser_state_tos->procname = token; parser_state_tos->procname_end = token_end; parser_state_tos->in_parameter_declaration = 1; } } not_proc:; } /* The following hack attempts to guess whether or not the current token is in fact a declaration keyword -- one that has been typedef'd */ if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha (*buf_ptr) || *buf_ptr == '_') && !parser_state_tos->p_l_follow && !parser_state_tos->block_init && (parser_state_tos->last_token == rparen || parser_state_tos->last_token == semicolon || parser_state_tos->last_token == decl || parser_state_tos->last_token == lbrace || parser_state_tos->last_token == rbrace)) { parser_state_tos->its_a_keyword = true; parser_state_tos->last_u_d = true; last_code = decl; return decl; } if (last_code == decl) /* if this is a declared variable, then following sign is unary */ parser_state_tos->last_u_d = true; /* will make "int a -1" work */ last_code = ident; return (ident); /* the ident is not in the list */ } /* end of procesing for alpanum character */ /* Scan a non-alphanumeric token */ /* If it is not a one character token, token_end will get changed later. */ token_end = buf_ptr + 1; if (++buf_ptr >= buf_end) fill_buffer (); switch (*token) { case '\0': code = code_eof; break; case EOL: unary_delim = parser_state_tos->last_u_d; parser_state_tos->last_nl = true; code = newline; break; case '\'': /* start of quoted character */ case '"': /* start of string */ qchar = *token; /* Find out how big the literal is so we can set token_end. */ /* Invariant: before loop test buf_ptr points to the next */ /* character that we have not yet checked. */ while (*buf_ptr != qchar && *buf_ptr != 0 && *buf_ptr != EOL) { if (*buf_ptr == '\\') { buf_ptr++; if (buf_ptr >= buf_end) fill_buffer (); if (*buf_ptr == EOL) ++line_no; if (*buf_ptr == 0) break; } buf_ptr++; if (buf_ptr >= buf_end) fill_buffer (); } if (*buf_ptr == EOL || *buf_ptr == 0) { diag (1, (qchar == '\'' ? "Unterminated character constant" : "Unterminated string constant"), 0, 0); } else { /* Advance over end quote char. */ buf_ptr++; if (buf_ptr >= buf_end) fill_buffer (); } code = ident; break; case ('('): case ('['): unary_delim = true; code = lparen; break; case (')'): case (']'): code = rparen; break; case '#': unary_delim = parser_state_tos->last_u_d; code = preesc; break; case '?': unary_delim = true; code = question; break; case (':'): code = colon; unary_delim = true; if (squest && *e_com != ' ') { if (e_code == s_code) parser_state_tos->want_blank = false; else parser_state_tos->want_blank = true; } break; case (';'): unary_delim = true; code = semicolon; break; case ('{'): unary_delim = true; /* This check is made in the code for '='. No one who writes initializers without '=' these days deserves to have indent work on their code (besides which, uncommenting this would screw up anything which assumes that parser_state_tos->block_init really means you are in an initializer. */ /* if (parser_state_tos->in_or_st) parser_state_tos->block_init = 1; */ /* The following neat hack causes the braces in structure initializations to be treated as parentheses, thus causing initializations to line up correctly, e.g. struct foo bar = {{a, b, c}, {1, 2}}; If lparen is returned, token can be used to distinguish between '{' and '(' where necessary. */ code = parser_state_tos->block_init ? lparen : lbrace; break; case ('}'): unary_delim = true; /* The following neat hack is explained under '{' above. */ code = parser_state_tos->block_init ? rparen : rbrace; break; case 014: /* a form feed */ unary_delim = parser_state_tos->last_u_d; parser_state_tos->last_nl = true; /* remember this so we can set 'parser_state_tos->col_1' right */ code = form_feed; break; case (','): unary_delim = true; code = comma; break; case '.': unary_delim = false; code = period; break; case '-': case '+': /* check for -, +, --, ++ */ code = (parser_state_tos->last_u_d ? unary_op : binary_op); unary_delim = true; if (*buf_ptr == token[0]) { /* check for doubled character */ buf_ptr++; /* buffer overflow will be checked at end of loop */ if (last_code == ident || last_code == rparen) { code = (parser_state_tos->last_u_d ? unary_op : postop); /* check for following ++ or -- */ unary_delim = false; } } else if (*buf_ptr == '=') /* check for operator += */ buf_ptr++; else if (*buf_ptr == '>') { /* check for operator -> */ buf_ptr++; if (!pointer_as_binop) { unary_delim = false; code = unary_op; parser_state_tos->want_blank = false; } } break; /* buffer overflow will be checked at end of switch */ case '=': if (parser_state_tos->in_or_st) parser_state_tos->block_init = 1; if (*buf_ptr == '=') /* == */ buf_ptr++; else if (*buf_ptr == '-' || *buf_ptr == '+' || *buf_ptr == '*' || *buf_ptr == '&') { /* Something like x=-1, which can mean x -= 1 ("old style" in K&R1) or x = -1 (ANSI). Note that this is only an ambiguity if the character can also be a unary operator. If not, just produce output code that produces a syntax error (the theory being that people want to detect and eliminate old style assignments but they don't want indent to silently change the meaning of their code). */ diag (0, "old style assignment ambiguity in \"=%c\". Assuming \"= %c\"\n", (int) *buf_ptr, (int) *buf_ptr); } code = binary_op; unary_delim = true; break; /* can drop thru!!! */ case '>': case '<': case '!': /* ops like <, <<, <=, !=, <<=, etc */ /* This will of course scan sequences like "<=>", "!=>", "<<>", etc. as one token, but I don't think that will cause any harm. */ while (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') { if (++buf_ptr >= buf_end) fill_buffer (); if (*buf_ptr == '=') { if (++buf_ptr >= buf_end) fill_buffer (); } } code = (parser_state_tos->last_u_d ? unary_op : binary_op); unary_delim = true; break; default: if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { /* A C or C++ comment */ if (*buf_ptr == '*') code = comment; else code = cplus_comment; if (++buf_ptr >= buf_end) fill_buffer (); unary_delim = parser_state_tos->last_u_d; break; } while (*(buf_ptr - 1) == *buf_ptr || *buf_ptr == '=') { /* handle ||, &&, etc, and also things as in int *****i */ if (++buf_ptr >= buf_end) fill_buffer (); } code = (parser_state_tos->last_u_d ? unary_op : binary_op); unary_delim = true; } /* end of switch */ if (code != newline) { l_struct = false; last_code = code; } token_end = buf_ptr; if (buf_ptr >= buf_end) /* check for input buffer empty */ fill_buffer (); parser_state_tos->last_u_d = unary_delim; return (code);}/* Add the given keyword to the keyword table, using val as the keyword type */addkey (key, val) char *key; enum rwcodes val;{ register struct templ *p; /* Check to see whether key is a reserved word or not. */ if (is_reserved (key, strlen (key)) != 0) return; if (user_specials == 0) { user_specials = (struct templ *) xmalloc (5 * sizeof (struct templ)); user_specials_max = 5; user_specials_idx = 0; } else if (user_specials_idx == user_specials_max) { user_specials_max += 5; user_specials = (struct templ *) xrealloc ((char *) user_specials, user_specials_max * sizeof (struct templ)); } p = &user_specials[user_specials_idx++]; p->rwd = key; p->rwcode = val; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -