📄 scan-gram.l
字号:
{ char *w = memchr (buf, '\r', bytes_read); if (w) { char const *r = ++w; char const *lim = buf + bytes_read; for (;;) { /* Found an '\r'. Treat it like '\n', but ignore any '\n' that immediately follows. */ w[-1] = '\n'; if (r == lim) { int ch = getc (fp); if (ch != '\n' && ungetc (ch, fp) != ch) break; } else if (*r == '\n') r++; /* Copy until the next '\r'. */ do { if (r == lim) return w - buf; } while ((*w++ = *r++) != '\r'); } return w - buf; } } return bytes_read;}/*------------------------------------------------------------------.| TEXT is pointing to a wannabee semantic value (i.e., a `$'). || || Possible inputs: $[<TYPENAME>]($|integer) || || Output to OBSTACK_FOR_STRING a reference to this semantic value. |`------------------------------------------------------------------*/static inline boolhandle_action_dollar (char *text, location loc){ const char *type_name = NULL; char *cp = text + 1; if (! current_rule) return false; /* Get the type name if explicit. */ if (*cp == '<') { type_name = ++cp; while (*cp != '>') ++cp; *cp = '\0'; ++cp; } if (*cp == '$') { if (!type_name) type_name = symbol_list_n_type_name_get (current_rule, loc, 0); if (!type_name && typed) complain_at (loc, _("$$ of `%s' has no declared type"), current_rule->sym->tag); if (!type_name) type_name = ""; obstack_fgrow1 (&obstack_for_string, "]b4_lhs_value([%s])[", type_name); } else { long int num; set_errno (0); num = strtol (cp, 0, 10); if (INT_MIN <= num && num <= rule_length && ! get_errno ()) { int n = num; if (1-n > max_left_semantic_context) max_left_semantic_context = 1-n; if (!type_name && n > 0) type_name = symbol_list_n_type_name_get (current_rule, loc, n); if (!type_name && typed) complain_at (loc, _("$%d of `%s' has no declared type"), n, current_rule->sym->tag); if (!type_name) type_name = ""; obstack_fgrow3 (&obstack_for_string, "]b4_rhs_value(%d, %d, [%s])[", rule_length, n, type_name); } else complain_at (loc, _("integer out of range: %s"), quote (text)); } return true;}/*----------------------------------------------------------------.| Map `$?' onto the proper M4 symbol, depending on its TOKEN_TYPE || (are we in an action?). |`----------------------------------------------------------------*/static voidhandle_dollar (int token_type, char *text, location loc){ switch (token_type) { case BRACED_CODE: if (handle_action_dollar (text, loc)) return; break; case PERCENT_DESTRUCTOR: case PERCENT_INITIAL_ACTION: case PERCENT_PRINTER: if (text[1] == '$') { obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar["); return; } break; default: break; } complain_at (loc, _("invalid value: %s"), quote (text));}/*------------------------------------------------------.| TEXT is a location token (i.e., a `@...'). Output to || OBSTACK_FOR_STRING a reference to this location. |`------------------------------------------------------*/static inline boolhandle_action_at (char *text, location loc){ char *cp = text + 1; locations_flag = true; if (! current_rule) return false; if (*cp == '$') obstack_sgrow (&obstack_for_string, "]b4_lhs_location["); else { long int num; set_errno (0); num = strtol (cp, 0, 10); if (INT_MIN <= num && num <= rule_length && ! get_errno ()) { int n = num; obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[", rule_length, n); } else complain_at (loc, _("integer out of range: %s"), quote (text)); } return true;}/*----------------------------------------------------------------.| Map `@?' onto the proper M4 symbol, depending on its TOKEN_TYPE || (are we in an action?). |`----------------------------------------------------------------*/static voidhandle_at (int token_type, char *text, location loc){ switch (token_type) { case BRACED_CODE: handle_action_at (text, loc); return; case PERCENT_INITIAL_ACTION: case PERCENT_DESTRUCTOR: case PERCENT_PRINTER: if (text[1] == '$') { obstack_sgrow (&obstack_for_string, "]b4_at_dollar["); return; } break; default: break; } complain_at (loc, _("invalid value: %s"), quote (text));}/*------------------------------------------------------.| Scan NUMBER for a base-BASE integer at location LOC. |`------------------------------------------------------*/static unsigned long intscan_integer (char const *number, int base, location loc){ unsigned long int num; set_errno (0); num = strtoul (number, 0, base); if (INT_MAX < num || get_errno ()) { complain_at (loc, _("integer out of range: %s"), quote (number)); num = INT_MAX; } return num;}/*------------------------------------------------------------------.| Convert universal character name UCN to a single-byte character, || and return that character. Return -1 if UCN does not correspond || to a single-byte character. |`------------------------------------------------------------------*/static intconvert_ucn_to_byte (char const *ucn){ unsigned long int code = strtoul (ucn + 2, 0, 16); /* FIXME: Currently we assume Unicode-compatible unibyte characters on ASCII hosts (i.e., Latin-1 on hosts with 8-bit bytes). On non-ASCII hosts we support only the portable C character set. These limitations should be removed once we add support for multibyte characters. */ if (UCHAR_MAX < code) return -1;#if ! ('$' == 0x24 && '@' == 0x40 && '`' == 0x60 && '~' == 0x7e) { /* A non-ASCII host. Use CODE to index into a table of the C basic execution character set, which is guaranteed to exist on all Standard C platforms. This table also includes '$', '@', and '`', which are not in the basic execution character set but which are unibyte characters on all the platforms that we know about. */ static signed char const table[] = { '\0', -1, -1, -1, -1, -1, -1, '\a', '\b', '\t', '\n', '\v', '\f', '\r', -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~' }; code = code < sizeof table ? table[code] : -1; }#endif return code;}/*----------------------------------------------------------------.| Handle `#line INT "FILE"'. ARGS has already skipped `#line '. |`----------------------------------------------------------------*/static voidhandle_syncline (char *args){ int lineno = strtol (args, &args, 10); const char *file = NULL; file = strchr (args, '"') + 1; *strchr (file, '"') = 0; scanner_cursor.file = current_file = uniqstr_new (file); scanner_cursor.line = lineno; scanner_cursor.column = 1;}/*----------------------------------------------------------------.| For a token or comment starting at START, report message MSGID, || which should say that an end marker was found before || the expected TOKEN_END. |`----------------------------------------------------------------*/static voidunexpected_end (boundary start, char const *msgid, char const *token_end){ location loc; loc.start = start; loc.end = scanner_cursor; complain_at (loc, _(msgid), token_end);}/*------------------------------------------------------------------------.| Report an unexpected EOF in a token or comment starting at START. || An end of file was encountered and the expected TOKEN_END was missing. |`------------------------------------------------------------------------*/static voidunexpected_eof (boundary start, char const *token_end){ unexpected_end (start, N_("missing `%s' at end of file"), token_end);}/*----------------------------------------.| Likewise, but for unexpected newlines. |`----------------------------------------*/static voidunexpected_newline (boundary start, char const *token_end){ unexpected_end (start, N_("missing `%s' at end of line"), token_end);}/*-------------------------.| Initialize the scanner. |`-------------------------*/voidscanner_initialize (void){ obstack_init (&obstack_for_string);}/*-----------------------------------------------.| Free all the memory allocated to the scanner. |`-----------------------------------------------*/voidscanner_free (void){ obstack_free (&obstack_for_string, 0); /* Reclaim Flex's buffers. */ yy_delete_buffer (YY_CURRENT_BUFFER);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -