输入部分,用类Input
class Input
{
public:
Input (FILE *stream, Keyword_Factory *keyword_factory);
~Input ();
void read_input ();
private:
/* Input stream. */
FILE * _stream;
/* Creates the keywords. */
Keyword_Factory * const _factory;
public:
/* Memory block containing the entire input. */
char * _input;
char * _input_end;
/* The C code from the declarations section. */
const char * _verbatim_declarations;
const char * _verbatim_declarations_end;
unsigned int _verbatim_declarations_lineno;
/* The C code from the end of the file. */
const char * _verbatim_code;
const char * _verbatim_code_end;
unsigned int _verbatim_code_lineno;
/* Declaration of struct type for a keyword and its attributes. */
const char * _struct_decl;
unsigned int _struct_decl_lineno;
/* Return type of the lookup function. */
const char * _return_type;
/* Shorthand for user-defined struct tag type. */
const char * _struct_tag;
/* List of all keywords. */
Keyword_List * _head;
/* Whether the keyword chars would have different values in a different
character set. */
bool _charset_dependent;
};
判断声明:
static bool
is_declaration (const char *line, const char *line_end, unsigned int lineno,
const char *decl)
{
/* Skip '%'. */
line++;
/* Skip DECL. */
for (const char *d = decl; *d; d++)
{
if (!(line < line_end))
return false;
if (!(*line == *d || (*d == '-' && *line == '_')))
return false;
line++;
}
if (line < line_end
&& ((*line >= 'A' && *line <= 'Z')
|| (*line >= 'a' && *line <= 'z')
|| *line == '-' || *line == '_'))
return false;
/* OK, found DECL. */
/* Skip whitespace. */
while (line < line_end && (*line == ' ' || *line == '\t'))
line++;
/* Expect end of line. */
if (line < line_end && *line != '\n')
{
fprintf (stderr, "%s:%u: junk after declaration\n",
pretty_input_file_name (), lineno);
exit (1);
}
return true;
}
读取声明的参数值 :
/* Tests if the given line contains a "%DECL=ARG" declaration.
If yes, it sets *ARGP to the argument, and returns true.
Otherwise, it returns false. */
static bool
is_declaration_with_arg (const char *line, const char *line_end,
unsigned int lineno,
const char *decl, char **argp)
{
/* Skip '%'. */
line++;
/* Skip DECL. */
for (const char *d = decl; *d; d++)
{
if (!(line < line_end))
return false;
if (!(*line == *d || (*d == '-' && *line == '_')))
return false;
line++;
}
if (line < line_end
&& ((*line >= 'A' && *line <= 'Z')
|| (*line >= 'a' && *line <= 'z')
|| *line == '-' || *line == '_'))
return false;
/* OK, found DECL. */
/* Skip '='. */
if (!(line < line_end && *line == '='))
{
fprintf (stderr, "%s:%u: missing argument in %%%s=ARG declaration.\n",
pretty_input_file_name (), lineno, decl);
exit (1);
}
line++;
/* The next word is the argument. */
char *arg = new char[line_end - line + 1];
char *p = arg;
while (line < line_end && !(*line == ' ' || *line == '\t' || *line == '\n'))
*p++ = *line++;
*p = '\0';
/* Skip whitespace. */
while (line < line_end && (*line == ' ' || *line == '\t'))
line++;
/* Expect end of line. */
if (line < line_end && *line != '\n')
{
fprintf (stderr, "%s:%u: junk after declaration\n",
pretty_input_file_name (), lineno);
exit (1);
}
*argp = arg;
return true;
}
声明为%define decl arg类型:
static bool
is_define_declaration (const char *line, const char *line_end,
unsigned int lineno,
const char *decl, char **argp)
{
/* Skip '%'. */
line++;
/* Skip "define". */
{
for (const char *d = "define"; *d; d++)
{
if (!(line < line_end))
return false;
if (!(*line == *d))
return false;
line++;
}
if (!(line < line_end && (*line == ' ' || *line == '\t')))
return false;
}
/* Skip whitespace. */
while (line < line_end && (*line == ' ' || *line == '\t'))
line++;
/* Skip DECL. */
for (const char *d = decl; *d; d++)
{
if (!(line < line_end))
return false;
if (!(*line == *d || (*d == '-' && *line == '_')))
return false;
line++;
}
if (line < line_end
&& ((*line >= 'A' && *line <= 'Z')
|| (*line >= 'a' && *line <= 'z')
|| *line == '-' || *line == '_'))
return false;
/* OK, found DECL. */
/* Skip whitespace. */
if (!(line < line_end && (*line == ' ' || *line == '\t')))
{
fprintf (stderr, "%s:%u:"
" missing argument in %%define %s ARG declaration.\n",
pretty_input_file_name (), lineno, decl);
exit (1);
}
do
line++;
while (line < line_end && (*line == ' ' || *line == '\t'));
/* The next word is the argument. */
char *arg = new char[line_end - line + 1];
char *p = arg;
while (line < line_end && !(*line == ' ' || *line == '\t' || *line == '\n'))
*p++ = *line++;
*p = '\0';
/* Skip whitespace. */
while (line < line_end && (*line == ' ' || *line == '\t'))
line++;
/* Expect end of line. */
if (line < line_end && *line != '\n')
{
fprintf (stderr, "%s:%u: junk after declaration\n",
pretty_input_file_name (), lineno);
exit (1);
}
*argp = arg;
return true;
}
Input::read_input中的将输入分为三部分的代码:声明,关键字,函数
/* Break up the input into the three sections. */
{
const char *separator[2] = { NULL, NULL };
unsigned int separator_lineno[2] = { 0, 0 };
int separators = 0;
{
unsigned int lineno = 1;
for (const char *p = input; p < input_end; )
{
if (p[0] == '%' && p[1] == '%')
{
separator[separators] = p;
separator_lineno[separators] = lineno;
if (++separators == 2)
break;
}
lineno++;
p = (const char *) memchr (p, '\n', input_end - p);
if (p != NULL)
p++;
else
p = input_end;
}
}
判断有无声明:
bool has_declarations;
if (separators == 1)
{
if (option[TYPE])
has_declarations = true;
else
{
has_declarations = false;
for (const char *p = input; p < separator[0]; )
{
if (p[0] == '%')
{
has_declarations = true;
break;
}
p = (const char *) memchr (p, '\n', separator[0] - p);
if (p != NULL)
p++;
else
p = separator[0];
}
}
}
else
has_declarations = (separators > 0);