~groovestomp/c-parser

52ac167e40ae03a785a2c1263b8ba4df5d07fb6d — Aaron Oman 2 years ago ce134c2
Many changes!

- Remove dependency on stdio.h in lexer.c
- Update 'Updated' metadata for each file.
- Set 'Created' metadata for each file.
- Conditionally define booleans in gs.h
- Add gs_MemSet to gs.h
- Update lexer to handle errors in a C-like way.
- Update Lex() function to return a tokenized stream.
- Update main.c to handle Lex() returning a stream, print parse tree without cli option.
- Change ParseTree to use enums instead of strings for type info.
- Update parser to use new ParseTree interface.
- Simplify Parse() function implementation by removing the loop.
8 files changed, 593 insertions(+), 441 deletions(-)

M .gitignore
M TODO
M src/gs.h
M src/lexer.c
M src/main.c
M src/parse_tree.c
M src/parser.c
M src/test.c
M .gitignore => .gitignore +4 -1
@@ 6,4 6,7 @@ env/
!env/.emacs
*~
cparser
test
\ No newline at end of file
test
core
#*
.#*

M TODO => TODO +1 -2
@@ 5,5 5,4 @@
- Changelog.
- Commit hook for updating changelog as part of release.
- Processing for doing a release.
- Remove dependency on stdio.h in lexer.c and remove printfs; instead returning errors appropriately.
  See how parse_tree.c handles errors.
\ No newline at end of file
- Generate an AST instead of just a parse tree.
\ No newline at end of file

M src/gs.h => src/gs.h +20 -43
@@ 1,7 1,7 @@
/******************************************************************************
 * File: gs.h
 * Created: 2016-07-14
 * Updated: 2016-11-03
 * Updated: 2016-11-04
 * Package: gslibc
 * Creator: Aaron Oman (GrooveStomp)
 * Copyright 2016 - 2020, Aaron Oman and the gslibc contributors


@@ 14,31 14,12 @@
#ifndef GS_VERSION
#define GS_VERSION 0.2.0-dev

#define gs_ArraySize(Array) (sizeof((Array)) / sizeof((Array)[0]))

/******************************************************************************
 * Usage:
 *
 * i32 Numbers[] = { 1, 2, 3, 4, 5 };
 * gs_ArrayForEach(i32 *Number, Numbers) {
 *         printf("Number[%i]: %i\n", Index, *Number);
 * }
 *
 * NOTE:
 * The variable `Index' is automatically generated for you.
 * `Item' must be a pointer to the type of variable used in the Array.
 *
 * Implementation taken from: http://stackoverflow.com/a/400970
 ******************************************************************************/
