+typedef struct cpp_token cpp_token;
+typedef struct cpp_string cpp_string;
+typedef struct cpp_hashnode cpp_hashnode;
+typedef struct cpp_pool cpp_pool;
+typedef struct cpp_macro cpp_macro;
+typedef struct cpp_lexer_pos cpp_lexer_pos;
+typedef struct cpp_lookahead cpp_lookahead;
+
+struct directive; /* These are deliberately incomplete. */
+struct answer;
+struct cpp_macro;
+struct macro_args;
+struct cpp_chunk;
+struct file_name_map_list;
+struct htab;
+
+/* The first two groups, apart from '=', can appear in preprocessor
+ expressions. This allows a lookup table to be implemented in
+ _cpp_parse_expr.
+
+ The first group, to CPP_LAST_EQ, can be immediately followed by an
+ '='. The lexer needs operators ending in '=', like ">>=", to be in
+ the same order as their counterparts without the '=', like ">>". */
+
+/* Positions in the table. */
+#define CPP_LAST_EQ CPP_MAX
+#define CPP_FIRST_DIGRAPH CPP_HASH
+#define CPP_LAST_PUNCTUATOR CPP_DOT_STAR
+
+#define TTYPE_TABLE \
+ OP(CPP_EQ = 0, "=") \
+ OP(CPP_NOT, "!") \
+ OP(CPP_GREATER, ">") /* compare */ \
+ OP(CPP_LESS, "<") \
+ OP(CPP_PLUS, "+") /* math */ \
+ OP(CPP_MINUS, "-") \
+ OP(CPP_MULT, "*") \
+ OP(CPP_DIV, "/") \
+ OP(CPP_MOD, "%") \
+ OP(CPP_AND, "&") /* bit ops */ \
+ OP(CPP_OR, "|") \
+ OP(CPP_XOR, "^") \
+ OP(CPP_RSHIFT, ">>") \
+ OP(CPP_LSHIFT, "<<") \
+ OP(CPP_MIN, "<?") /* extension */ \
+ OP(CPP_MAX, ">?") \
+\
+ OP(CPP_COMPL, "~") \
+ OP(CPP_AND_AND, "&&") /* logical */ \
+ OP(CPP_OR_OR, "||") \
+ OP(CPP_QUERY, "?") \
+ OP(CPP_COLON, ":") \
+ OP(CPP_COMMA, ",") /* grouping */ \
+ OP(CPP_OPEN_PAREN, "(") \
+ OP(CPP_CLOSE_PAREN, ")") \
+ OP(CPP_EQ_EQ, "==") /* compare */ \
+ OP(CPP_NOT_EQ, "!=") \
+ OP(CPP_GREATER_EQ, ">=") \
+ OP(CPP_LESS_EQ, "<=") \
+\
+ OP(CPP_PLUS_EQ, "+=") /* math */ \
+ OP(CPP_MINUS_EQ, "-=") \
+ OP(CPP_MULT_EQ, "*=") \
+ OP(CPP_DIV_EQ, "/=") \
+ OP(CPP_MOD_EQ, "%=") \
+ OP(CPP_AND_EQ, "&=") /* bit ops */ \
+ OP(CPP_OR_EQ, "|=") \
+ OP(CPP_XOR_EQ, "^=") \
+ OP(CPP_RSHIFT_EQ, ">>=") \
+ OP(CPP_LSHIFT_EQ, "<<=") \
+ OP(CPP_MIN_EQ, "<?=") /* extension */ \
+ OP(CPP_MAX_EQ, ">?=") \
+ /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \
+ OP(CPP_HASH, "#") /* digraphs */ \
+ OP(CPP_PASTE, "##") \
+ OP(CPP_OPEN_SQUARE, "[") \
+ OP(CPP_CLOSE_SQUARE, "]") \
+ OP(CPP_OPEN_BRACE, "{") \
+ OP(CPP_CLOSE_BRACE, "}") \
+ /* The remainder of the punctuation. Order is not significant. */ \
+ OP(CPP_SEMICOLON, ";") /* structure */ \
+ OP(CPP_ELLIPSIS, "...") \
+ OP(CPP_PLUS_PLUS, "++") /* increment */ \
+ OP(CPP_MINUS_MINUS, "--") \
+ OP(CPP_DEREF, "->") /* accessors */ \
+ OP(CPP_DOT, ".") \
+ OP(CPP_SCOPE, "::") \
+ OP(CPP_DEREF_STAR, "->*") \
+ OP(CPP_DOT_STAR, ".*") \
+\
+ TK(CPP_NAME, SPELL_IDENT) /* word */ \
+ TK(CPP_INT, SPELL_STRING) /* 23 */ \
+ TK(CPP_FLOAT, SPELL_STRING) /* 3.14159 */ \
+ TK(CPP_NUMBER, SPELL_STRING) /* 34_be+ta */ \
+\
+ TK(CPP_CHAR, SPELL_STRING) /* 'char' */ \
+ TK(CPP_WCHAR, SPELL_STRING) /* L'char' */ \
+ TK(CPP_OTHER, SPELL_CHAR) /* stray punctuation */ \
+\
+ TK(CPP_STRING, SPELL_STRING) /* "string" */ \
+ TK(CPP_WSTRING, SPELL_STRING) /* L"string" */ \
+ TK(CPP_OSTRING, SPELL_STRING) /* @"string" - Objective C */ \
+ TK(CPP_HEADER_NAME, SPELL_STRING) /* <stdio.h> in #include */ \
+\
+ TK(CPP_COMMENT, SPELL_STRING) /* Only if output comments. */ \
+ TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \
+ OP(CPP_EOF, "EOL") /* End of line or file. */
+
+#define OP(e, s) e,
+#define TK(e, s) e,
+enum cpp_ttype
+{
+ TTYPE_TABLE
+ N_TTYPES