Parser

Example Usage

To demonstrate the usage of the libparser library, the below program parses the Ix programming language and converts it to simple Java.

Includes

The program uses the C standard library, the C standard IO library, the libtokenizer library, and the libparser library.

C
#include <stdlib.h>
#include <stdio.h>
#include "libparser/libparser.h"
#include "libtokenizer/PushbackReader.h"

Program Structure

Execution begins in the 'main' function and recursively descends into either the printPackage, printClass, printFunction, or printStatement function, depending on the AST (Abstract Syntax Tree) nodes traversed.

C
int main( int argc, char** argv );
        //
        void printPackage ( NodeIterator* it );
        void printClass   ( NodeIterator* it );
        void printFunction( NodeIterator* it );

Functions

Function: main
C
int main( int argc, char** argv )
{
    if ( 1 < argc )
    {
        const char* filepath = argv[1];

        Parser* parser = Parser_NewFromFile ( filepath );
        AST*    ast    = Parser_parse       ( parser   );
/*
        const Node*     root      = AST_getRoot        ( ast        );
        NodeIterator*   it        = Node_iterator      ( root       ); 

        while ( NodeIterator_hasNext( it ) )
        {
            const Node child = NodeIterator_next( it );
            {
                switch ( child->nodeType )
                {
                case NODE_PACKAGE:
                    printPackage( it );
                    break;

                case NODE_CLASS:
                    printClass( it );
                    break;

                case NODE_FUNCTION:
                    printFunction( it );
                    break;
                }
            }
        }
        NodeIterator_free( &it     );
        Parser_free      ( &parser );
*/
        
        Parser_free( &parser );
    }
    return 0;
}

Main include

CC
#ifndef LIBPARSER_STRUCTS_H
#define LIBPARSER_STRUCTS_H

typedef struct _AST          AST;
typedef struct _Node         Node;
typedef struct _NodeIterator NodeIterator;
typedef struct _Parser       Parser;

#endif

Includes

C
#include "libtokenizer/Base.h"
#include "libtokenizer/Runtime.h"
#include "libtokenizer/Tokenizer.h"

Types

CC
#include "libparser/AST.h"
#include "libparser/Node.h"
#include "libparser/NodeIterator.h"
#include "libparser/Parser.h"
Parser
C
#ifndef LIBPARSER_PARSER_H
#define LIBPARSER_PARSER_H

#include "libparser/structs.h"

struct _Parser
{
    Tokenizer* tokenizer;
    AST*       ast;
};

Parser* Parser_NewFromFile( const char* filepath );

Parser* Parser_new  ( Tokenizer** tokenizer );
Parser* Parser_free ( Parser** self );
AST*    Parser_parse( Parser*  self );

#endif

Constructor

CCC
#include <stdlib.h>
#include "libparser/libparser.h"

Destructor

CCC
Parser* Parser_free( Parser** self )
{
    if ( (*self) && (*self)->tokenizer )
    {
        (*self)->tokenizer = Tokenizer_free( &(*self)->tokenizer );
    }
    return ((*self) = Runtime_Free( *self ));
}
AST
C
#ifndef LIBPARSER_AST_H
#define LIBPARSER_AST_H

#include "libparser/structs.h"

struct _AST
{
    Node* root;
};

AST*        AST_new    ( Node* root );
const Node* AST_getRoot( AST*  ast  );

#endif

Node

Class Definitions

C
#ifndef LIBPARSER_NODE_H
#define LIBPARSER_NODE_H

#include "libparser/structs.h"

struct _Node
{
    const Node*  parent;
          Token* token;
          Node** children;
};

Node*         Node_new     ( const Node* parent, Token** token );
NodeIterator* Node_iterator( const Node*  self  );

#endif

Constructor

C
Node* Node_new( const Node* parent, Token** token )
{
    Node* self = Runtime_Calloc( 1, sizeof( Node ) );

    if ( self )
    {
        self->parent   = parent;
        self->token    = *token;
        self->children = NULL; // Array 
    }

    return self;
}

Destructor

C
Node* Node_free( Node** self )
{
    Node* _self = *self;

    if ( _self )
    {
        Token_free( _self->token );
        // Array_free( _self->children );
    }

    return (*self = NULL);
}

Node_iterator

C
NodeIterator* Node_iterator( const Node* self )
{
    return NULL;
}

Node

Class Definitions

C
#ifndef LIBPARSER_NODEITERATOR_H
#define LIBPARSER_NODEITERATOR_H

#include "libparser/structs.h"

struct _NodeIterator
{
    const Node* parent;
          Node* current;
};

NodeIterator* NodeIterator_new    ( const Node* parent );
NodeIterator* NodeIterator_free   ( NodeIterator** self );
bool          NodeIterator_hasNext( NodeIterator*  self );
Node*         NodeIterator_next   ( NodeIterator*  self );

#endif

Constructor

C
NodeIterator* NodeIterator_new( const Node* parent )
{
    NodeIterator* self = Runtime_Calloc( 1, sizeof( NodeIterator ) );

    if ( self )
    {
        self->parent  = parent;
        self->current = NULL;
    }

    return self;
}

Destructor

C
NodeIterator* NodeIterator_free( NodeIterator** self )
{
    NodeIterator* _self = *self;

    if ( _self )
    {
        _self->parent  = NULL;
        _self->current = NULL;
    }

    return (*self = NULL);
}

CC
bool NodeIterator_hasNext( NodeIterator* self )
{
    return FALSE;
}

Make

MAKEFILEMAKEFILE
CFLAGS=-O0
BIN=bin
DEP=dep/libtokenizer/obj/c/*.o
INC=-Iinclude -Idep/libtokenizer/include
LIB=lib
OBJ=obj
SRC=src

all: dirs c js tests

dirs:
	mkdir -p $(BIN) $(OBJ) $(OBJ)/c $(LIB)

c: dirs
	cc -c $(CFLAGS) $(INC) -o $(OBJ)/c/AST.o          $(SRC)/c/AST.c
	cc -c $(CFLAGS) $(INC) -o $(OBJ)/c/Node.o         $(SRC)/c/Node.c
	cc -c $(CFLAGS) $(INC) -o $(OBJ)/c/NodeIterator.o $(SRC)/c/NodeIterator.c
	cc -c $(CFLAGS) $(INC) -o $(OBJ)/c/Parser.o       $(SRC)/c/Parser.c

js:
	mkdir -p $(LIB)/js
	cat $(SRC)/js/*.js > $(LIB)/js/libparser.js

tests:
	cc $(CFLAGS) $(INC) -o $(BIN)/testParser  $(SRC)/c/testParser.c  $(OBJ)/c/*.o $(DEP)

.PHONY: test
test:
	$(BIN)/testParser         > /dev/null