#define gs_ArrayForEach(Item, Array) \
        for (i32 Keep##__LINE__ = 1, \
                Count##__LINE__ = 0, \
                Index = 0, \
                Size##__LINE__ = sizeof((Array)) / sizeof(*(Array)); \
            Keep##__LINE__ && Count##__LINE__ != Size##__LINE__; \
            Keep##__LINE__ = !Keep##__LINE__, Count##__LINE__++) \
                for (Item = (Array) + Count##__LINE__; Keep##__LINE__; Keep##__LINE__ = !Keep##__LINE__, Index++)
#define GS_1024_INVERSE 1.0/1024
#define gs_BytesToKilobytes(X) (X) * GS_1024_INVERSE
#define gs_BytesToMegabytes(X) gs_BytesToKilobytes((X)) * GS_1024_INVERSE
#define gs_BytesToGigabytes(X) gs_BytesToMegabytes((X)) * GS_1024_INVERSE

#define gs_ArraySize(Array) (sizeof((Array)) / sizeof((Array)[0]))
#define gs_Max(A, B) ((A) < (B) ? (B) : (A))
#define gs_Min(A, B) ((A) < (B) ? (A) : (B))



@@ 61,28 42,22 @@
/*                 fprintf(stdout, __VA_ARGS__); \ */
/*         } */

#define GS_1024_INVERSE 1.0/1024
#define gs_BytesToKilobytes(X) (X) * GS_1024_INVERSE
#define gs_BytesToMegabytes(X) gs_BytesToKilobytes((X)) * GS_1024_INVERSE
#define gs_BytesToGigabytes(X) gs_BytesToMegabytes((X)) * GS_1024_INVERSE

/******************************************************************************
 * Primitive Type Definitions
 * TODO: Conditionally do typedefs?
 ******************************************************************************/

#define GS_NULL_CHAR '\0'
#define GS_NULL_PTR NULL

#ifndef NULL
#define NULL 0
    #define NULL 0
#endif

#define GS_NULL_PTR NULL

typedef int bool;
#ifndef false
#define false 0
#define true !false
#ifndef false // Assume this dictates whether 'bool' is defined.
    typedef int bool;
    #define false 0
    #define true !false
#endif

typedef char i8;


@@ 125,6 100,12 @@ typedef struct gs_Allocator {
        void *(*calloc)(u64, u64);
} gs_Allocator;

void gs_MemSet(char *mem, char byte, u32 size) {
        for (int i = 0; i < size; i++) {
                mem[i] = byte;
        }
}

/******************************************************************************
 * Character Definitions
 *-----------------------------------------------------------------------------


@@ 478,14 459,10 @@ gs_HashMap *gs_HashMapInit(void *memory, u32 max_key_length, u32 num_entries) {
        i32 keys_mem_length = max_key_length * num_entries;

        self->keys = key_value_memory;
        for (i32 i = 0; i < keys_mem_length; i++) {
                self->keys[i] = 0;
        }
        gs_MemSet(self->keys, 0, keys_mem_length);

        self->values = (void **)(self->keys + keys_mem_length);
        for (i32 i = 0; i < num_entries; i++) {
                self->values[i] = 0;
        }
        gs_MemSet(self->keys, 0, keys_mem_length);

        return self;
}

M src/lexer.c => src/lexer.c +57 -25
@@ 1,10 1,10 @@
/******************************************************************************
 * File: lexer.c
 * Created:
 * Updated: 2016-11-04
 * Created: 2016-07-06
 * Updated: 2020-11-16
 * Package: C-Parser
 * Creator: Aaron Oman (GrooveStomp)
 * Copyright - 2020, Aaron Oman and the C-Parser contributors
 * Copyright 2016 - 2020, Aaron Oman and the C-Parser contributors
 * SPDX-License-Identifier: LGPL-3.0-only
 ******************************************************************************/
#ifndef LEXER_C


@@ 12,7 12,27 @@

#include "gs.h"

#include <stdio.h> /* TODO: Remove printfs */
typedef enum LexerErrorEnum {
        LexerErrorNoSpace,
        LexerReallocFail,
        LexerUnknownToken,
        LexerErrorNone,
} LexerErrorEnum;

const char *__lexer_error_strings[] = {
        "Couldn't allocate space for token stream",
        "Couldn't reallocate space for token stream after lexing completed",
        "Unknown token",
        "No error",
};

LexerErrorEnum __lexer_last_error = LexerErrorNone;

const char *LexerErrorString() {
        const char *result = __lexer_error_strings[__lexer_last_error];
        __lexer_last_error = LexerErrorNone;
        return result;
}

typedef enum TokenType {
        Token_Unknown,


@@ 148,7 168,7 @@ char *TokenName(TokenType type) {

typedef struct Token {
        char *text;
        size_t text_length;
        u32 text_length;
        TokenType type;
        u32 line;
        u32 column;


@@ 576,37 596,49 @@ Token GetToken(Tokenizer *tokenizer) {
        return token;
}

void Lex(gs_Buffer *stream) {
bool Lex(gs_Allocator allocator, gs_Buffer *input_stream, Token **out_stream, u32 *out_num_tokens) {
        Tokenizer tokenizer;
        TokenizerInit(&tokenizer, stream->start);
        TokenizerInit(&tokenizer, input_stream->start);

        // Overestimate allocation.
        // This assumes one token per char; which is way too much.
        // We'll resize later.
        Token *token_stream = *out_stream;
        token_stream = (Token *)allocator.malloc(sizeof(*token_stream) * input_stream->length);
        if (token_stream == GS_NULL_PTR) {
                __lexer_last_error = LexerErrorNoSpace;
                out_num_tokens = 0;
                return false;
        }

        bool parsing = true;
        while (parsing) {
        u32 num_tokens = 0;

        bool lexing = true;
        while (lexing) {
                Token token = GetToken(&tokenizer);
                token_stream[num_tokens++] = token;
                switch (token.type) {
                        case Token_EndOfStream: {
                                parsing = false;
                                lexing = false;
                        } break;

                        case Token_Unknown: {
                                printf("[%u,%u] Token Name: %20s, Token Text: %.*s (%.*s)\n",
                                       token.line + 1,
                                       token.column,
                                       TokenName(token.type),
                                       (u32)(token.text_length), token.text,
                                       (u32)(token.text_length + 4), token.text - 2);
                        } break;

                        default: {
                                printf("[%u,%u] Token Name: %20s, Token Text: %.*s\n",
                                       token.line + 1,
                                       token.column,
                                       TokenName(token.type),
                                       (u32)(token.text_length),
                                       token.text);
                                __lexer_last_error = LexerUnknownToken;
                                lexing = false;
                        } break;
                }
        }

        // Resize the stream now.
        *out_stream = (Token *)allocator.realloc(token_stream, sizeof(*token_stream) * num_tokens);
        if (*out_stream == GS_NULL_PTR) {
                __lexer_last_error = LexerReallocFail;
                out_num_tokens = 0;
                return false;
        }

        *out_num_tokens = num_tokens;
        return true;
}

#endif /* LEXER_C */

M src/main.c => src/main.c +26 -9
@@ 1,10 1,10 @@
/******************************************************************************
 * File: main.c
 * Created:
 * Updated: 2016-11-04
 * Created: 2016-05-18
 * Updated: 2016-11-16
 * Package: C-Parser
 * Creator: Aaron Oman (GrooveStomp)
 * Copyright - 2020, Aaron Oman and the C-Parser contributors
 * Copyright 2016 - 2020, Aaron Oman and the C-Parser contributors
 * SPDX-License-Identifier: LGPL-3.0-only
 ******************************************************************************/
#include "gs.h"


@@ 22,9 22,6 @@ void Usage(const char *name) {
        puts("  operation: One of: [parse, lex].");
        puts("  file: Must be a file in this directory.");
        puts("  Specify '-h' or '--help' for this help text.");
        puts("");
        puts("Options:");
        puts("  --show-parse-tree: Valid with `parse' subcommand.");
        exit(EXIT_SUCCESS);
}



@@ 73,10 70,30 @@ int main(int argc, char **argv) {
        gs_Allocator allocator = { .malloc = malloc, .free = free, .realloc = realloc, .calloc = calloc };

        if (gs_StringIsEqual(command, "parse", 5)) {
                bool show_parse_tree = (argc == 4 && gs_StringIsEqual(argv[3], "--show-parse-tree", 17));
                Parse(allocator, &buffer, show_parse_tree);
                ParseTreeNode *parse_tree;
                Tokenizer tokenizer;
                if (Parse(allocator, &buffer, &parse_tree, &tokenizer)) {
                        ParseTreePrint(parse_tree, 0, 2, printf);
                } else {
                        printf("Input did not parse @ [%d,%d]\n", tokenizer.line, tokenizer.column);
                }
        } else {
                Lex(&buffer);
                Token *token_stream;
                u32 num_tokens;
                if (Lex(allocator, &buffer, &token_stream, &num_tokens)) {
                        for (int i = 0; i < num_tokens; i++) {
                                Token token = token_stream[i];

                                printf("[%u,%u] Token Name: %20s, Token Text: %.*s\n",
                                       token.line + 1,
                                       token.column,
                                       TokenName(token.type),
                                       (u32)(token.text_length),
                                       token.text);
                        }
                } else {
                        fprintf(stderr, LexerErrorString());
                }
        }

        return EXIT_SUCCESS;

M src/parse_tree.c => src/parse_tree.c +232 -63
@@ 1,10 1,10 @@
/******************************************************************************
 * File: parse_tree.c
 * Created:
 * Updated: 2016-11-04
 * Created: 2017-01-12
 * Updated: 2020-11-16
 * Package: C-Parser
 * Creator: Aaron Oman (GrooveStomp)
 * Copyright - 2020, Aaron Oman and the C-Parser contributors
 * Copyright 2017 - 2020, Aaron Oman and the C-Parser contributors
 * SPDX-License-Identifier: LGPL-3.0-only
 ******************************************************************************/
#ifndef PARSE_TREE


@@ 15,13 15,216 @@

#define DEFAULT_ALLOC_COUNT 2

typedef enum ParseTreeNodeType {
        ParseTreeNode_AbstractDeclarator,
        ParseTreeNode_AdditiveExpression,
        ParseTreeNode_AndExpression,
        ParseTreeNode_ArgumentExpressionList,
        ParseTreeNode_AssignmentExpression,
        ParseTreeNode_AssignmentOperator,
        ParseTreeNode_CastExpression,
        ParseTreeNode_CompoundStatement,
        ParseTreeNode_ConditionalExpression,
        ParseTreeNode_Constant,
        ParseTreeNode_ConstantExpression,
        ParseTreeNode_Declaration,
        ParseTreeNode_DeclarationList,
        ParseTreeNode_DeclarationSpecifiers,
        ParseTreeNode_Declarator,
        ParseTreeNode_DirectAbstractDeclarator,
        ParseTreeNode_DirectDeclarator,
        ParseTreeNode_EnumSpecifier,
        ParseTreeNode_Enumerator,
        ParseTreeNode_EnumeratorList,
        ParseTreeNode_EqualityExpression,
        ParseTreeNode_ExclusiveOrExpression,
        ParseTreeNode_Expression,
        ParseTreeNode_ExpressionStatement,
        ParseTreeNode_ExternalDeclaration,
        ParseTreeNode_FunctionDefinition,
        ParseTreeNode_Identifier,
        ParseTreeNode_IdentifierList,
        ParseTreeNode_InclusiveOrExpression,
        ParseTreeNode_InitDeclarationList,
        ParseTreeNode_InitDeclarator,
        ParseTreeNode_InitDeclaratorList,
        ParseTreeNode_Initializer,
        ParseTreeNode_InitializerList,
        ParseTreeNode_IterationStatement,
        ParseTreeNode_JumpStatement,
        ParseTreeNode_Keyword,
        ParseTreeNode_LabeledStatement,
        ParseTreeNode_LogicalAndExpression,
        ParseTreeNode_LogicalOrExpression,
        ParseTreeNode_MultiplicativeExpression,
        ParseTreeNode_ParameterDeclaration,
        ParseTreeNode_ParameterList,
        ParseTreeNode_ParameterTypeList,
        ParseTreeNode_Pointer,
        ParseTreeNode_PostfixExpression,
        ParseTreeNode_PrimaryExpression,
        ParseTreeNode_RelationalExpression,
        ParseTreeNode_SelectionStatement,
        ParseTreeNode_ShiftExpression,
        ParseTreeNode_SpecifierQualifierList,
        ParseTreeNode_Statement,
        ParseTreeNode_StatementList,
        ParseTreeNode_StorageClassSpecifier,
        ParseTreeNode_String,
        ParseTreeNode_StructDeclaration,
        ParseTreeNode_StructDeclarationList,
        ParseTreeNode_StructDeclarator,
        ParseTreeNode_StructDeclaratorList,
        ParseTreeNode_StructOrUnion,
        ParseTreeNode_StructOrUnionSpecifier,
        ParseTreeNode_Symbol,
        ParseTreeNode_TranslationUnit,
        ParseTreeNode_TypeName,
        ParseTreeNode_TypeQualifier,
        ParseTreeNode_TypeQualifierList,
        ParseTreeNode_TypeSpecifier,
        ParseTreeNode_TypedefName,
        ParseTreeNode_UnaryExpression,
        ParseTreeNode_UnaryOperator,

        ParseTreeNode_AdditiveExpressionI,
        ParseTreeNode_AndExpressionI,
        ParseTreeNode_ArgumentExpressionListI,
        ParseTreeNode_DeclarationListI,
        ParseTreeNode_DirectAbstractDeclaratorI,
        ParseTreeNode_DirectDeclaratorI,
        ParseTreeNode_EnumeratorListI,
        ParseTreeNode_EqualityExpressionI,
        ParseTreeNode_ExclusiveOrExpressionI,
        ParseTreeNode_ExpressionI,
        ParseTreeNode_IdentifierListI,
        ParseTreeNode_InclusiveOrExpressionI,
        ParseTreeNode_InitDeclaratorListI,
        ParseTreeNode_InitializerListI,
        ParseTreeNode_LogicalAndExpressionI,
        ParseTreeNode_LogicalOrExpressionI,
        ParseTreeNode_ParameterListI,
        ParseTreeNode_PostfixExpressionI,
        ParseTreeNode_RelationalExpressionI,
        ParseTreeNode_ShiftExpressionI,
        ParseTreeNode_StatementListI,
        ParseTreeNode_StructDeclarationListI,
        ParseTreeNode_StructDeclaratorListI,
        ParseTreeNode_TranslationUnitI,
        ParseTreeNode_TypeQualifierListI,

        ParseTreeNode_Unknown,
} ParseTreeNodeType;

char *ParseTreeNodeName(ParseTreeNodeType type) {
        switch (type) {
                case ParseTreeNode_AbstractDeclarator: { return "AbstractDeclarator"; } break;
                case ParseTreeNode_AdditiveExpression: { return "AdditiveExpression"; } break;
                case ParseTreeNode_AndExpression: { return "AndExpression"; } break;
                case ParseTreeNode_ArgumentExpressionList: { return "ArgumentExpressionList"; } break;
                case ParseTreeNode_AssignmentExpression: { return "AssignmentExpression"; } break;
                case ParseTreeNode_AssignmentOperator: { return "AssignmentOperator"; } break;
                case ParseTreeNode_CastExpression: { return "CastExpression"; } break;
                case ParseTreeNode_CompoundStatement: { return "CompoundStatement"; } break;
                case ParseTreeNode_ConditionalExpression: { return "ConditionalExpression"; } break;
                case ParseTreeNode_Constant: { return "Constant"; } break;
                case ParseTreeNode_ConstantExpression: { return "ConstantExpression"; } break;
                case ParseTreeNode_Declaration: { return "Declaration"; } break;
                case ParseTreeNode_DeclarationList: { return "DeclarationList"; } break;
                case ParseTreeNode_DeclarationSpecifiers: { return "DeclarationSpecifiers"; } break;
                case ParseTreeNode_Declarator: { return "Declarator"; } break;
                case ParseTreeNode_DirectAbstractDeclarator: { return "DirectAbstractDeclarator"; } break;
                case ParseTreeNode_DirectDeclarator: { return "DirectDeclarator"; } break;
                case ParseTreeNode_EnumSpecifier: { return "EnumSpecifier"; } break;
                case ParseTreeNode_Enumerator: { return "Enumerator"; } break;
                case ParseTreeNode_EnumeratorList: { return "EnumeratorList"; } break;
                case ParseTreeNode_EqualityExpression: { return "EqualityExpression"; } break;
                case ParseTreeNode_ExclusiveOrExpression: { return "ExclusiveOrExpression"; } break;
                case ParseTreeNode_Expression: { return "Expression"; } break;
                case ParseTreeNode_ExpressionStatement: { return "ExpressionStatement"; } break;
                case ParseTreeNode_ExternalDeclaration: { return "ExternalDeclaration"; } break;
                case ParseTreeNode_FunctionDefinition: { return "FunctionDefinition"; } break;
                case ParseTreeNode_Identifier: { return "Identifier"; } break;
                case ParseTreeNode_IdentifierList: { return "IdentifierList"; } break;
                case ParseTreeNode_InclusiveOrExpression: { return "InclusiveOrExpression"; } break;
                case ParseTreeNode_InitDeclarationList: { return "InitDeclarationList"; } break;
                case ParseTreeNode_InitDeclarator: { return "InitDeclarator"; } break;
                case ParseTreeNode_InitDeclaratorList: { return "InitDeclaratorList"; } break;
                case ParseTreeNode_Initializer: { return "Initializer"; } break;
                case ParseTreeNode_InitializerList: { return "InitializerList"; } break;
                case ParseTreeNode_IterationStatement: { return "IterationStatement"; } break;
                case ParseTreeNode_JumpStatement: { return "JumpStatement"; } break;
                case ParseTreeNode_Keyword: { return "Keyword"; } break;
                case ParseTreeNode_LabeledStatement: { return "LabeledStatement"; } break;
                case ParseTreeNode_LogicalAndExpression: { return "LogicalAndExpression"; } break;
                case ParseTreeNode_LogicalOrExpression: { return "LogicalOrExpression"; } break;
                case ParseTreeNode_MultiplicativeExpression: { return "MultiplicativeExpression"; } break;
                case ParseTreeNode_ParameterDeclaration: { return "ParameterDeclaration"; } break;
                case ParseTreeNode_ParameterList: { return "ParameterList"; } break;
                case ParseTreeNode_ParameterTypeList: { return "ParameterTypeList"; } break;
                case ParseTreeNode_Pointer: { return "Pointer"; } break;
                case ParseTreeNode_PostfixExpression: { return "PostfixExpression"; } break;
                case ParseTreeNode_PrimaryExpression: { return "PrimaryExpression"; } break;
                case ParseTreeNode_RelationalExpression: { return "RelationalExpression"; } break;
                case ParseTreeNode_SelectionStatement: { return "SelectionStatement"; } break;
                case ParseTreeNode_ShiftExpression: { return "ShiftExpression"; } break;
                case ParseTreeNode_SpecifierQualifierList: { return "SpecifierQualifierList"; } break;
                case ParseTreeNode_Statement: { return "Statement"; } break;
                case ParseTreeNode_StatementList: { return "StatementList"; } break;
                case ParseTreeNode_StorageClassSpecifier: { return "StorageClassSpecifier"; } break;
                case ParseTreeNode_String: { return "String"; } break;
                case ParseTreeNode_StructDeclaration: { return "StructDeclaration"; } break;
                case ParseTreeNode_StructDeclarationList: { return "StructDeclarationList"; } break;
                case ParseTreeNode_StructDeclarator: { return "StructDeclarator"; } break;
                case ParseTreeNode_StructDeclaratorList: { return "StructDeclaratorList"; } break;
                case ParseTreeNode_StructOrUnion: { return "StructOrUnion"; } break;
                case ParseTreeNode_StructOrUnionSpecifier: { return "StructOrUnionSpecifier"; } break;
                case ParseTreeNode_Symbol: { return "Symbol"; } break;
                case ParseTreeNode_TranslationUnit: { return "TranslationUnit"; } break;
                case ParseTreeNode_TypeName: { return "TypeName"; } break;
                case ParseTreeNode_TypeQualifier: { return "TypeQualifier"; } break;
                case ParseTreeNode_TypeQualifierList: { return "TypeQualifierList"; } break;
                case ParseTreeNode_TypeSpecifier: { return "TypeSpecifier"; } break;
                case ParseTreeNode_TypedefName: { return "TypedefName"; } break;
                case ParseTreeNode_UnaryExpression: { return "UnaryExpression"; } break;
                case ParseTreeNode_UnaryOperator: { return "UnaryOperator"; } break;

                case ParseTreeNode_AdditiveExpressionI: { return "AdditiveExpression'"; } break;
                case ParseTreeNode_AndExpressionI: { return "AndExpression'"; } break;
                case ParseTreeNode_ArgumentExpressionListI: { return "ArgumentExpressionList'"; } break;
                case ParseTreeNode_DeclarationListI: { return "DeclarationList'"; } break;
                case ParseTreeNode_DirectAbstractDeclaratorI: { return "DirectAbstractDeclarator'"; } break;
                case ParseTreeNode_DirectDeclaratorI: { return "DirectDeclarator'"; } break;
                case ParseTreeNode_EnumeratorListI: { return "EnumeratorList'"; } break;
                case ParseTreeNode_EqualityExpressionI: { return "EqualityExpression'"; } break;
                case ParseTreeNode_ExclusiveOrExpressionI: { return "ExclusiveOrExpression'"; } break;
                case ParseTreeNode_ExpressionI: { return "Expression'"; } break;
                case ParseTreeNode_IdentifierListI: { return "IdentifierList'"; } break;
                case ParseTreeNode_InclusiveOrExpressionI: { return "InclusiveOrExpression'"; } break;
                case ParseTreeNode_InitDeclaratorListI: { return "InitDeclaratorList'"; } break;
                case ParseTreeNode_InitializerListI: { return "InitializerList'"; } break;
                case ParseTreeNode_LogicalAndExpressionI: { return "LogicalAndExpression'"; } break;
                case ParseTreeNode_LogicalOrExpressionI: { return "LogicalOrExpression'"; } break;
                case ParseTreeNode_ParameterListI: { return "ParameterList'"; } break;
                case ParseTreeNode_PostfixExpressionI: { return "PostfixExpression'"; } break;
                case ParseTreeNode_RelationalExpressionI: { return "RelationalExpression'"; } break;
                case ParseTreeNode_ShiftExpressionI: { return "ShiftExpression'"; } break;
                case ParseTreeNode_StatementListI: { return "StatementList'"; } break;
                case ParseTreeNode_StructDeclarationListI: { return "StructDeclarationList'"; } break;
                case ParseTreeNode_StructDeclaratorListI: { return "StructDeclaratorList'"; } break;
                case ParseTreeNode_TranslationUnitI: { return "TranslationUnit'"; } break;
                case ParseTreeNode_TypeQualifierListI: { return "TypeQualifierList'"; } break;

                default: { return "Unknown"; } break;
        }
}

typedef struct ParseTreeNode {
        gs_Allocator allocator;
        u32 name_length;
        ParseTreeNodeType type;
        Token token;
        u32 capacity;
        u32 num_children;
        Token token;
        char *name;
        struct ParseTreeNode *children;
} ParseTreeNode;



@@ 30,29 233,20 @@ typedef enum ParseTreeErrorEnum {
        ParseTreeErrorNone,
} ParseTreeErrorEnum;

const char *__parse_tree_ErrorStrings[] = {
const char *__parse_tree_error_strings[] = {
        "Couldn't allocate memory for new child node",
        "No Error"
        "No error",
};

ParseTreeErrorEnum __parse_tree_LastError = ParseTreeErrorNone;
ParseTreeErrorEnum __parse_tree_last_error = ParseTreeErrorNone;

const char *ParseTreeErrorString() {
        const char *result = __parse_tree_ErrorStrings[__parse_tree_LastError];
        __parse_tree_LastError = ParseTreeErrorNone;
        const char *result = __parse_tree_error_strings[__parse_tree_last_error];
        __parse_tree_last_error = ParseTreeErrorNone;

        return result;
}

ParseTreeNode *ParseTreeInit(gs_Allocator allocator);
void ParseTreeDeinit(ParseTreeNode *node);

void ParseTreeSetName(ParseTreeNode *node, char *name);
void ParseTreeSetToken(ParseTreeNode *node, Token token);
void ParseTreeSet(ParseTreeNode *self, char *name, Token token);
void ParseTreeNewChildren(ParseTreeNode *self, u32 Count);
void ParseTreePrint(ParseTreeNode *self, u32 IndentLevel, u32 IndentIncrement);

ParseTreeNode *__parse_tree_Alloc(gs_Allocator allocator) {
        ParseTreeNode *node = (ParseTreeNode *)allocator.malloc(sizeof(*node));
        return node;


@@ 67,8 261,7 @@ void __parse_tree_Init(ParseTreeNode *node, gs_Allocator allocator) {
        node->token.line = 0;
        node->token.column = 0;

        node->name = GS_NULL_PTR;
        node->name_length = 0;
        node->type = ParseTreeNode_Unknown;
        node->children = GS_NULL_PTR;
        node->num_children = 0;
        node->capacity = 0;


@@ 82,18 275,6 @@ ParseTreeNode *ParseTreeInit(gs_Allocator allocator) {
        return node;
}

/* name must be a NULL-terminated string! */
void ParseTreeSetName(ParseTreeNode *node, char *name) {
        u32 name_length = gs_StringLength(name);
        if (node->name != NULL) {
                node->allocator.free(node->name);
        }

        node->name = (char *)node->allocator.malloc(name_length + 1);
        gs_StringCopy(name, node->name, name_length);
        node->name_length = name_length;
}

void ParseTreeSetToken(ParseTreeNode *node, Token token) {
        Token *this = &(node->token);
        this->text = token.text;


@@ 103,19 284,18 @@ void ParseTreeSetToken(ParseTreeNode *node, Token token) {
        this->column = token.column;
}

void ParseTreeSet(ParseTreeNode *self, char *name, Token token) {
        ParseTreeSetName(self, name);
void ParseTreeSet(ParseTreeNode *self, ParseTreeNodeType type, Token token) {
        self->type = type;
        ParseTreeSetToken(self, token);
}

bool __parse_tree_AddChild(ParseTreeNode *self, char *name) {
        u32 name_length = gs_StringLength(name);
bool __parse_tree_AddChild(ParseTreeNode *self, ParseTreeNodeType type) {
        u32 alloc_count = DEFAULT_ALLOC_COUNT;

        if (self->children == NULL) {
                self->children = (ParseTreeNode *)self->allocator.malloc(sizeof(ParseTreeNode) * alloc_count);
                if (self->children == NULL) {
                        __parse_tree_LastError = ParseTreeErrorChildAlloc;
                        __parse_tree_last_error = ParseTreeErrorChildAlloc;
                        return false;
                }
                self->capacity = alloc_count;


@@ 127,7 307,7 @@ bool __parse_tree_AddChild(ParseTreeNode *self, char *name) {
                        alloc_count = self->capacity * 2;
                        self->children = (ParseTreeNode *)self->allocator.realloc(self->children, sizeof(ParseTreeNode) * alloc_count);
                        if (self->children == NULL) {
                                __parse_tree_LastError = ParseTreeErrorChildAlloc;
                                __parse_tree_last_error = ParseTreeErrorChildAlloc;
                                return false;
                        }
                        self->capacity = alloc_count;


@@ 137,7 317,7 @@ bool __parse_tree_AddChild(ParseTreeNode *self, char *name) {
                }
        }

        ParseTreeSetName(&self->children[self->num_children], name);
        self->children[self->num_children].type = type;
        self->num_children++;

        return true;


@@ 145,7 325,7 @@ bool __parse_tree_AddChild(ParseTreeNode *self, char *name) {

void ParseTreeNewChildren(ParseTreeNode *self, u32 count) {
        for (int i = 0; i < count; i++) {
                __parse_tree_AddChild(self, "Empty");
                __parse_tree_AddChild(self, ParseTreeNode_Unknown);
        }
}



@@ 161,39 341,28 @@ void ParseTreeDeinit(ParseTreeNode *self) {
                self->capacity = 0;
        }

        if (self->name != NULL) {
                self->allocator.free(self->name);
                self->name = NULL;
                self->name_length = 0;
        }

        self->allocator.free(self);
}

void ParseTreePrint(ParseTreeNode *self, u32 IndentLevel, u32 IndentIncrement) {
        int min_compare_length = gs_Min(self->name_length, 5);
        if (gs_StringIsEqual("Empty", self->name, min_compare_length)) return;
void ParseTreePrint(ParseTreeNode *self, u32 indent_level, u32 indent_increment, int (*print_func)(const char *format, ...)) {
        if (self->type == ParseTreeNode_Unknown) return;

        if (self->token.type != Token_Unknown) {
                printf("[%4d,%3d] ", self->token.line, self->token.column);
                print_func("[%4d,%3d] ", self->token.line, self->token.column);
        } else {
                printf("           ");
                print_func("           ");
        }

        if (IndentLevel > 0) printf("%*c", IndentLevel * IndentIncrement, ' ');
        if (indent_level > 0) print_func("%*c", indent_level * indent_increment, ' ');

        if (self->name_length > 0) {
                printf("%s", self->name);
        } else {
                printf("Unknown name");
        }
        print_func("%s", ParseTreeNodeName(self->type));

        if (self->token.type != Token_Unknown) printf("( %.*s )", (u32)(self->token.text_length), self->token.text);
        if (self->token.type != Token_Unknown) print_func("( %.*s )", (u32)(self->token.text_length), self->token.text);

        printf("\n");
        print_func("\n");

        for (int i=0; i<self->num_children; i++) {
                ParseTreePrint(&self->children[i], IndentLevel + 1, IndentIncrement);
        for (int i = 0; i < self->num_children; i++) {
                ParseTreePrint(&self->children[i], indent_level + 1, indent_increment, print_func);
        }
}


M src/parser.c => src/parser.c +250 -295
@@ 1,10 1,10 @@
/******************************************************************************
 * File: parser.c
 * Created:
 * Updated: 2016-11-04
 * Created: 2016-07-06
 * Updated: 2020-11-16
 * Package: C-Parser
 * Creator: Aaron Oman (GrooveStomp)
 * Copyright - 2020, Aaron Oman and the C-Parser contributors
 * Copyright 2016 - 2020, Aaron Oman and the C-Parser contributors
 * SPDX-License-Identifier: LGPL-3.0-only
 ******************************************************************************/
#ifndef PARSER_C


@@ 14,20 14,18 @@
#include "lexer.c"
#include "parse_tree.c"

#include <stdio.h>

gs_Allocator __parser_allocator;

void __parser_ParseTreeUpdate(ParseTreeNode *parse_tree, char *name, u32 num_children) {
        ParseTreeSetName(parse_tree, name);
void __parser_ParseTreeUpdate(ParseTreeNode *node, ParseTreeNodeType type, u32 num_children) {
        node->type = type;
        if (num_children > 0) {
                ParseTreeNewChildren(parse_tree, num_children);
                ParseTreeNewChildren(node, num_children);
        }
}

void __parser_ParseTreeClearChildren(ParseTreeNode *parse_tree) {
        for (int i = 0; i < parse_tree->num_children; i++) {
                ParseTreeSetName(&parse_tree->children[i], "Empty");
void __parser_ParseTreeClearChildren(ParseTreeNode *node) {
        for (int i = 0; i < node->num_children; i++) {
                node->children[i].type = ParseTreeNode_Unknown;
        }
}



@@ 122,7 120,7 @@ bool ParseConstant(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                case Token_PrecisionNumber:
/*      TODO:   case Token_Enumeration:*/
                {
                        ParseTreeSet(parse_tree, "Constant", token);
                        ParseTreeSet(parse_tree, ParseTreeNode_Constant, token);
                        return true;
                } break;
                default:


@@ 137,12 135,12 @@ bool ParseArgumentExpressionListI(Tokenizer *tokenizer, ParseTreeNode *parse_tre
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Argument Expression List'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ArgumentExpressionListI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseAssignmentExpression(tokenizer, &parse_tree->children[1]) &&
           ParseArgumentExpressionListI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 158,7 156,7 @@ bool ParseArgumentExpressionListI(Tokenizer *tokenizer, ParseTreeNode *parse_tre
bool ParseArgumentExpressionList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Argument Expresion List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ArgumentExpressionList, 2);

        if (ParseAssignmentExpression(tokenizer, &parse_tree->children[0]) &&
           ParseArgumentExpressionListI(tokenizer, &parse_tree->children[1])) {


@@ 180,10 178,10 @@ bool ParsePrimaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Primary Expression", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_PrimaryExpression, 3);

        if (Token_Identifier == (tokens[0] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Identifier", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Identifier, tokens[0]);
                return true;
        }



@@ 192,7 190,7 @@ bool ParsePrimaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {

        *tokenizer = start;
        if (Token_String == (tokens[0] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "String", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_String, tokens[0]);
                return true;
        }



@@ 200,8 198,8 @@ bool ParsePrimaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
           ParseExpression(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 213,14 211,14 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Postfix Expression'", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_PostfixExpressionI, 4);

        if (Token_OpenBracket == (tokens[0] = GetToken(tokenizer)).type &&
           ParseExpression(tokenizer, &parse_tree->children[1]) &&
           Token_CloseBracket == (tokens[0] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 229,8 227,8 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseArgumentExpressionList(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 240,8 238,8 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 249,8 247,8 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Dot == (tokens[0] = GetToken(tokenizer)).type &&
           Token_Identifier == (tokens[1] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Identifier", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Identifier, tokens[1]);
                return true;
        }



@@ 258,8 256,8 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Arrow == (tokens[0] = GetToken(tokenizer)).type &&
           Token_Identifier == (tokens[1] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Identifier", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Identifier, tokens[1]);
                return true;
        }



@@ 268,14 266,14 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        *tokenizer = start;
        if (Token_PlusPlus == (tokens[0] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[1])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                return true;
        }

        *tokenizer = start;
        if (Token_MinusMinus == (tokens[0] = GetToken(tokenizer)).type &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[1])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                return true;
        }



@@ 296,7 294,7 @@ bool ParsePostfixExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParsePostfixExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Postfix Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_PostfixExpression, 2);

        if (ParsePrimaryExpression(tokenizer, &parse_tree->children[0]) &&
           ParsePostfixExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 318,7 316,7 @@ bool ParseUnaryOperator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                case Token_Tilde:
                case Token_Bang:
                {
                        ParseTreeSet(parse_tree, "Unary Operator", token);
                        ParseTreeSet(parse_tree, ParseTreeNode_UnaryOperator, token);
                        return true;
                }
                default:


@@ 342,7 340,7 @@ bool ParseUnaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Unary Expression", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_UnaryExpression, 4);

        if (ParsePostfixExpression(tokenizer, &parse_tree->children[0])) {
                return true;


@@ 353,7 351,7 @@ bool ParseUnaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        *tokenizer = start;
        if (Token_PlusPlus == (tokens[0] = GetToken(tokenizer)).type &&
           ParseUnaryExpression(tokenizer, &parse_tree->children[1])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                return true;
        }



@@ 362,7 360,7 @@ bool ParseUnaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        *tokenizer = start;
        if (Token_MinusMinus == (tokens[0] = GetToken(tokenizer)).type &&
           ParseUnaryExpression(tokenizer, &parse_tree->children[1])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                return true;
        }



@@ 380,7 378,7 @@ bool ParseUnaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        tokens[0] = GetToken(tokenizer);
        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("sizeof", tokens[0].text, gs_StringLength("sizeof"))) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);

                Tokenizer Previous = *tokenizer;
                if (ParseUnaryExpression(tokenizer, &parse_tree->children[1])) {


@@ 391,8 389,8 @@ bool ParseUnaryExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
                   ParseTypeName(tokenizer, &parse_tree->children[2]) &&
                   Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type) {
                        ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[0]);
                        ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[1]);
                        ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[0]);
                        ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[1]);
                        return true;
                }
        }


@@ 410,7 408,7 @@ bool ParseCastExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Cast Expression", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_CastExpression, 4);

        if (ParseUnaryExpression(tokenizer, &parse_tree->children[0])) {
                return true;


@@ 421,8 419,8 @@ bool ParseCastExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseTypeName(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseCastExpression(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 434,12 432,12 @@ bool ParseMultiplicativeExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_t
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Multiplicative Expression", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_MultiplicativeExpression, 3);

        if (Token_Asterisk == (token = GetToken(tokenizer)).type &&
           ParseCastExpression(tokenizer, &parse_tree->children[1]) &&
           ParseMultiplicativeExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 447,7 445,7 @@ bool ParseMultiplicativeExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_t
        if (Token_Slash == (token = GetToken(tokenizer)).type &&
           ParseCastExpression(tokenizer, &parse_tree->children[1]) &&
           ParseMultiplicativeExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 455,7 453,7 @@ bool ParseMultiplicativeExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_t
        if (Token_PercentSign == (token = GetToken(tokenizer)).type &&
           ParseCastExpression(tokenizer, &parse_tree->children[1]) &&
           ParseMultiplicativeExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 473,7 471,7 @@ bool ParseMultiplicativeExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_t
bool ParseMultiplicativeExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Multiplicative Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_MultiplicativeExpression, 2);

        if (ParseCastExpression(tokenizer, &parse_tree->children[0]) &&
           ParseMultiplicativeExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 488,12 486,12 @@ bool ParseAdditiveExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Additive Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_AdditiveExpressionI, 3);

        if (Token_Cross == (token = GetToken(tokenizer)).type &&
           ParseMultiplicativeExpression(tokenizer, &parse_tree->children[1]) &&
           ParseAdditiveExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 501,7 499,7 @@ bool ParseAdditiveExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Dash == (token = GetToken(tokenizer)).type &&
           ParseMultiplicativeExpression(tokenizer, &parse_tree->children[1]) &&
           ParseAdditiveExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 518,7 516,7 @@ bool ParseAdditiveExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseAdditiveExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Additive Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_AdditiveExpression, 2);

        if (ParseMultiplicativeExpression(tokenizer, &parse_tree->children[0]) &&
           ParseAdditiveExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 533,12 531,12 @@ bool ParseShiftExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Shift Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ShiftExpressionI, 3);

        if (Token_BitShiftLeft == (token = GetToken(tokenizer)).type &&
           ParseAdditiveExpression(tokenizer, &parse_tree->children[1]) &&
           ParseShiftExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 546,7 544,7 @@ bool ParseShiftExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_BitShiftRight == (token = GetToken(tokenizer)).type &&
           ParseAdditiveExpression(tokenizer, &parse_tree->children[1]) &&
           ParseShiftExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 563,7 561,7 @@ bool ParseShiftExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseShiftExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Shift Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ShiftExpression, 2);

        if (ParseAdditiveExpression(tokenizer, &parse_tree->children[0]) &&
           ParseShiftExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 578,12 576,12 @@ bool ParseRelationalExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Relational Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_RelationalExpressionI, 3);

        if (Token_LessThan == (token = GetToken(tokenizer)).type &&
           ParseShiftExpression(tokenizer, &parse_tree->children[1]) &&
           ParseRelationalExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 591,7 589,7 @@ bool ParseRelationalExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        if (Token_GreaterThan == (token = GetToken(tokenizer)).type &&
           ParseShiftExpression(tokenizer, &parse_tree->children[1]) &&
           ParseRelationalExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 599,7 597,7 @@ bool ParseRelationalExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        if (Token_LessThanEqual == (token = GetToken(tokenizer)).type &&
           ParseShiftExpression(tokenizer, &parse_tree->children[1]) &&
           ParseRelationalExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 607,7 605,7 @@ bool ParseRelationalExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        if (Token_GreaterThanEqual == (token = GetToken(tokenizer)).type &&
           ParseShiftExpression(tokenizer, &parse_tree->children[1]) &&
           ParseRelationalExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 626,7 624,7 @@ bool ParseRelationalExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
bool ParseRelationalExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Relational Expressoin", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_RelationalExpression, 2);

        if (ParseShiftExpression(tokenizer, &parse_tree->children[0]) &&
           ParseRelationalExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 641,12 639,12 @@ bool ParseEqualityExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Equality Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_EqualityExpressionI, 3);

        if (Token_LogicalEqual == (token = GetToken(tokenizer)).type &&
           ParseRelationalExpression(tokenizer, &parse_tree->children[1]) &&
           ParseEqualityExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 654,7 652,7 @@ bool ParseEqualityExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_NotEqual == (token = GetToken(tokenizer)).type &&
           ParseRelationalExpression(tokenizer, &parse_tree->children[1]) &&
           ParseEqualityExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 671,7 669,7 @@ bool ParseEqualityExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseEqualityExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Equality Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_EqualityExpression, 2);

        if (ParseRelationalExpression(tokenizer, &parse_tree->children[0]) &&
           ParseEqualityExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 686,12 684,12 @@ bool ParseAndExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "And Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_AndExpressionI, 3);

        if (Token_Ampersand == (token = GetToken(tokenizer)).type &&
           ParseEqualityExpression(tokenizer, &parse_tree->children[1]) &&
           ParseAndExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 707,7 705,7 @@ bool ParseAndExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseAndExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "And Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_AndExpression, 2);

        if (ParseEqualityExpression(tokenizer, &parse_tree->children[0]) &&
           ParseAndExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 722,12 720,12 @@ bool ParseExclusiveOrExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Exclusive Or Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ExclusiveOrExpressionI, 3);

        if (Token_Carat == (token = GetToken(tokenizer)).type &&
           ParseAndExpression(tokenizer, &parse_tree->children[1]) &&
           ParseExclusiveOrExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 743,7 741,7 @@ bool ParseExclusiveOrExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree
bool ParseExclusiveOrExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Exclusive Or Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ExclusiveOrExpression, 2);

        if (ParseAndExpression(tokenizer, &parse_tree->children[0]) &&
           ParseExclusiveOrExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 758,12 756,12 @@ bool ParseInclusiveOrExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Inclusive Or Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InclusiveOrExpressionI, 3);

        if (Token_Pipe == (token = GetToken(tokenizer)).type &&
           ParseExclusiveOrExpression(tokenizer, &parse_tree->children[1]) &&
           ParseInclusiveOrExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 779,7 777,7 @@ bool ParseInclusiveOrExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree
bool ParseInclusiveOrExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Inclusive Or Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InclusiveOrExpression, 2);

        if (ParseExclusiveOrExpression(tokenizer, &parse_tree->children[0]) &&
           ParseInclusiveOrExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 794,12 792,12 @@ bool ParseLogicalAndExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Logical And Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_LogicalAndExpressionI, 3);

        if (Token_LogicalAnd == (token = GetToken(tokenizer)).type &&
           ParseInclusiveOrExpression(tokenizer, &parse_tree->children[1]) &&
           ParseLogicalAndExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 815,7 813,7 @@ bool ParseLogicalAndExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
bool ParseLogicalAndExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Logical And Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_LogicalAndExpression, 2);

        if (ParseInclusiveOrExpression(tokenizer, &parse_tree->children[0]) &&
           ParseLogicalAndExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 830,12 828,12 @@ bool ParseLogicalOrExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) 
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Logical Or Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_LogicalOrExpressionI, 3);

        if (Token_LogicalOr == (token = GetToken(tokenizer)).type &&
           ParseLogicalAndExpression(tokenizer, &parse_tree->children[1]) &&
           ParseLogicalOrExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 851,7 849,7 @@ bool ParseLogicalOrExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) 
bool ParseLogicalOrExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Logical Or Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_LogicalOrExpression, 2);

        if (ParseLogicalAndExpression(tokenizer, &parse_tree->children[0]) &&
           ParseLogicalOrExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 869,7 867,7 @@ bool ParseLogicalOrExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseConstantExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Constant Expression", 1);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ConstantExpression, 1);

        if (ParseConditionalExpression(tokenizer, &parse_tree->children[0])) {
                return true;


@@ 888,15 886,15 @@ bool ParseConditionalExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Conditional Expression", 5);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ConditionalExpression, 5);

        if (ParseLogicalOrExpression(tokenizer, &parse_tree->children[0]) &&
           Token_QuestionMark == (tokens[0] = GetToken(tokenizer)).type &&
           ParseExpression(tokenizer, &parse_tree->children[2]) &&
           Token_Colon == (tokens[1] = GetToken(tokenizer)).type &&
           ParseConditionalExpression(tokenizer, &parse_tree->children[4])) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 931,7 929,7 @@ bool ParseAssignmentOperator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                case Token_AmpersandEquals:
                case Token_CaratEquals:
                case Token_PipeEquals: {
                        ParseTreeSet(parse_tree, "Assignment Operator", token);
                        ParseTreeSet(parse_tree, ParseTreeNode_AssignmentOperator, token);
                        return true;
                }
        }


@@ 948,7 946,7 @@ bool ParseAssignmentOperator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseAssignmentExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Assignment Expression", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_AssignmentExpression, 3);

        if (ParseUnaryExpression(tokenizer, &parse_tree->children[0]) &&
           ParseAssignmentOperator(tokenizer, &parse_tree->children[1]) &&


@@ 971,12 969,12 @@ bool ParseExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Expression'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ExpressionI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseAssignmentExpression(tokenizer, &parse_tree->children[1]) &&
           ParseExpressionI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 992,7 990,7 @@ bool ParseExpressionI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseExpression(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Expression", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Expression, 2);

        if (ParseAssignmentExpression(tokenizer, &parse_tree->children[0]) &&
           ParseExpressionI(tokenizer, &parse_tree->children[1])) {


@@ 1008,7 1006,7 @@ bool ParseIdentifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Token token;

        if (Token_Identifier == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(parse_tree, "Identifier", token);
                ParseTreeSet(parse_tree, ParseTreeNode_Identifier, token);
                return true;
        }



@@ 1029,14 1027,14 @@ bool ParseJumpStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        tokens[0] = GetToken(tokenizer);
        Tokenizer at_token = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Jump Statement", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_JumpStatement, 3);

        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("goto", tokens[0].text, tokens[0].text_length) &&
           ParseIdentifier(tokenizer, &parse_tree->children[1]) &&
           Token_SemiColon == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1046,8 1044,8 @@ bool ParseJumpStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("continue", tokens[0].text, tokens[0].text_length) &&
           Token_SemiColon == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1057,8 1055,8 @@ bool ParseJumpStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("break", tokens[0].text, tokens[0].text_length) &&
           Token_SemiColon == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1067,7 1065,7 @@ bool ParseJumpStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        *tokenizer = at_token;
        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("return", tokens[0].text, tokens[0].text_length)) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                int ChildIndex = 1;
                Tokenizer Previous = *tokenizer;



@@ 1077,7 1075,7 @@ bool ParseJumpStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                }

                if (Token_SemiColon == (tokens[1] = GetToken(tokenizer)).type) {
                        ParseTreeSet(&parse_tree->children[ChildIndex], "Symbol", tokens[1]);
                        ParseTreeSet(&parse_tree->children[ChildIndex], ParseTreeNode_Symbol, tokens[1]);
                        return true;
                }
        }


@@ 1098,7 1096,7 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        tokens[0] = GetToken(tokenizer);
        Tokenizer at_token = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Iteration Statement", 10); /* TODO(AARON): Magic Number! */
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_IterationStatement, 10); /* TODO(AARON): Magic Number! */

        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("while", tokens[0].text, tokens[0].text_length) &&


@@ 1106,9 1104,9 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseExpression(tokenizer, &parse_tree->children[2]) &&
           Token_CloseParen == (tokens[2] = GetToken(tokenizer)).type &&
           ParseStatement(tokenizer, &parse_tree->children[4])) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[2]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[2]);
                return true;
        }



@@ 1119,7 1117,7 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           gs_StringIsEqual("do", tokens[0].text, tokens[0].text_length) &&
           ParseStatement(tokenizer, &parse_tree->children[1])) {
                ParseTreeNode *child_node = &parse_tree->children[0];
                ParseTreeSet(child_node, "Keyword", tokens[0]);
                ParseTreeSet(child_node, ParseTreeNode_Keyword, tokens[0]);

                tokens[1] = GetToken(tokenizer);
                if (Token_Keyword == tokens[1].type &&


@@ 1128,11 1126,11 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                   ParseExpression(tokenizer, &parse_tree->children[4]) &&
                   Token_CloseParen == (tokens[3] = GetToken(tokenizer)).type &&
                   Token_SemiColon == (tokens[4] = GetToken(tokenizer)).type) {
                        ParseTreeSet(++child_node, "Keyword", tokens[1]);
                        ParseTreeSet(++child_node, "Symbol", tokens[2]);
                        ParseTreeSet(++child_node, ParseTreeNode_Keyword, tokens[1]);
                        ParseTreeSet(++child_node, ParseTreeNode_Symbol, tokens[2]);
                        ++child_node; // Child #4 is set in the `if' above.
                        ParseTreeSet(++child_node, "Symbol", tokens[3]);
                        ParseTreeSet(++child_node, "Symbol", tokens[4]);
                        ParseTreeSet(++child_node, ParseTreeNode_Symbol, tokens[3]);
                        ParseTreeSet(++child_node, ParseTreeNode_Symbol, tokens[4]);
                        return true;
                }
        }


@@ 1143,8 1141,8 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("for", tokens[0].text, tokens[0].text_length) &&
           Token_OpenParen == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);

                int i = 2;



@@ 1159,7 1157,7 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                        *tokenizer = start;
                        return false;
                }
                ParseTreeSet(&parse_tree->children[i++], "Symbol", tokens[2]);
                ParseTreeSet(&parse_tree->children[i++], ParseTreeNode_Symbol, tokens[2]);

                Previous = *tokenizer;
                if (!ParseExpression(tokenizer, &parse_tree->children[i++])) {


@@ 1171,7 1169,7 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                        *tokenizer = start;
                        return false;
                }
                ParseTreeSet(&parse_tree->children[i++], "Symbol", tokens[3]);
                ParseTreeSet(&parse_tree->children[i++], ParseTreeNode_Symbol, tokens[3]);

                Previous = *tokenizer;
                if (!ParseExpression(tokenizer, &parse_tree->children[i++])) {


@@ 1181,7 1179,7 @@ bool ParseIterationStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {

                if (Token_CloseParen == (tokens[4] = GetToken(tokenizer)).type &&
                   ParseStatement(tokenizer, &parse_tree->children[i + 1])) {
                        ParseTreeSet(&parse_tree->children[i], "Symbol", tokens[4]);
                        ParseTreeSet(&parse_tree->children[i], ParseTreeNode_Symbol, tokens[4]);
                        return true;
                }
        }


@@ 1202,7 1200,7 @@ bool ParseSelectionStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        tokens[0] = GetToken(tokenizer);
        Tokenizer at_token = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Selection Statement", 6);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_SelectionStatement, 6);

        if (Token_Keyword == tokens[0].type &&
           gs_StringIsEqual("if", tokens[0].text, tokens[0].text_length) &&


@@ 1213,14 1211,14 @@ bool ParseSelectionStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                Tokenizer at_else = *tokenizer;
                Token token = GetToken(tokenizer);

                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[2]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[2]);

                if (Token_Keyword == token.type &&
                   gs_StringIsEqual("else", token.text, token.text_length) &&
                   ParseStatement(tokenizer, &parse_tree->children[5])) {
                        ParseTreeSet(&parse_tree->children[4], "Keyword", token);
                        ParseTreeSet(&parse_tree->children[4], ParseTreeNode_Keyword, token);
                        return true;
                }



@@ 1237,9 1235,9 @@ bool ParseSelectionStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseExpression(tokenizer, &parse_tree->children[2]) &&
           Token_CloseParen == (tokens[2] = GetToken(tokenizer)).type &&
           ParseStatement(tokenizer, &parse_tree->children[4])) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[2]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[2]);
                return true;
        }



@@ 1250,7 1248,7 @@ bool ParseSelectionStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseStatementListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Statement List'", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StatementListI, 2);

        if (ParseStatement(tokenizer, &parse_tree->children[0]) &&
           ParseStatementListI(tokenizer, &parse_tree->children[1])) {


@@ 1269,7 1267,7 @@ bool ParseStatementListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseStatementList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Statement List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StatementList, 2);

        if (ParseStatement(tokenizer, &parse_tree->children[0]) &&
           ParseStatementListI(tokenizer, &parse_tree->children[1])) {


@@ 1288,10 1286,10 @@ bool ParseCompoundStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Compound Statement", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_CompoundStatement, 3);

        if (Token_OpenBrace == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                int i = 0;

                Tokenizer Previous = *tokenizer;


@@ 1307,7 1305,7 @@ bool ParseCompoundStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                }

                if (Token_CloseBrace == (token = GetToken(tokenizer)).type) {
                        ParseTreeSet(&parse_tree->children[i], "Symbol", token);
                        ParseTreeSet(&parse_tree->children[i], ParseTreeNode_Symbol, token);
                        return true;
                }
        }


@@ 1324,11 1322,11 @@ bool ParseExpressionStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Expression Statement", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ExpressionStatement, 2);

        if (ParseExpression(tokenizer, &parse_tree->children[0]) &&
           Token_SemiColon == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", token);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 1336,7 1334,7 @@ bool ParseExpressionStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {

        *tokenizer = start;
        if (Token_SemiColon == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 1354,12 1352,12 @@ bool ParseLabeledStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Labeled Statement", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_LabeledStatement, 4);

        if (ParseIdentifier(tokenizer, &parse_tree->children[0]) &&
           Token_Colon == (tokens[0] = GetToken(tokenizer)).type &&
           ParseStatement(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[0]);
                return true;
        }



@@ 1372,8 1370,8 @@ bool ParseLabeledStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseConstantExpression(tokenizer, &parse_tree->children[1]) &&
           Token_Colon == (tokens[1] = GetToken(tokenizer)).type &&
           ParseStatement(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1384,8 1382,8 @@ bool ParseLabeledStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           gs_StringIsEqual("default", tokens[0].text, tokens[0].text_length) &&
           Token_Colon == (tokens[1] = GetToken(tokenizer)).type &&
           ParseStatement(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Keyword", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1405,7 1403,7 @@ bool ParseLabeledStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseStatement(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Statement", 1);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Statement, 1);
        ParseTreeNode *child = &parse_tree->children[0];

        if (ParseLabeledStatement(tokenizer, child)) return true;


@@ 1438,10 1436,10 @@ bool ParseTypedefName(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Token token = GetToken(tokenizer);
        *tokenizer = start;

        __parser_ParseTreeUpdate(parse_tree, "Typedef Name", 1);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TypedefName, 1);

        if (ParseIdentifier(tokenizer, &parse_tree->children[0]) && TypedefIsName(token)) {
                ParseTreeSet(parse_tree, "Typedef Name", token);
                ParseTreeSet(parse_tree, ParseTreeNode_TypedefName, token);
                return true;
        }



@@ 1459,14 1457,14 @@ bool ParseDirectAbstractDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_t
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Direct Abstract Declarator'", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DirectAbstractDeclaratorI, 4);

        if (Token_OpenBracket == (tokens[0] = GetToken(tokenizer)).type &&
           ParseConstantExpression(tokenizer, &parse_tree->children[1]) &&
           Token_CloseBracket == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1476,8 1474,8 @@ bool ParseDirectAbstractDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_t
        if (Token_OpenBracket == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseBracket == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1486,8 1484,8 @@ bool ParseDirectAbstractDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_t
           ParseParameterTypeList(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1497,8 1495,8 @@ bool ParseDirectAbstractDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_t
        if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1516,14 1514,14 @@ bool ParseDirectAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tr
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Direct Abstract Declarator", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DirectAbstractDeclarator, 4);

        if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
           ParseAbstractDeclarator(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1532,8 1530,8 @@ bool ParseDirectAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tr
           ParseConstantExpression(tokenizer, &parse_tree->children[1]) &&
           Token_CloseBracket == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1543,8 1541,8 @@ bool ParseDirectAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tr
        if (Token_OpenBracket == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseBracket == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1553,8 1551,8 @@ bool ParseDirectAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tr
           ParseParameterTypeList(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1562,8 1560,8 @@ bool ParseDirectAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tr
        if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectAbstractDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1579,7 1577,7 @@ bool ParseDirectAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tr
bool ParseAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Abstract Declarator", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_AbstractDeclarator, 2);

        if (ParsePointer(tokenizer, &parse_tree->children[0]) &&
           ParseDirectAbstractDeclarator(tokenizer, &parse_tree->children[1])) {


@@ 1609,7 1607,7 @@ bool ParseAbstractDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseTypeName(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Type Name", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TypeName, 2);

        if (ParseSpecifierQualifierList(tokenizer, &parse_tree->children[0]) &&
           ParseAbstractDeclarator(tokenizer, &parse_tree->children[1])) {


@@ 1631,12 1629,12 @@ bool ParseInitializerListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Initializer List'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InitializerListI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseInitializer(tokenizer, &parse_tree->children[1]) &&
           ParseInitializerListI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 1652,7 1650,7 @@ bool ParseInitializerListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseInitializerList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Initializer List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InitializerList, 2);

        if (ParseInitializer(tokenizer, &parse_tree->children[0]) &&
           ParseInitializerListI(tokenizer, &parse_tree->children[1])) {


@@ 1673,7 1671,7 @@ bool ParseInitializer(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[3];

        __parser_ParseTreeUpdate(parse_tree, "Initializer", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Initializer, 4);

        if (ParseAssignmentExpression(tokenizer, &parse_tree->children[0])) {
                return true;


@@ 1683,8 1681,8 @@ bool ParseInitializer(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_OpenBrace == (tokens[0] = GetToken(tokenizer)).type &&
           ParseInitializerList(tokenizer, &parse_tree->children[1]) &&
           Token_CloseBrace == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1693,9 1691,9 @@ bool ParseInitializer(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseInitializerList(tokenizer, &parse_tree->children[1]) &&
           Token_Comma == (tokens[1] = GetToken(tokenizer)).type &&
           Token_CloseBrace == (tokens[2] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[2]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[2]);
                return true;
        }



@@ 1707,12 1705,12 @@ bool ParseIdentifierListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Identifier List'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_IdentifierListI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseIdentifier(tokenizer, &parse_tree->children[1]) &&
           ParseIdentifierListI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 1728,7 1726,7 @@ bool ParseIdentifierListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseIdentifierList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Identifier List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_IdentifierList, 2);

        if (ParseIdentifier(tokenizer, &parse_tree->children[0]) &&
           ParseIdentifierListI(tokenizer, &parse_tree->children[1])) {


@@ 1747,7 1745,7 @@ bool ParseIdentifierList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseParameterDeclaration(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Parameter Declaration", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ParameterDeclaration, 2);

        if (ParseDeclarationSpecifiers(tokenizer, &parse_tree->children[0]) &&
           ParseDeclarator(tokenizer, &parse_tree->children[1])) {


@@ 1775,12 1773,12 @@ bool ParseParameterListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Parameter List'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ParameterListI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseParameterDeclaration(tokenizer, &parse_tree->children[1]) &&
           ParseParameterListI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 1796,7 1794,7 @@ bool ParseParameterListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseParameterList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Parameter List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ParameterList, 2);

        if (ParseParameterDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseParameterListI(tokenizer, &parse_tree->children[1])) {


@@ 1816,14 1814,14 @@ bool ParseParameterTypeList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Parameter Type List", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ParameterTypeList, 3);

        if (ParseParameterList(tokenizer, &parse_tree->children[0])) {
                Tokenizer Previous = *tokenizer;
                if (Token_Comma == (tokens[0] = GetToken(tokenizer)).type &&
                   Token_Ellipsis == (tokens[1] = GetToken(tokenizer)).type) {
                        ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[0]);
                        ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                        ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[0]);
                        ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                        return true;
                }



@@ 1838,7 1836,7 @@ bool ParseParameterTypeList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseTypeQualifierListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Type Qualifier List'", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TypeQualifierListI, 2);

        if (ParseTypeQualifier(tokenizer, &parse_tree->children[0]) &&
           ParseTypeQualifierListI(tokenizer, &parse_tree->children[1])) {


@@ 1857,7 1855,7 @@ bool ParseTypeQualifierListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseTypeQualifierList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Type Qualifier List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TypeQualifierList, 2);

        if (ParseTypeQualifier(tokenizer, &parse_tree->children[0]) &&
           ParseTypeQualifierListI(tokenizer, &parse_tree->children[1])) {


@@ 1878,14 1876,14 @@ bool ParsePointer(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Token token = GetToken(tokenizer);
        Tokenizer at_token = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Pointer", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Pointer, 2);

        if (Token_Asterisk != token.type) {
                *tokenizer = start;
                return false;
        }

        ParseTreeSet(parse_tree, "Pointer", token);
        ParseTreeSet(parse_tree, ParseTreeNode_Pointer, token);

        if (ParseTypeQualifierList(tokenizer, &parse_tree->children[0]) &&
           ParsePointer(tokenizer, &parse_tree->children[1])) {


@@ 1920,14 1918,14 @@ bool ParseDirectDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Direct Declarator'", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DirectDeclaratorI, 4);

        if (Token_OpenBracket == (tokens[0] = GetToken(tokenizer)).type &&
           ParseConstantExpression(tokenizer, &parse_tree->children[1]) &&
           Token_CloseBracket == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1937,8 1935,8 @@ bool ParseDirectDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_OpenBracket == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseBracket == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1947,8 1945,8 @@ bool ParseDirectDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseParameterTypeList(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1957,8 1955,8 @@ bool ParseDirectDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseIdentifierList(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1968,8 1966,8 @@ bool ParseDirectDeclaratorI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_OpenParen == (tokens[0] = GetToken(tokenizer)).type &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 1989,7 1987,7 @@ bool ParseDirectDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Direct Declarator", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DirectDeclarator, 4);

        if (ParseIdentifier(tokenizer, &parse_tree->children[0]) &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[1])) {


@@ 2001,8 1999,8 @@ bool ParseDirectDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
           ParseDeclarator(tokenizer, &parse_tree->children[1]) &&
           Token_CloseParen == (tokens[1] = GetToken(tokenizer)).type &&
           ParseDirectDeclaratorI(tokenizer, &parse_tree->children[3])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 2017,7 2015,7 @@ bool ParseDirectDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Declarator", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Declarator, 2);

        if (ParsePointer(tokenizer, &parse_tree->children[0]) &&
           ParseDirectDeclarator(tokenizer, &parse_tree->children[1])) {


@@ 2044,12 2042,12 @@ bool ParseEnumerator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Enumerator", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Enumerator, 3);

        if (ParseIdentifier(tokenizer, &parse_tree->children[0]) &&
           Token_EqualSign == (token = GetToken(tokenizer)).type &&
           ParseConstantExpression(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", token);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2068,12 2066,12 @@ bool ParseEnumeratorListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Enumerator List'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_EnumeratorListI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseEnumerator(tokenizer, &parse_tree->children[1]) &&
           ParseEnumeratorListI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2089,7 2087,7 @@ bool ParseEnumeratorListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseEnumeratorList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Enumerator List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_EnumeratorList, 2);

        if (ParseEnumerator(tokenizer, &parse_tree->children[0]) &&
           ParseEnumeratorListI(tokenizer, &parse_tree->children[1])) {


@@ 2111,7 2109,7 @@ bool ParseEnumSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer at_token = *tokenizer;
        Token tokens[2];

        __parser_ParseTreeUpdate(parse_tree, "Enum Specifier", 5);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_EnumSpecifier, 5);

        if (!(Token_Keyword == token.type &&
             gs_StringIsEqual("enum", token.text, token.text_length))) {


@@ 2119,14 2117,14 @@ bool ParseEnumSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
                return false;
        }

        ParseTreeSet(&parse_tree->children[0], "Keyword", token);
        ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Keyword, token);

        if (ParseIdentifier(tokenizer, &parse_tree->children[1]) &&
           Token_OpenBrace == (tokens[0] = GetToken(tokenizer)).type &&
           ParseEnumeratorList(tokenizer, &parse_tree->children[3]) &&
           Token_CloseBrace == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[4], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[4], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 2137,8 2135,8 @@ bool ParseEnumSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_OpenBrace == (tokens[0] = GetToken(tokenizer)).type &&
           ParseEnumeratorList(tokenizer, &parse_tree->children[2]) &&
           Token_CloseBrace == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 2162,12 2160,12 @@ bool ParseStructDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Struct Declarator", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructDeclarator, 3);

        if (ParseDeclarator(tokenizer, &parse_tree->children[0]) &&
           Token_Colon == (token = GetToken(tokenizer)).type &&
           ParseConstantExpression(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", token);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2176,7 2174,7 @@ bool ParseStructDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        *tokenizer = start;
        if (Token_Colon == (token = GetToken(tokenizer)).type &&
           ParseConstantExpression(tokenizer, &parse_tree->children[1])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2195,12 2193,12 @@ bool ParseStructDeclaratorListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Struct Declarator List'", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructDeclaratorListI, 3);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseStructDeclarator(tokenizer, &parse_tree->children[1]) &&
           ParseStructDeclaratorListI(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2216,7 2214,7 @@ bool ParseStructDeclaratorListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
bool ParseStructDeclaratorList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Struct Declarator List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructDeclaratorList, 2);

        if (ParseStructDeclarator(tokenizer, &parse_tree->children[0]) &&
           ParseStructDeclaratorListI(tokenizer, &parse_tree->children[1])) {


@@ 2235,7 2233,7 @@ bool ParseStructDeclaratorList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) 
bool ParseSpecifierQualifierList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Specifier Qualifier List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_SpecifierQualifierList, 2);

        if (ParseTypeSpecifier(tokenizer, &parse_tree->children[0]) &&
           ParseSpecifierQualifierList(tokenizer, &parse_tree->children[1])) {


@@ 2274,12 2272,12 @@ bool ParseStructDeclaration(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Struct Declaration", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructDeclaration, 3);

        if (ParseSpecifierQualifierList(tokenizer, &parse_tree->children[0]) &&
           ParseStructDeclaratorList(tokenizer, &parse_tree->children[1]) &&
           Token_SemiColon == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[2], "Struct Declaration", token);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_StructDeclaration, token);
                return true;
        }



@@ 2296,12 2294,12 @@ bool ParseInitDeclarator(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Init Declarator", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InitDeclarator, 3);

        if (ParseDeclarator(tokenizer, &parse_tree->children[0]) &&
           Token_EqualSign == (token = GetToken(tokenizer)).type &&
           ParseInitializer(tokenizer, &parse_tree->children[2])) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", token);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2320,11 2318,11 @@ bool ParseInitDeclaratorListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Init Declarator List'", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InitDeclaratorListI, 2);

        if (Token_Comma == (token = GetToken(tokenizer)).type &&
           ParseInitDeclarator(tokenizer, &parse_tree->children[1])) {
                ParseTreeSet(&parse_tree->children[0], "Symbol", token);
                ParseTreeSet(&parse_tree->children[0], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2340,7 2338,7 @@ bool ParseInitDeclaratorListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseInitDeclaratorList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Init Declaration List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_InitDeclarationList, 2);

        if (ParseInitDeclarator(tokenizer, &parse_tree->children[0]) &&
           ParseInitDeclaratorListI(tokenizer, &parse_tree->children[1])) {


@@ 2354,7 2352,7 @@ bool ParseInitDeclaratorList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseStructDeclarationListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Struct Declaration List'", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructDeclarationListI, 2);

        if (ParseStructDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseStructDeclarationListI(tokenizer, &parse_tree->children[1])) {


@@ 2373,7 2371,7 @@ bool ParseStructDeclarationListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree
bool ParseStructDeclarationList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Struct Declaration List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructDeclarationList, 2);

        if (ParseStructDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseStructDeclarationListI(tokenizer, &parse_tree->children[1])) {


@@ 2395,7 2393,7 @@ bool ParseStructOrUnion(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (Token_Keyword == token.type) {
                if (gs_StringIsEqual(token.text, "struct", token.text_length) ||
                   gs_StringIsEqual(token.text, "union", token.text_length)) {
                        ParseTreeSet(parse_tree, "Struct or Union", token);
                        ParseTreeSet(parse_tree, ParseTreeNode_StructOrUnion, token);
                        return true;
                }
        }


@@ 2412,7 2410,7 @@ bool ParseStructOrUnion(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseStructOrUnionSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Struct or Union Specifier", 5);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_StructOrUnionSpecifier, 5);

        Token tokens[2];



@@ 2421,8 2419,8 @@ bool ParseStructOrUnionSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree
           Token_OpenBrace == (tokens[0] = GetToken(tokenizer)).type &&
           ParseStructDeclarationList(tokenizer, &parse_tree->children[3]) &&
           Token_CloseBrace == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[2], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[4], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[4], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 2433,8 2431,8 @@ bool ParseStructOrUnionSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree
           Token_OpenBrace == (tokens[0] = GetToken(tokenizer)).type &&
           ParseStructDeclarationList(tokenizer, &parse_tree->children[2]) &&
           Token_CloseBrace == (tokens[1] = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", tokens[0]);
                ParseTreeSet(&parse_tree->children[3], "Symbol", tokens[1]);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, tokens[0]);
                ParseTreeSet(&parse_tree->children[3], ParseTreeNode_Symbol, tokens[1]);
                return true;
        }



@@ 2461,7 2459,7 @@ bool ParseTypeQualifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (token.type == Token_Keyword) {
                if (gs_StringIsEqual(token.text, "const", token.text_length) ||
                   gs_StringIsEqual(token.text, "volatile", token.text_length)) {
                        ParseTreeSet(parse_tree, "Type Qualifier", token);
                        ParseTreeSet(parse_tree, ParseTreeNode_TypeQualifier, token);
                        return true;
                }
        }


@@ 2484,13 2482,13 @@ bool ParseTypeSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        if (token.type == Token_Keyword) {
                for (int i = 0; i < gs_ArraySize(keywords); i++) {
                        if (gs_StringIsEqual(token.text, keywords[i], token.text_length)) {
                                ParseTreeSet(parse_tree, "Type Specifier", token);
                                ParseTreeSet(parse_tree, ParseTreeNode_TypeSpecifier, token);
                                return true;
                        }
                }
        }

        __parser_ParseTreeUpdate(parse_tree, "Type Specifier", 1);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TypeSpecifier, 1);

        *tokenizer = start;
        if (ParseStructOrUnionSpecifier(tokenizer, &parse_tree->children[0])) {


@@ 2523,7 2521,7 @@ bool ParseStorageClassSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
        if (token.type == Token_Keyword) {
                for (int i = 0; i < gs_ArraySize(keywords); i++) {
                        if (gs_StringIsEqual(token.text, keywords[i], token.text_length)) {
                                ParseTreeSet(parse_tree, "Storage Class Specifier", token);
                                ParseTreeSet(parse_tree, ParseTreeNode_StorageClassSpecifier, token);
                                return true;
                        }
                }


@@ 2543,7 2541,7 @@ bool ParseStorageClassSpecifier(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
bool ParseDeclarationSpecifiers(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Declaration Specifiers", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DeclarationSpecifiers, 2);

        if (ParseStorageClassSpecifier(tokenizer, &parse_tree->children[0]) &&
           ParseDeclarationSpecifiers(tokenizer, &parse_tree->children[1])) {


@@ 2586,7 2584,7 @@ bool ParseDeclarationSpecifiers(Tokenizer *tokenizer, ParseTreeNode *parse_tree)
bool ParseDeclarationListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Declaration List'", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DeclarationListI, 2);

        if (ParseDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseDeclarationListI(tokenizer, &parse_tree->children[1])) {


@@ 2605,7 2603,7 @@ bool ParseDeclarationListI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseDeclarationList(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Declaration List", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_DeclarationList, 2);

        if (ParseDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseDeclarationListI(tokenizer, &parse_tree->children[1])) {


@@ 2624,19 2622,19 @@ bool ParseDeclaration(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;
        Token token;

        __parser_ParseTreeUpdate(parse_tree, "Declaration", 3);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_Declaration, 3);

        if (ParseDeclarationSpecifiers(tokenizer, &parse_tree->children[0]) &&
           ParseInitDeclaratorList(tokenizer, &parse_tree->children[1]) &&
           Token_SemiColon == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[2], "Symbol", token);
                ParseTreeSet(&parse_tree->children[2], ParseTreeNode_Symbol, token);
                return true;
        }

        *tokenizer = start;
        if (ParseDeclarationSpecifiers(tokenizer, &parse_tree->children[0]) &&
           Token_SemiColon == (token = GetToken(tokenizer)).type) {
                ParseTreeSet(&parse_tree->children[1], "Symbol", token);
                ParseTreeSet(&parse_tree->children[1], ParseTreeNode_Symbol, token);
                return true;
        }



@@ 2651,7 2649,7 @@ bool ParseDeclaration(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseFunctionDefinition(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Function Definition", 4);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_FunctionDefinition, 4);

        if (ParseDeclarationSpecifiers(tokenizer, &parse_tree->children[0]) &&
           ParseDeclarator(tokenizer, &parse_tree->children[1]) &&


@@ 2696,7 2694,7 @@ bool ParseFunctionDefinition(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseExternalDeclaration(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "External Declaration", 1);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_ExternalDeclaration, 1);

        if (ParseFunctionDefinition(tokenizer, &parse_tree->children[0])) return true;



@@ 2710,7 2708,7 @@ bool ParseExternalDeclaration(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseTranslationUnitI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Translation Unit'", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TranslationUnitI, 2);

        if (ParseExternalDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseTranslationUnitI(tokenizer, &parse_tree->children[1])) {


@@ 2729,7 2727,7 @@ bool ParseTranslationUnitI(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
bool ParseTranslationUnit(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        Tokenizer start = *tokenizer;

        __parser_ParseTreeUpdate(parse_tree, "Translation Unit", 2);
        __parser_ParseTreeUpdate(parse_tree, ParseTreeNode_TranslationUnit, 2);

        if (ParseExternalDeclaration(tokenizer, &parse_tree->children[0]) &&
           ParseTranslationUnitI(tokenizer, &parse_tree->children[1])) {


@@ 2740,64 2738,21 @@ bool ParseTranslationUnit(Tokenizer *tokenizer, ParseTreeNode *parse_tree) {
        return false;
}

void Parse(gs_Allocator allocator, gs_Buffer *stream, bool show_parse_tree) {
bool Parse(gs_Allocator allocator, gs_Buffer *stream, ParseTreeNode **out_tree, Tokenizer *out_tokenizer) {
        __parser_allocator = allocator;
        ParseTreeNode *parse_tree = ParseTreeInit(allocator);

        Tokenizer tokenizer;
        tokenizer.beginning = tokenizer.at = stream->start;
        tokenizer.line = tokenizer.column = 1;
        char *stream_end = stream->start + stream->length - 1;

        TypedefInit(__parser_typedef_names);

        bool parsing = true;
        while (parsing) {
                Tokenizer start = tokenizer;
                Token token = GetToken(&tokenizer);
                Tokenizer after_token = tokenizer;
                tokenizer = start;

                switch (token.type) {
                        /* Done! */
                        case Token_EndOfStream: {
                                parsing = false;
                        } break;

                        /* Skip this input. */
                        case Token_PreprocessorCommand:
                        case Token_Comment:
                        case Token_Unknown: {
                                tokenizer = after_token;
                        } break;

                        /* Okay, let's parse! */
                        default: {
                                bool result = ParseTranslationUnit(&tokenizer, parse_tree);

                                if (result && tokenizer.at == stream_end) {
                                        puts("Successfully parsed input");
                                } else {
                                        puts("Input did not parse");
                                        if (!result) {
                                                puts("Parsing failed");
                                        } else if (tokenizer.at != stream_end) {
                                                puts("Parsing terminated early");
                                                printf("tokenizer->At(%p), File End(%p)\n", tokenizer.at, stream_end);
                                        }
                                }

                                if (show_parse_tree) {
                                        puts("--------------------------------------------------------------------------------");
                                        ParseTreePrint(parse_tree, 0, 2);
                                        puts("--------------------------------------------------------------------------------");
                                }
                                parsing = false;
                        } break;
                }
        }
        bool result = ParseTranslationUnit(&tokenizer, parse_tree);
        *out_tokenizer = tokenizer;
        *out_tree = parse_tree;

        ParseTreeDeinit(parse_tree);
        return result;
}

#endif /* PARSER_C */

M src/test.c => src/test.c +3 -3
@@ 1,10 1,10 @@
/******************************************************************************
 * File: test.c
 * Created:
 * Updated: 2016-11-03
 * Created: 2016-07-06
 * Updated: 2016-11-16
 * Package: C-Parser
 * Creator: Aaron Oman (GrooveStomp)
 * Copyright - 2020, Aaron Oman and the C-Parser contributors
 * Copyright 2016 - 2020, Aaron Oman and the C-Parser contributors
 * SPDX-License-Identifier: LGPL-3.0-only
 ******************************************************************************/
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */