[gcalctool] Replace lex/bison parser with hand-written parser



commit 4acb11b9692e01d40bee2d3c31d582d5de485b31
Author: PioneerAxon <arth svnit gmail com>
Date:   Fri Aug 3 18:26:28 2012 +0530

    Replace lex/bison parser with hand-written parser
    
    Fixed .gitignore file entry.
    Removed dependency of lex/bison.
    Add back test case in test-mp-equation.c.
    Added new parser code.
    -prelexer.[ch] deals with unichar manipulation.
    -lexer.[ch] generates tokens from input.
    -parser.[ch] deals with grammar, and generates parse-tree.
    -parserfunc.[ch] binds mp code and parser to evaluate parse-tree.
    
    This patch is result of 33 commits.
    The repository with complete commit history is hosted at https://bitbucket.org/PioneerAxon/math-parser

 .gitignore                |    2 +-
 configure.ac              |   19 -
 src/Makefile.am           |   59 +--
 src/lexer.c               |  587 ++++++++++++++++++++++
 src/lexer.h               |   40 ++
 src/mp-equation-lexer.l   |  111 ----
 src/mp-equation-parser.y  |  261 ----------
 src/mp-equation-private.h |   56 --
 src/mp-equation.c         |   85 ++--
 src/parser.c              | 1228 +++++++++++++++++++++++++++++++++++++++++++++
 src/parser.h              |   79 +++
 src/parserfunc.c          |  967 +++++++++++++++++++++++++++++++++++
 src/parserfunc.h          |   80 +++
 src/prelexer.c            |  214 ++++++++
 src/prelexer.h            |   93 ++++
 src/test-mp-equation.c    |    2 +-
 16 files changed, 3353 insertions(+), 530 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e1d7840..3cc5d51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,4 +40,4 @@ src/mp-equation-parser.h
 src/gcalccmd
 src/gcalctool
 src/test-mp
-src/test-mp-serializer
+src/test-mp-equation
diff --git a/configure.ac b/configure.ac
index c2ff44d..011073d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,25 +43,6 @@ AC_SUBST(GLIB_MKENUMS)
 AC_CHECK_LIB(m, log)
 
 dnl ###########################################################################
-dnl Determine if a usable lex is available on this system
-dnl ###########################################################################
-
-AM_PROG_LEX
-if [[ "$LEX" != "flex" ]]; then
-	AC_MSG_ERROR(flex is required to create the gcalctool scanners)
-fi
-
-dnl ###########################################################################
-dnl Determine if a usable yacc is available on this system
-dnl ###########################################################################
-
-AC_PROG_YACC
-AC_CHECK_PROG(HAVE_YACC, $YACC, yes, no)
-if [[ "$HAVE_YACC" = "no" ]]; then
-	AC_MSG_ERROR($YACC is not usable as yacc - consider using bison)
-fi
-
-dnl ###########################################################################
 dnl Internationalization
 dnl ###########################################################################
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 3a23f65..b67c11d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,10 +42,6 @@ gcalctool_SOURCES = \
 	mp-equation.c \
 	mp-equation.h \
 	mp-equation-private.h \
-	mp-equation-lexer.c \
-	mp-equation-lexer.h \
-	mp-equation-parser.c \
-	mp-equation-parser.h \
 	mp-private.h \
 	mp-serializer.c \
 	mp-serializer.h \
@@ -57,7 +53,15 @@ gcalctool_SOURCES = \
 	unit-category.c \
 	unit-category.h \
 	unit-manager.c \
-	unit-manager.h
+	unit-manager.h \
+	prelexer.c \
+	prelexer.h \
+	lexer.c \
+	lexer.h \
+	parserfunc.c \
+	parserfunc.h \
+	parser.c \
+	parser.h
 
 gcalctool_LDADD = \
 	$(GCALCTOOL_LIBS)        
@@ -74,8 +78,6 @@ gcalccmd_SOURCES = \
 	mp-enums.c \
 	mp-enums.h \
 	mp-equation.c \
-	mp-equation-parser.c \
-	mp-equation-lexer.c \
 	mp-serializer.c \
 	mp-serializer.h\
 	mp-trigonometric.c \
@@ -84,7 +86,15 @@ gcalccmd_SOURCES = \
 	unit-category.c \
 	unit-category.h \
 	unit-manager.c \
-	unit-manager.h
+	unit-manager.h \
+	prelexer.c \
+	prelexer.h \
+	lexer.c \
+	lexer.h \
+	parserfunc.c \
+	parserfunc.h \
+	parser.c \
+	parser.h
 
 gcalccmd_LDADD = \
 	$(GCALCCMD_LIBS) \
@@ -117,8 +127,6 @@ test_mp_equation_SOURCES = \
 	mp-enums.c \
 	mp-enums.h \
 	mp-equation.c \
-	mp-equation-parser.c \
-	mp-equation-lexer.c \
 	mp-serializer.c \
 	mp-serializer.h \
 	mp-trigonometric.c \
@@ -127,7 +135,15 @@ test_mp_equation_SOURCES = \
 	unit-category.c \
 	unit-category.h \
 	unit-manager.c \
-	unit-manager.h
+	unit-manager.h \
+	prelexer.c \
+	prelexer.h \
+	lexer.c \
+	lexer.h \
+	parserfunc.c \
+	parserfunc.h \
+	parser.c \
+	parser.h
 
 test_mp_equation_LDADD = \
 	$(GCALCCMD_LIBS) \
@@ -135,24 +151,7 @@ test_mp_equation_LDADD = \
 
 CLEANFILES = \
 	mp-enums.c \
-	mp-enums.h \
-	mp-equation-parser.h \
-	mp-equation-parser.c \
-	mp-equation-lexer.c \
-	mp-equation-lexer.h
-
-# Generate parser files
-mp-equation-parser.c mp-equation-parser.h: mp-equation-parser.y mp-equation-lexer.h
-	$(AM_V_GEN)$(YACC) -d -o mp-equation-parser.c $(srcdir)/mp-equation-parser.y
-
-# Generate lexer files
-mp-equation-lexer.c mp-equation-lexer.h: mp-equation-lexer.l
-	$(AM_V_GEN)$(LEX) $(srcdir)/mp-equation-lexer.l
-
-# Rebuild parser when source files change
-mp-equation-parser.o: mp-equation-lexer.h
-mp-equation-lexer.o: mp-equation-parser.h
-mp-equation.c: mp-equation-lexer.h mp-equation-parser.h
+	mp-enums.h
 
 # Generate enum types
 mp-enums.h: mp-enums.h.template mp-serializer.h
@@ -176,8 +175,6 @@ uninstall-local:
 	&& rm -f "$(DESTDIR)$(bindir)/gnome-calculator"
 
 EXTRA_DIST = \
-	mp-equation-parser.y \
-	mp-equation-lexer.l \
 	mp-enums.c.template \
 	mp-enums.h.template
 
diff --git a/src/lexer.c b/src/lexer.c
new file mode 100644
index 0000000..9f6f9ab
--- /dev/null
+++ b/src/lexer.c
@@ -0,0 +1,587 @@
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "lexer.h"
+#include "parserfunc.h"
+#include "mp-equation.h"
+
+static gboolean
+l_check_if_function(LexerState* state)
+{
+    gchar* name = pl_get_marked_substring(state->prelexer);
+    if(!state->parent->function_is_defined)
+    {
+        free(name);
+        return FALSE;
+    }
+    if ((*(state->parent->function_is_defined))(state->parent, name))
+    {
+        free(name);
+        return TRUE;
+    }
+    else
+    {
+        free(name);
+        return FALSE;
+    }
+}
+
+static gboolean
+l_check_if_number(LexerState* state)
+{
+    MPNumber tmp;
+    int count = 0;
+    gchar* text = pl_get_marked_substring(state->prelexer);
+    if(mp_set_from_string(text, state->parent->options->base, &tmp) == 0)
+    {
+        free(text);
+        return TRUE;
+    }
+    else
+    {
+        /* Try to rollback several characters to see, if that yeilds any number. */
+        while(strlen (text) > 0)
+        {
+            if(mp_set_from_string(text, state->parent->options->base, &tmp) == 0)
+            {
+                free(text);
+                return TRUE;
+            }
+            free(text);
+            count++;
+            pl_roll_back(state->prelexer);
+            text = pl_get_marked_substring(state->prelexer);
+        }
+        /* Undo all rollbacks. */
+        while(count--)
+            pl_get_next_token (state->prelexer);
+        free(text);
+        return FALSE;
+    }
+}
+
+/* Insert generated token to the LexerState structure. */
+static LexerToken*
+l_insert_token(LexerState* state, const LexerTokenType type)
+{
+    state->tokens = (LexerToken *) realloc(state->tokens, (state->token_count + 1) * sizeof(LexerToken));
+    assert(state->tokens != NULL);
+    state->tokens[state->token_count].string = pl_get_marked_substring(state->prelexer);
+    state->tokens[state->token_count].start_index = state->prelexer->mark_index;
+    state->tokens[state->token_count].end_index = state->prelexer->next_index;
+    state->tokens[state->token_count].token_type = type;
+    state->token_count++;
+    return &state->tokens[state->token_count - 1];
+}
+
+/* Generates next token from pre-lexer stream and call l_insert_token() to insert it at the end. */
+static LexerToken*
+l_insert_next_token(LexerState* lstate)
+{
+    PreLexerState* state = lstate->prelexer;
+    LexerTokenType type;
+    gchar* tmp;
+    pl_set_marker(state);
+    /* Ignore all blank spaces. :) */
+    while((type = pl_get_next_token(state)) == PL_SKIP)
+        /* Set marker. Beginning of new token. */
+        pl_set_marker(state);
+    if(type == T_AND
+     ||type == T_OR
+     ||type == T_XOR
+     ||type == T_NOT
+     ||type == T_ADD
+     ||type == T_SUBTRACT
+     ||type == T_MULTIPLY
+     ||type == T_DIVIDE
+     ||type == T_L_FLOOR
+     ||type == T_R_FLOOR
+     ||type == T_L_CEILING
+     ||type == T_R_CEILING
+     ||type == T_ROOT
+     ||type == T_ROOT_3
+     ||type == T_ROOT_4
+     ||type == T_ASSIGN
+     ||type == T_L_R_BRACKET
+     ||type == T_R_R_BRACKET
+     ||type == T_L_S_BRACKET
+     ||type == T_R_S_BRACKET
+     ||type == T_L_C_BRACKET
+     ||type == T_R_C_BRACKET
+     ||type == T_ABS
+     ||type == T_POWER
+     ||type == T_FACTORIAL
+     ||type == T_PERCENTAGE)
+    {
+        return l_insert_token(lstate, type);
+    }
+    /* [PL_SUPER_MINUS][PL_SUPER_DIGIT]+ */
+    if(type == PL_SUPER_MINUS)
+    {
+        if((type = pl_get_next_token(state)) != PL_SUPER_DIGIT)
+        {
+            /* ERROR: expected PL_SUP_DIGIT */
+            set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring (state));
+            free(tmp);
+            return l_insert_token(lstate, T_UNKNOWN);
+        }
+        /* Get all PL_SUPER_DIGITs. */
+        while (pl_get_next_token(state) == PL_SUPER_DIGIT);
+        pl_roll_back(state);
+        return l_insert_token(lstate, T_NSUP_NUMBER);
+    }
+    /* [PL_SUPER_DIGIT]+ */
+    if(type == PL_SUPER_DIGIT)
+    {
+        while(pl_get_next_token(state) == PL_SUPER_DIGIT);
+        pl_roll_back(state);
+        return l_insert_token(lstate, T_SUP_NUMBER);
+    }
+    /* [PL_SUB_DIGIT]+ */
+    if(type == PL_SUB_DIGIT)
+    {
+        while(pl_get_next_token(state) == PL_SUB_DIGIT);
+        pl_roll_back(state);
+        return l_insert_token(lstate, T_SUB_NUMBER);
+    }
+    /* [PL_FRACTION] */
+    if(type == PL_FRACTION)
+    {
+        return l_insert_token(lstate, T_NUMBER);
+    }
+    if(type == PL_DIGIT)
+    {
+        while((type = pl_get_next_token(state)) == PL_DIGIT);
+        if(type == PL_FRACTION)
+        {
+            return l_insert_token(lstate, T_NUMBER);
+        }
+        else if(type == PL_SUB_DIGIT)
+        {
+            while(pl_get_next_token(state) == PL_SUB_DIGIT);
+            pl_roll_back(state);
+            return l_insert_token(lstate, T_NUMBER);
+        }
+        else if(type == PL_DEGREE)
+        {
+            type = pl_get_next_token(state);
+            if(type == PL_DIGIT)
+            {
+                while((type = pl_get_next_token(state)) == PL_DIGIT);
+                if(type == PL_DECIMAL)
+                {
+                    goto ANGLE_NUM_DM_STATE;
+                }
+                else if(type == PL_MINUTE)
+                {
+                    type = pl_get_next_token(state);
+                    if(type == PL_DIGIT)
+                    {
+                        while((type = pl_get_next_token(state)) == PL_DIGIT);
+                        if(type == PL_DECIMAL)
+                        {
+                            goto ANGLE_NUM_DMS_STATE;
+                        }
+                        else if(type == PL_SECOND)
+                        {
+                            return l_insert_token(lstate, T_NUMBER);
+                        }
+                        else
+                        {
+                            /* ERROR: expected PL_SECOND */
+                            set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring (state));
+                            free(tmp);
+                            return l_insert_token(lstate, T_UNKNOWN);
+                        }
+                    }
+                    else if(type == PL_DECIMAL)
+                    {
+ANGLE_NUM_DMS_STATE:
+                        if((type = pl_get_next_token (state)) != PL_DIGIT)
+                        {
+                            /* ERROR: expected PL_DIGIT */
+                            set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                            free(tmp);
+                            return l_insert_token(lstate, T_UNKNOWN);
+                        }
+                        while((type = pl_get_next_token(state)) == PL_DIGIT);
+                        if(type == PL_SECOND)
+                        {
+                            return l_insert_token(lstate, T_NUMBER);
+                        }
+                        else
+                        {
+                            /* ERROR: expected PL_SECOND */
+                            set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                            free(tmp);
+                            return l_insert_token(lstate, T_UNKNOWN);
+                        }
+                    }
+                    else
+                    {
+                        pl_roll_back(state);
+                        return l_insert_token(lstate, T_NUMBER);
+                    }
+                }
+                else
+                {
+                    /* ERROR: expected PL_MINUTE | PL_DIGIT */
+                    set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                    free(tmp);
+                    return l_insert_token(lstate, T_UNKNOWN);
+                }
+            }
+            else if(type == PL_DECIMAL)
+            {
+ANGLE_NUM_DM_STATE:
+                if((type = pl_get_next_token(state)) != PL_DIGIT)
+                {
+                    /* ERROR: expected PL_DIGIT */
+                    set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                    free(tmp);
+                    return l_insert_token(lstate, T_UNKNOWN);
+                }
+                while((type = pl_get_next_token(state)) == PL_DIGIT);
+                if(type == PL_MINUTE)
+                {
+                    return l_insert_token(lstate, T_NUMBER);
+                }
+                else
+                {
+                    /* ERROR: expected PL_MINUTE */
+                    set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                    free(tmp);
+                    return l_insert_token(lstate, T_UNKNOWN);
+                }
+            }
+            else
+            {
+                return l_insert_token(lstate, T_NUMBER);
+            }
+        }
+        else if(type == PL_DECIMAL)
+        {
+            goto DECIMAL_STATE;
+        }
+        else if(type == PL_HEX)
+        {
+            goto HEX_DEC_STATE;
+        }
+        else
+        {
+            pl_roll_back(state);
+            return l_insert_token(lstate, T_NUMBER);
+        }
+    }
+    if(type == PL_DECIMAL)
+    {
+DECIMAL_STATE:
+        type = pl_get_next_token(state);
+        if(type == PL_DIGIT)
+        {
+            while((type = pl_get_next_token(state)) == PL_DIGIT);
+            if(type == PL_DEGREE)
+            {
+                return l_insert_token(lstate, T_NUMBER);
+            }
+            else if(type == PL_HEX)
+            {
+                goto DECIMAL_HEX_STATE;
+            }
+            else if(type == PL_SUB_DIGIT)
+            {
+                while(pl_get_next_token(state) == PL_SUB_DIGIT);
+                pl_roll_back(state);
+                return l_insert_token(lstate, T_NUMBER);
+            }
+            else
+            {
+                pl_roll_back(state);
+                return l_insert_token(lstate, T_NUMBER);
+            }
+        }
+        else if(type == PL_HEX)
+        {
+            goto DECIMAL_HEX_STATE;
+        }
+        else
+        {
+            /* ERROR: expected PL_DIGIT | PL_HEX */
+            set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+            free(tmp);
+            return l_insert_token(lstate, T_UNKNOWN);
+        }
+    }
+    if(type == PL_HEX)
+    {
+        while((type = pl_get_next_token(state)) == PL_HEX);
+        if(type == PL_DIGIT)
+        {
+HEX_DEC_STATE:
+            while(1)
+            {
+                type = pl_get_next_token(state);
+                if(type == PL_DIGIT || type == PL_HEX)
+                {
+                    continue;
+                }
+                else if(type == PL_DECIMAL)
+                {
+                    goto DECIMAL_HEX_STATE;
+                }
+                else if(type == PL_SUB_DIGIT)
+                {
+                    while(pl_get_next_token(state) == PL_SUB_DIGIT);
+                    pl_roll_back(state);
+                    return l_insert_token(lstate, T_NUMBER);
+                }
+                else
+                {
+                    if(l_check_if_number(lstate))
+                        return l_insert_token(lstate, T_NUMBER);
+                    /* ERROR: expected PL_DECIMAL | PL_DIGIT | PL_HEX */
+                    set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                    free(tmp);
+                    return l_insert_token(lstate, T_UNKNOWN);
+                }
+            }
+        }
+        else if(type == PL_DECIMAL)
+        {
+DECIMAL_HEX_STATE:
+            type = pl_get_next_token(state);
+            if(!(type == PL_DIGIT || type == PL_HEX))
+            {
+                /* ERROR: expected PL_DIGIT | PL_HEX */
+                set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
+                free(tmp);
+                return l_insert_token(lstate, T_UNKNOWN);
+            }
+            while(1)
+            {
+                type = pl_get_next_token(state);
+                if(type == PL_DIGIT || type == PL_HEX)
+                {
+                    continue;
+                }
+                else if(type == PL_SUB_DIGIT)
+                {
+                    while(pl_get_next_token(state) == PL_SUB_DIGIT);
+                    pl_roll_back(state);
+                    return l_insert_token(lstate, T_NUMBER);
+                }
+                else
+                {
+                    pl_roll_back(state);
+                    return l_insert_token(lstate, T_NUMBER);
+                }
+            }
+        }
+        else if(type == PL_SUB_DIGIT)
+        {
+            while(pl_get_next_token(state) == PL_SUB_DIGIT);
+            pl_roll_back(state);
+            if(l_check_if_number(lstate))
+            {
+                /* NUMBER */
+                return l_insert_token(lstate, T_NUMBER);
+            }
+            else
+            {
+                /* VARIABLE */
+                if(l_check_if_function(lstate))
+                {
+                    return l_insert_token(lstate, T_FUNCTION);
+                }
+                else
+                {
+                    return l_insert_token(lstate, T_VARIABLE);
+                }
+            }
+        }
+        else if(type == PL_LETTER)
+        {
+            goto LETTER_STATE;
+        }
+        else
+        {
+            pl_roll_back(state);
+            if(l_check_if_number(lstate))
+            {
+                /* NUMBER */
+                return l_insert_token(lstate, T_NUMBER);
+            }
+            else
+            {
+                /* VARIABLE */
+                if(l_check_if_function(lstate))
+                {
+                    return l_insert_token(lstate, T_FUNCTION);
+                }
+                else
+                {
+                    return l_insert_token(lstate, T_VARIABLE);
+                }
+            }
+        }
+    }
+    if(type == PL_LETTER)
+    {
+LETTER_STATE:
+        while(1)
+        {
+            type = pl_get_next_token(state);
+            if(type == PL_LETTER || type == PL_HEX)
+            {
+                continue;
+            }
+            else if(type == PL_SUB_DIGIT)
+            {
+                while(pl_get_next_token(state) == PL_SUB_DIGIT);
+                pl_roll_back(state);
+                tmp = g_ascii_strdown(pl_get_marked_substring(state), -1);
+                if(g_strcmp0(tmp, "mod") == 0)
+                {
+                    return l_insert_token(lstate, T_MOD);
+                }
+                if(g_strcmp0(tmp, "and") == 0)
+                {
+                    return l_insert_token(lstate, T_AND);
+                }
+                if(g_strcmp0(tmp, "or") == 0)
+                {
+                    return l_insert_token(lstate, T_OR);
+                }
+                if(g_strcmp0(tmp, "xor") == 0)
+                {
+                    return l_insert_token(lstate, T_XOR);
+                }
+                if(g_strcmp0(tmp, "not") == 0)
+                {
+                    return l_insert_token(lstate, T_NOT);
+                }
+                if(g_strcmp0(tmp, "in") == 0)
+                {
+                    return l_insert_token(lstate, T_IN);
+                }
+                if(l_check_if_function(lstate))
+                {
+                    return l_insert_token(lstate, T_FUNCTION);
+                }
+                else
+                {
+                    return l_insert_token(lstate, T_VARIABLE);
+                }
+            }
+            else
+            {
+                pl_roll_back(state);
+                tmp = g_ascii_strdown(pl_get_marked_substring(state), -1);
+                if(g_strcmp0(tmp, "mod") == 0)
+                {
+                    return l_insert_token(lstate, T_MOD);
+                }
+                if(g_strcmp0(tmp, "and") == 0)
+                {
+                    return l_insert_token(lstate, T_AND);
+                }
+                if(g_strcmp0(tmp, "or") == 0)
+                {
+                    return l_insert_token(lstate, T_OR);
+                }
+                if(g_strcmp0(tmp, "xor") == 0)
+                {
+                    return l_insert_token(lstate, T_XOR);
+                }
+                if(g_strcmp0(tmp, "not") == 0)
+                {
+                    return l_insert_token(lstate, T_NOT);
+                }
+                if(g_strcmp0(tmp, "in") == 0)
+                {
+                    return l_insert_token(lstate, T_IN);
+                }
+                if(l_check_if_function(lstate))
+                {
+                    return l_insert_token(lstate, T_FUNCTION);
+                }
+                else
+                {
+                    return l_insert_token(lstate, T_VARIABLE);
+                }
+            }
+        }
+    }
+    if(type == PL_EOS)
+    {
+        return l_insert_token(lstate, PL_EOS);
+    }
+    /* ERROR: Unexpected token.. X( */
+    set_error(lstate->parent, PARSER_ERR_INVALID, tmp = pl_get_marked_substring(state));
+    free(tmp);
+    return l_insert_token(lstate, T_UNKNOWN);
+}
+
+/* Call l_insert_next_token() as many times as needed to completely tokenize the string. */
+void
+l_insert_all_tokens(LexerState* state)
+{
+    LexerToken* token;
+    while(1)
+    {
+        token = l_insert_next_token(state);
+        assert(token != NULL);
+        if(token->token_type == PL_EOS)
+        {
+            break;
+        }
+    }
+}
+
+/* Create a lexer state from given input string. This will take care of pre-lexer state. */
+LexerState*
+l_create_lexer(const gchar* input, struct parser_state* parent)
+{
+    LexerState* ret;
+    ret = (LexerState *) malloc(sizeof(LexerState));
+    assert(ret != NULL);
+    ret->prelexer = pl_create_scanner(input);
+    ret->tokens = NULL;
+    ret->token_count = 0;
+    ret->next_token = 0;
+    ret->parent = parent;
+    return ret;
+}
+
+/* Destroy lexer state and free memory. */
+void
+l_destroy_lexer(LexerState* state)
+{
+    int l;
+    pl_destroy_scanner(state->prelexer);
+    for(l = 0; l < state->token_count; l++)
+    {
+        free(state->tokens[l].string);
+    }
+    free(state->tokens);
+    free(state);
+}
+
+/* Get next token interface. Will be called by parser to get pointer to next token in token stream. */
+LexerToken*
+l_get_next_token(LexerState* state)
+{
+    /* Return PL_EOS token after token stream reaches to its end. */
+    if(state->next_token >= state->token_count)
+        return &state->tokens[state->token_count - 1];
+    return &state->tokens[state->next_token++];
+}
+
+/* Roll back one lexer token. */
+void
+l_roll_back(LexerState* state)
+{
+    if(state->next_token > 0)
+        state->next_token--;
+}
diff --git a/src/lexer.h b/src/lexer.h
new file mode 100644
index 0000000..2fd7fa7
--- /dev/null
+++ b/src/lexer.h
@@ -0,0 +1,40 @@
+#ifndef LEXER_H
+#define LEXER_H
+
+#include "prelexer.h"
+
+/* Structure to hold single token. */
+typedef struct
+{
+    gchar* string;			/* Poniter to local copy of token string. */
+    guint start_index;			/* Start index in original stream. */
+    guint end_index;			/* End index in original stream. */
+    LexerTokenType token_type;		/* Type of token. */
+} LexerToken;
+
+/* Structure to hold lexer state and all the tokens. */
+typedef struct
+{
+    PreLexerState *prelexer;		/* Pre-lexer state. Pre-lexer is part of lexer. */
+    LexerToken *tokens;			/* Pointer to the dynamic array of LexerTokens. */
+    guint token_count;			/* Count of tokens in array. */
+    guint next_token;			/* Index of next, to be sent, token. */
+    struct parser_state *parent;	/* Pointer to the parent parser. */
+} LexerState;
+
+/* Create a new LexerState object and fill the dynamic array with tokens. */
+LexerState* l_create_lexer(const gchar*, struct parser_state*);
+
+/* Destroy LexerState object and free up space. */
+void l_destroy_lexer(LexerState*);
+
+/* Tokanize complete string. */
+void l_insert_all_tokens(LexerState*);
+
+/* Return next, to be sent, token. */
+LexerToken* l_get_next_token(LexerState*);
+
+/* Roll back one token. */
+void l_roll_back(LexerState*);
+
+#endif /* LEXER_H */
diff --git a/src/mp-equation.c b/src/mp-equation.c
index addff8e..9b6a195 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -10,16 +10,12 @@
  */
 
 #include <ctype.h>
-
-#include "mp-equation-private.h"
-#include "mp-equation-parser.h"
-#include "mp-equation-lexer.h"
-
-extern int _mp_equation_parse(yyscan_t yyscanner);
-
+#include <string.h>
+#include <stdlib.h>
+#include "parser.h"
 
 static int
-variable_is_defined(MPEquationParserState *state, const char *name)
+variable_is_defined(ParserState *state, const char *name)
 {
     /* FIXME: Make more generic */
     if (strcmp(name, "e") == 0 || strcmp(name, "i") == 0 || strcmp(name, "Ï") == 0)
@@ -31,7 +27,7 @@ variable_is_defined(MPEquationParserState *state, const char *name)
 
 
 static int
-get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
+get_variable(ParserState *state, const char *name, MPNumber *z)
 {
     int result = 1;
 
@@ -50,7 +46,7 @@ get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
 }
 
 static void
-set_variable(MPEquationParserState *state, const char *name, const MPNumber *x)
+set_variable(ParserState *state, const char *name, const MPNumber *x)
 {
     // Reserved words, e, Ï, mod, and, or, xor, not, abs, log, ln, sqrt, int, frac, sin, cos, ...
     if (strcmp(name, "e") == 0 || strcmp(name, "i") == 0 || strcmp(name, "Ï") == 0)
@@ -107,7 +103,7 @@ super_atoi(const char *data)
 
 
 static int
-function_is_defined(MPEquationParserState *state, const char *name)
+function_is_defined(ParserState *state, const char *name)
 {
     char *c, *lower_name;
 
@@ -151,7 +147,7 @@ function_is_defined(MPEquationParserState *state, const char *name)
 
 
 static int
-get_function(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z)
+get_function(ParserState *state, const char *name, const MPNumber *x, MPNumber *z)
 {
     char *c, *lower_name;
     int result = 1;
@@ -239,7 +235,7 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
 
 
 static int
-convert(MPEquationParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
+convert(ParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
 {
     if (state->options->convert)
         return state->options->convert(x, x_units, z_units, z, state->options->callback_data);
@@ -252,49 +248,44 @@ MPErrorCode
 mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *result, char **error_token)
 {
     int ret;
-    MPEquationParserState state;
-    yyscan_t yyscanner;
-    YY_BUFFER_STATE buffer;
+    int err;
+    ParserState* state;
+    state = p_create_parser (expression, options);
 
     if (!(expression && result) || strlen(expression) == 0)
         return PARSER_ERR_INVALID;
 
-    memset(&state, 0, sizeof(MPEquationParserState));
-    state.options = options;
-    state.variable_is_defined = variable_is_defined;
-    state.get_variable = get_variable;
-    state.set_variable = set_variable;
-    state.function_is_defined = function_is_defined;
-    state.get_function = get_function;
-    state.convert = convert;
-    state.error = 0;
-
+    state->variable_is_defined = variable_is_defined;
+    state->get_variable = get_variable;
+    state->set_variable = set_variable;
+    state->function_is_defined = function_is_defined;
+    state->get_function = get_function;
+    state->convert = convert;
+    state->error = 0;
     mp_clear_error();
-
-    _mp_equation_lex_init_extra(&state, &yyscanner);
-    buffer = _mp_equation__scan_string(expression, yyscanner);
-
-    ret = _mp_equation_parse(yyscanner);
-    if (state.error_token != NULL && error_token != NULL) {
-        *error_token = state.error_token;
+    ret = p_parse (state);
+    if (state->error_token != NULL && error_token != NULL) {
+        *error_token = state->error_token;
     }
-
-    _mp_equation__delete_buffer(buffer, yyscanner);
-    _mp_equation_lex_destroy(yyscanner);
-
     /* Error during parsing */
-    if (state.error)
-        return state.error;
+    if (state->error) {
+	err = state->error;
+        p_destroy_parser (state);
+        return err;
+    }
 
-    if (mp_get_error())
+    if (mp_get_error()) {
+        p_destroy_parser (state);
         return PARSER_ERR_MP;
+    }
 
     /* Failed to parse */
-    if (ret)
+    if (ret) {
+        p_destroy_parser (state);
         return PARSER_ERR_INVALID;
-
-    mp_set_from_mp(&state.ret, result);
-
+    }
+    mp_set_from_mp(&state->ret, result);
+    p_destroy_parser (state);
     return PARSER_ERR_NONE;
 }
 
@@ -322,9 +313,3 @@ mp_error_code_to_string(MPErrorCode error_code)
         return "Unknown parser error";
     }
 }
-
-
-int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text)
-{
-    return 0;
-}
diff --git a/src/parser.c b/src/parser.c
new file mode 100644
index 0000000..497f148
--- /dev/null
+++ b/src/parser.c
@@ -0,0 +1,1228 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "parser.h"
+#include "parserfunc.h"
+#include "mp-equation.h"
+
+/* Converts LexerTokenType to Precedence value. */
+static guint
+p_get_precedence(LexerTokenType type)
+{
+    /* WARNING: This function doesn't work for Unary Plus and Unary Minus. Use their precedence directly while inserting them in tree. */
+    if(type == T_ADD
+     ||type == T_SUBTRACT)
+        return P_AddSubtract;
+    if(type == T_MULTIPLY)
+        return P_Multiply;
+    if(type == T_MOD)
+        return P_Mod;
+    if(type == T_DIVIDE)
+        return P_Divide;
+    if(type == T_NOT)
+        return P_Not;
+    if(type == T_ROOT
+     ||type == T_ROOT_3
+     ||type == T_ROOT_4)
+        return P_Root;
+    if(type == T_FUNCTION)
+        return P_Function;
+    if(type == T_AND
+     ||type == T_OR
+     ||type == T_XOR)
+        return P_Boolean;
+    if(type == T_PERCENTAGE)
+        return P_Percentage;
+    if(type == T_POWER)
+        return P_Power;
+    if(type == T_FACTORIAL)
+        return P_Factorial;
+    if(type == T_NUMBER
+     ||type == T_VARIABLE)
+        return P_NumberVariable;
+    return P_Unknown;
+}
+
+/* Return associativity of specific token type from precedence. */
+static Associativity
+p_get_associativity_p(Precedence type)
+{
+    if(type == P_Boolean
+     ||type == P_Divide
+     ||type == P_Mod
+     ||type == P_Multiply
+     ||type == P_AddSubtract)
+        return LEFT_ASSOCIATIVE;
+    if(type == P_Power)
+        return RIGHT_ASSOCIATIVE;
+    /* For all remaining / non-associative operators, return Left Associativity. */
+    return LEFT_ASSOCIATIVE;
+}
+
+/* Return associativity of specific token by converting it to precedence first. */
+static Associativity
+p_get_associativity(LexerToken* token)
+{
+    return p_get_associativity_p(p_get_precedence(token->token_type));
+}
+
+/* Generate precedence for a node from precedence value. Includes depth_level. */
+static guint
+p_make_precedence_p(ParserState* state, Precedence p)
+{
+    return (p + (state->depth_level * P_Depth));
+}
+
+/* Generate precedence for a node from lexer token type. Includes depth_level. */
+static guint
+p_make_precedence_t(ParserState* state, LexerTokenType type)
+{
+    return (p_get_precedence(type) + (state->depth_level * P_Depth));
+}
+
+/* Allocate and create a new node. */
+static ParseNode*
+p_create_node(ParserState* state, LexerToken* token, guint precedence, Associativity associativity, void* value, void* (*function)(ParseNode*))
+{
+    ParseNode* new;
+    new = (ParseNode*) malloc(sizeof(ParseNode));
+    assert(new != NULL);
+    new->parent = NULL;
+    new->left = NULL;
+    new->right = NULL;
+    new->token = token;
+    new->precedence = precedence;
+    new->associativity = associativity;
+    new->value = value;
+    new->state = state;
+    new->evaluate = function;
+    return new;
+}
+
+/* Compares two nodes to decide, which will be parent and which willbe child. */
+static gint
+p_cmp_nodes(ParseNode* left, ParseNode* right)
+{
+    /* Return values.
+       1 = right goes up (near root) in parse tree.
+       0 = left  goes up (near root) in parse tree.
+    */
+    if(left == NULL)
+        return 0;
+    if(left->precedence > right->precedence)
+    {
+        return 1;
+    }
+    else if(left->precedence < right->precedence)
+    {
+        return 0;
+    }
+    else
+    {
+        if(right->associativity == RIGHT_ASSOCIATIVE)
+        {
+            return 0;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+}
+
+/* Unified interface (unary and binary nodes) to insert node into parse tree. */
+static void
+p_insert_into_tree_all(ParserState* state, ParseNode* node, guint unary_function)
+{
+    if(state->root == NULL)
+    {
+        state->root = node;
+        state->right_most = state->root;
+        return;
+    }
+    ParseNode* tmp = state->right_most;
+    while(p_cmp_nodes(tmp, node))
+        tmp = tmp->parent;
+    if(unary_function)
+    {
+        /* If tmp is null, that means, we have to insert new node at root. */
+        if(tmp == NULL)
+        {
+            node->right = state->root;
+            node->right->parent = node;
+
+            state->root = node;
+        }
+        else
+        {
+            node->right = tmp->right;
+            if(node->right)
+                node->right->parent = node;
+
+            tmp->right = node;
+            if(tmp->right)
+                tmp->right->parent = tmp;
+
+        }
+        state->right_most = node;
+        while(state->right_most->right != NULL)
+            state->right_most = state->right_most->right;
+    }
+    else
+    {
+        /* If tmp is null, that means, we have to insert new node at root. */
+        if(tmp == NULL)
+        {
+            node->left = state->root;
+            node->left->parent = node;
+
+            state->root = node;
+        }
+        else
+        {
+            node->left = tmp->right;
+            if(node->left)
+                node->left->parent = node;
+
+            tmp->right = node;
+            if(tmp->right)
+                tmp->right->parent = tmp;
+
+        }
+        state->right_most = node;
+    }
+}
+
+/* Insert binary node into the parse tree. */
+static void
+p_insert_into_tree(ParserState* state, ParseNode* node)
+{
+    p_insert_into_tree_all(state, node, 0);
+}
+
+/* Insert unary node into the parse tree. */
+static void
+p_insert_into_tree_unary(ParserState* state, ParseNode* node)
+{
+    p_insert_into_tree_all(state, node, 1);
+}
+
+/* Recursive call to free every node of parse-tree. */
+static void
+p_destroy_all_nodes(ParseNode* node)
+{
+    if(node == NULL)
+        return;
+    p_destroy_all_nodes(node->left);
+    p_destroy_all_nodes(node->right);
+    /* Don't call free for tokens, as they are allocated and freed in lexer. */
+    /* WARNING: If node->value is freed elsewhere, please assign it NULL before calling p_destroy_all_nodes(). */
+    if(node->value)
+        free(node->value);
+    free(node);
+}
+
+/* Create parser state. */
+ParserState*
+p_create_parser(const gchar* input, MPEquationOptions* options)
+{
+    ParserState* state;
+    state = (ParserState*) malloc(sizeof(ParserState));
+    assert(state != NULL);
+    state->lexer = l_create_lexer(input, state);
+    state->root = NULL;
+    state->depth_level = 0;
+    state->right_most = NULL;
+    state->options = options;
+    state->error = 0;
+    state->error_token = NULL;
+    return state;
+}
+
+static guint statement (ParserState*);
+/* Start parsing input string. And call evaluate on success. */
+guint
+p_parse(ParserState* state)
+{
+    guint ret;
+    LexerToken* token;
+    MPNumber* ans;
+    l_insert_all_tokens(state->lexer);
+    ret = statement(state);
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == T_ASSIGN)
+    {
+        token = l_get_next_token(state->lexer);
+        if(token->token_type != PL_EOS)
+        {
+        /* Full string is not parsed. */
+            if(!state->error)
+                set_error(state, PARSER_ERR_INVALID, token->string);
+            return PARSER_ERR_INVALID;
+        }
+    }
+    if(token->token_type != PL_EOS)
+    {
+        /* Full string is not parsed. */
+        if(!state->error)
+            set_error(state, PARSER_ERR_INVALID, token->string);
+        return PARSER_ERR_INVALID;
+    }
+    if(ret == 0)
+        /* Input can't be parsed with grammar. */
+        return PARSER_ERR_INVALID;
+    ans = (MPNumber *) (*(state->root->evaluate))(state->root);
+    if(ans)
+    {
+        mp_set_from_mp(ans, &state->ret);
+        free(ans);
+        return PARSER_ERR_NONE;
+    }
+    return PARSER_ERR_INVALID;
+}
+
+/* Destroy parser state. */
+void
+p_destroy_parser(ParserState* state)
+{
+    /* If state has a parse tree, destroy it first. */
+    if(state->root)
+    {
+        p_destroy_all_nodes(state->root);
+    }
+    l_destroy_lexer(state->lexer);
+    free(state);
+}
+
+/* LL (*) parser. Lookahead count depends on tokens. Handle with care. :P */
+
+static guint expression(ParserState* state);
+static guint expression_1(ParserState* state);
+static guint expression_2(ParserState* state);
+static guint unit(ParserState* state);
+static guint variable(ParserState* state);
+static guint term(ParserState* state);
+static guint term_2(ParserState* state);
+
+/* Helping function to p_check_variable. */
+static gchar*
+utf8_next_char(const gchar* c)
+{
+    c++;
+    while((*c & 0xC0) == 0x80)
+        c++;
+    return (gchar *)c;
+}
+
+/* Check if string "name" is a valid variable for given ParserState. It is the same code, used to get the value of variable in parserfunc.c. */
+static gboolean
+p_check_variable(ParserState* state, gchar* name)
+{
+    gint result = 0;
+
+    const gchar *c, *next;
+    gchar *buffer;
+    MPNumber temp;
+
+    if(!(state->get_variable))
+    {
+        return FALSE;
+    }
+
+    /* If defined, then get the variable */
+    if((*(state->get_variable))(state, name, &temp))
+    {
+        return TRUE;
+    }
+
+    /* If has more than one character then assume a multiplication of variables */
+    if(utf8_next_char(name)[0] != '\0')
+    {
+        result = 1;
+        buffer = (gchar*) malloc(sizeof(gchar) * strlen(name));
+        for(c = name; *c != '\0'; c = next)
+        {
+            next = utf8_next_char(c);
+            snprintf(buffer, next - c + 1, "%s", c);
+            if(!(*(state->get_variable))(state, buffer, &temp))
+            {
+                result = 0;
+                break;
+            }
+        }
+        free(buffer);
+    }
+    if(!result)
+    {
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static guint
+statement(ParserState* state)
+{
+    LexerToken* token;
+    LexerToken* token_old;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == T_VARIABLE)
+    {
+        token_old = token;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_ASSIGN)
+        {
+            /* VARIABLE = expression. */
+
+            node = p_create_node(state, token_old, p_make_precedence_p(state, P_NumberVariable), p_get_associativity(token_old), NULL, pf_none);
+            p_insert_into_tree(state, node);
+
+            node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_set_var);
+            p_insert_into_tree(state, node);
+
+            if(!expression(state))
+                return 0;
+            return 1;
+        }
+        else if(token->token_type == T_IN)
+        {
+            /* UNIT in UNIT. */
+            l_roll_back(state->lexer);
+            l_roll_back(state->lexer);
+            if(!unit(state))
+                return 0;
+            l_get_next_token(state->lexer);
+
+            node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_1);
+            p_insert_into_tree(state, node);
+
+            if(!unit(state))
+                return 0;
+            return 1;
+        }
+        else if(token->token_type == T_SUP_NUMBER)
+        {
+            token = l_get_next_token(state->lexer);
+            if(token->token_type == T_IN)
+            {
+                /* UNIT in UNIT */
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+                if(!unit(state))
+                    return 0;
+                l_get_next_token(state->lexer);
+
+                node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_1);
+                p_insert_into_tree(state, node);
+
+                if(!unit(state))
+                    return 0;
+                return 1;
+            }
+            else
+            {
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+                if(!expression(state))
+                    return 0;
+                return 1;
+            }
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+            l_roll_back(state->lexer);
+            if(!expression(state))
+                return 0;
+            return 1;
+        }
+    }
+    else if(token->token_type == T_NUMBER)
+    {
+        token_old = token;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_VARIABLE)
+        {
+            token = l_get_next_token(state->lexer);
+            if(token->token_type == T_IN)
+            {
+                /* NUMBER UNIT in UNIT */
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+
+                node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token), NULL, pf_constant);
+                p_insert_into_tree(state, node);
+
+                if(!unit(state))
+                    return 0;
+                token = l_get_next_token(state->lexer);
+
+                node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_number);
+                p_insert_into_tree(state, node);
+
+                if(!unit(state))
+                    return 0;
+                return 1;
+            }
+            else if(token->token_type == T_SUP_NUMBER)
+            {
+                token = l_get_next_token(state->lexer);
+                if(token->token_type == T_IN)
+                {
+                    /* NUMBER UNIT in UNIT */
+                    l_roll_back(state->lexer);
+                    l_roll_back(state->lexer);
+                    l_roll_back(state->lexer);
+
+                    node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token), NULL, pf_constant);
+                    p_insert_into_tree(state, node);
+
+                    if(!unit(state))
+                        return 0;
+                    token = l_get_next_token(state->lexer);
+
+                    node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_number);
+                    p_insert_into_tree(state, node);
+
+                    if(!unit(state))
+                        return 0;
+                    return 1;
+                }
+                else
+                {
+                    l_roll_back(state->lexer);
+                    l_roll_back(state->lexer);
+                    l_roll_back(state->lexer);
+                    l_roll_back(state->lexer);
+                    if(!expression(state))
+                        return 0;
+                    return 1;
+                }
+            }
+            else
+            {
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+                l_roll_back(state->lexer);
+                if(!expression(state))
+                    return 0;
+                return 1;
+            }
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+            l_roll_back(state->lexer);
+            if(!expression(state))
+                return 0;
+            return 1;
+        }
+    }
+    else
+    {
+        l_roll_back(state->lexer);
+        if(!expression(state))
+            return 0;
+        return 1;
+    }
+}
+
+static guint
+unit(ParserState* state)
+{
+    LexerToken* token;
+    LexerToken* token_old;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == T_VARIABLE)
+    {
+        token_old = token;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_SUP_NUMBER)
+        {
+            /* VARIABLE POWER */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), pf_make_unit(token_old->string, token->string), pf_none);
+            p_insert_into_tree(state, node);
+
+            return 1;
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+            /* VARIABLE */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), NULL, pf_none);
+            p_insert_into_tree(state, node);
+
+            return 1;
+        }
+    }
+    else
+    {
+        l_roll_back(state->lexer);
+        return 0;
+    }
+}
+
+static guint
+expression(ParserState* state)
+{
+    if(!expression_1(state))
+        return 0;
+    if(!expression_2(state))
+        return 0;
+    return 1;
+}
+
+static guint
+expression_1(ParserState* state)
+{
+    LexerToken* token;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == PL_EOS
+     ||token->token_type == T_ASSIGN)
+    {
+        l_roll_back(state->lexer);
+        return 0;
+    }
+    if(token->token_type == T_L_R_BRACKET)
+    {
+        state->depth_level++;
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_R_R_BRACKET)
+        {
+            state->depth_level--;
+            return 1;
+        }
+        else
+        //Expected ")" here...
+            return 0;
+    }
+    else if(token->token_type == T_L_S_BRACKET)
+    {
+        state->depth_level++;
+
+        /* Give round, preference of P_Unknown aka 0, to keep it on the top of expression. */
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_Unknown), p_get_associativity(token), NULL, pf_do_round);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_R_S_BRACKET)
+        {
+            state->depth_level--;
+            return 1;
+        }
+        else
+        //Expected "]" here...
+            return 0;
+    }
+    else if(token->token_type == T_L_C_BRACKET)
+    {
+        state->depth_level++;
+
+        /* Give fraction, preference of P_Unknown aka 0, to keep it on the top of expression. */
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_Unknown), p_get_associativity(token), NULL, pf_do_fraction);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_R_C_BRACKET)
+        {
+            state->depth_level--;
+            return 1;
+        }
+        else
+        //Expected "}" here...
+            return 0;
+    }
+    else if(token->token_type == T_ABS)
+    {
+        state->depth_level++;
+
+        /* Give abs, preference of P_Unknown aka 0, to keep it on the top of expression. */
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_Unknown), p_get_associativity(token), NULL, pf_do_abs);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_ABS)
+        {
+            state->depth_level--;
+            return 1;
+        }
+        else
+        //Expected "|" here...
+            return 0;
+    }
+    else if(token->token_type == T_NOT)
+    {
+        /* NOT expression */
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_Not), p_get_associativity(token), NULL, pf_do_not);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_NUMBER)
+    {
+        /* NUMBER */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_constant);
+        p_insert_into_tree(state, node);
+
+        token = l_get_next_token(state->lexer);
+        l_roll_back(state->lexer);
+
+        if(token->token_type == T_FUNCTION
+         ||token->token_type == T_VARIABLE
+         ||token->token_type == T_SUB_NUMBER
+         ||token->token_type == T_ROOT
+         ||token->token_type == T_ROOT_3
+         ||token->token_type == T_ROOT_4)
+        {
+            /* NUMBER variable. */
+
+            node = p_create_node(state, NULL, p_make_precedence_p(state, P_Multiply), p_get_associativity_p(P_Multiply), NULL, pf_do_multiply);
+            p_insert_into_tree(state, node);
+
+            if(!variable(state))
+                return 0;
+            else
+                return 1;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+    else if(token->token_type == T_L_FLOOR)
+    {
+        state->depth_level++;
+        /* Give floor, preference of P_Unknown aka 0, to keep it on the top of expression. */
+
+        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Unknown), p_get_associativity_p(P_Unknown), NULL, pf_do_floor);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_R_FLOOR)
+        {
+            state->depth_level--;
+            return 1;
+        }
+        else
+        //Expected â here...
+            return 0;
+    }
+    else if(token->token_type == T_L_CEILING)
+    {
+        state->depth_level++;
+        /* Give ceiling, preference of P_Unknown aka 0, to keep it on the top of expression. */
+
+        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Unknown), p_get_associativity_p(P_Unknown), NULL, pf_do_ceiling);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_R_CEILING)
+        {
+            state->depth_level--;
+            return 1;
+        }
+        else
+        //Expected â here...
+            return 0;
+    }
+    else if(token->token_type == T_SUBTRACT)
+    {
+        /* UnaryMinus expression */
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_UnaryMinus), p_get_associativity_p(P_UnaryMinus), NULL, pf_unary_minus);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_ADD)
+    {
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_NUMBER)
+        {
+            /* UnaryPlus expression */
+            /* Ignore T_ADD. It is not required. */
+
+            node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_constant);
+            p_insert_into_tree(state, node);
+            return 1;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+    else
+    {
+        l_roll_back(state->lexer);
+        if(!variable(state))
+            return 0;
+        else
+            return 1;
+    }
+}
+
+static guint
+expression_2(ParserState* state)
+{
+    LexerToken* token;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == T_L_R_BRACKET)
+    {
+        /* expression "(" expression ")" */
+
+        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Multiply), p_get_associativity_p(P_Multiply), NULL, pf_do_multiply);
+        p_insert_into_tree(state, node);
+
+        state->depth_level++;
+        if(!expression(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_R_R_BRACKET)
+        {
+            state->depth_level--;
+            if(!expression_2(state))
+                return 0;
+            return 1;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+    else if(token->token_type == T_POWER)
+    {
+        /* expression "^" expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_x_pow_y);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_SUP_NUMBER)
+    {
+        /* expression T_SUP_NUMBER */
+
+        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Power), p_get_associativity_p(P_Power), NULL, pf_do_x_pow_y_int);
+        p_insert_into_tree(state, node);
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_NumberVariable), p_get_associativity_p(P_NumberVariable), NULL, pf_none);
+        p_insert_into_tree(state, node);
+
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_NSUP_NUMBER)
+    {
+        /* expression T_NSUP_NUMBER */
+
+        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Power), p_get_associativity_p(P_Power), NULL, pf_do_x_pow_y_int);
+        p_insert_into_tree(state, node);
+
+        node = p_create_node(state, token, p_make_precedence_p(state, P_NumberVariable), p_get_associativity_p(P_NumberVariable), NULL, pf_none);
+        p_insert_into_tree(state, node);
+
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_FACTORIAL)
+    {
+        /* expression T_FACTORIAL */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_factorial);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_MULTIPLY)
+    {
+        /* expression T_MULTIPLY expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_multiply);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_PERCENTAGE)
+    {
+        /* expression % */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_percent);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_AND)
+    {
+        /* expression T_AND expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_and);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_OR)
+    {
+        /* expression T_OR expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_or);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_XOR)
+    {
+        /* expression T_XOR expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_xor);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_DIVIDE)
+    {
+        /* expression T_DIVIDE expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_divide);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_MOD)
+    {
+        /* expression T_MOD expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_mod);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_ADD)
+    {
+        /* expression T_ADD expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_add);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_PERCENTAGE)
+        {
+            //FIXME: This condition needs to be verified for all cases.. :(
+            if(node->right->precedence > P_Percentage)
+            {
+                node->precedence = P_Percentage;
+                node->evaluate = pf_do_add_percent;
+                return 1;
+            }
+            else
+            {
+                /* Assume '%' to be part of 'expression T_PERCENTAGE' statement. */
+                l_roll_back(state->lexer);
+                if(!expression_2(state))
+                    return 1;
+            }
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+        }
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_SUBTRACT)
+    {
+        /* expression T_SUBTRACT expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_subtract);
+        p_insert_into_tree(state, node);
+
+        if(!expression_1(state))
+            return 0;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_PERCENTAGE)
+        {
+            //FIXME: This condition needs to be verified for all cases.. :(
+            if(node->right->precedence > P_Percentage)
+            {
+                node->precedence = P_Percentage;
+                node->evaluate = pf_do_subtract_percent;
+                return 1;
+            }
+            else
+            {
+                /* Assume '%' to be part of 'expression T_PERCENTAGE' statement. */
+                l_roll_back(state->lexer);
+                if(!expression_2 (state))
+                    return 1;
+            }
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+        }
+        if(!expression_2(state))
+            return 0;
+        return 1;
+    }
+    else
+    {
+        l_roll_back(state->lexer);
+        return 1;
+    }
+}
+
+static guint
+variable(ParserState* state)
+{
+    LexerToken* token;
+    LexerToken* token_old;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == T_FUNCTION)
+    {
+        token_old = token;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_SUP_NUMBER)
+        {
+            /* FUNCTION SUP_NUMBER expression */
+            /* Pass power as void * value. That will be taken care in pf_apply_func_with_powre. */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), token, pf_apply_func_with_power);
+            p_insert_into_tree_unary(state, node);
+
+            if(!expression(state))
+                return 0;
+            return 1;
+        }
+        else if(token->token_type == T_NSUP_NUMBER)
+        {
+            /* FUNCTION NSUP_NUMBER expression */
+            /* Pass power as void * value. That will be taken care in pf_apply_func_with_npowre. */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), token, pf_apply_func_with_npower);
+            p_insert_into_tree_unary(state, node);
+
+            if(!expression(state))
+                return 0;
+            return 1;
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+            /* FUNCTION expression */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), NULL, pf_apply_func);
+            p_insert_into_tree_unary(state, node);
+
+            if(!expression(state))
+                return 0;
+            return 1;
+        }
+    }
+    else if(token->token_type == T_SUB_NUMBER)
+    {
+        token_old = token;
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_ROOT)
+        {
+            /* SUB_NUM ROOT expression */
+            /* Pass SUB_NUM as void* value in node. pf_do_nth_root will take care of it. */
+
+            node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), token_old, pf_do_nth_root);
+            p_insert_into_tree_unary(state, node);
+
+            if(!expression (state))
+                return 0;
+            return 1;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+    else if(token->token_type == T_ROOT)
+    {
+        /* ROOT expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_sqrt);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_ROOT_3)
+    {
+        /* ROOT_3 expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_root_3);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_ROOT_4)
+    {
+        /* ROOT_4 expression */
+
+        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_root_4);
+        p_insert_into_tree_unary(state, node);
+
+        if(!expression(state))
+            return 0;
+        return 1;
+    }
+    else if(token->token_type == T_VARIABLE)
+    {
+        l_roll_back(state->lexer);
+        //TODO: unknown function ERROR for (T_VARIABLE T_SUP_NUMBER expression).
+        if(!term(state))
+            return 0;
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+static guint
+term(ParserState* state)
+{
+    LexerToken* token;
+    LexerToken* token_old;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    if(token->token_type == T_VARIABLE)
+    {
+        token_old = token;
+        /* Check if the token is a valid variable or not. */
+        if(!p_check_variable(state, token->string))
+        {
+            set_error(state, PARSER_ERR_UNKNOWN_VARIABLE, token->string);
+            return 0;
+        }
+        token = l_get_next_token(state->lexer);
+        if(token->token_type == T_SUP_NUMBER)
+        {
+            /* VARIABLE SUP_NUMBER */
+            /* Pass power as void* value. pf_get_variable_with_power will take care of it. */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), token, pf_get_variable_with_power);
+            p_insert_into_tree(state, node);
+
+        }
+        else
+        {
+            l_roll_back(state->lexer);
+            /* VARIABLE */
+
+            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), NULL, pf_get_variable);
+            p_insert_into_tree(state, node);
+
+        }
+        if(!term_2(state))
+            return 0;
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+static guint
+term_2(ParserState* state)
+{
+    LexerToken* token;
+    ParseNode* node;
+    token = l_get_next_token(state->lexer);
+    l_roll_back(state->lexer);
+    if(token->token_type == PL_EOS
+     ||token->token_type == T_ASSIGN)
+    {
+        return 1;
+    }
+    if(token->token_type == T_VARIABLE)
+    {
+        /* Insert multiply in between two distinct (variable). */
+
+        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Multiply), p_get_associativity_p(P_Multiply), NULL, pf_do_multiply);
+        p_insert_into_tree(state, node);
+
+        if(!term(state))
+            return 0;
+        return 1;
+    }
+    else
+    {
+        return 1;
+    }
+}
diff --git a/src/parser.h b/src/parser.h
new file mode 100644
index 0000000..3efaa03
--- /dev/null
+++ b/src/parser.h
@@ -0,0 +1,79 @@
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <lexer.h>
+
+#include "mp-equation.h"
+#include "mp.h"
+
+/* Operator Associativity. */
+typedef enum
+{
+    LEFT_ASSOCIATIVE,
+    RIGHT_ASSOCIATIVE
+} Associativity;
+
+/* Operator Precedence. */
+typedef enum
+{
+    P_Unknown = 0,
+    P_AddSubtract=1,
+    P_Multiply=2,
+    P_Mod=3,
+    P_Divide=4,
+    P_Not=5,
+    P_Root=6,
+    P_Function=7,
+    P_Boolean=8,
+    P_Percentage=9,
+    /* UnaryMinus and Power must have same precedence. */
+    P_UnaryMinus=10,
+    P_Power=10,
+    P_Factorial=11,
+    P_NumberVariable=12,
+    /* P_Depth should be always at the bottom. It stops node jumping off the current depth level. */
+    P_Depth
+} Precedence;
+
+/* ParseNode structure for parse tree. */
+typedef struct parse_node
+{
+    struct parse_node *parent;
+    struct parse_node *left, *right;
+    LexerToken *token;
+    guint precedence;
+    Associativity associativity;
+    void* value;
+    struct parser_state* state;
+    void* (*evaluate) (struct parse_node* self);
+} ParseNode;
+
+/* ParserState structure. Stores parser state. */
+typedef struct parser_state
+{
+    ParseNode *root;
+    ParseNode *right_most;
+    LexerState *lexer;
+    guint depth_level;
+    MPEquationOptions *options;
+    int error;
+    char *error_token;
+    MPNumber ret;
+    int (*variable_is_defined)(struct parser_state *state, const char *name);
+    int (*get_variable)(struct parser_state *state, const char *name, MPNumber *z);
+    void (*set_variable)(struct parser_state *state, const char *name, const MPNumber *x);
+    int (*function_is_defined)(struct parser_state *state, const char *name);
+    int (*get_function)(struct parser_state *state, const char *name, const MPNumber *x, MPNumber *z);
+    int (*convert)(struct parser_state *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z);
+} ParserState;
+
+/* Create ParserState object. */
+ParserState* p_create_parser(const gchar*, MPEquationOptions*);
+
+/* Destroy ParserState object. */
+void p_destroy_parser(ParserState*);
+
+/* Parse string from ParserState. */
+guint p_parse(ParserState*);
+
+#endif /* PARSER_H */
diff --git a/src/parserfunc.c b/src/parserfunc.c
new file mode 100644
index 0000000..edd34f6
--- /dev/null
+++ b/src/parserfunc.c
@@ -0,0 +1,967 @@
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "parser.h"
+#include "parserfunc.h"
+
+/* Register error variables in ParserState structure. */
+void
+set_error(ParserState* state, gint errorno, const gchar *token)
+{
+    state->error = errorno;
+    if(token)
+        state->error_token = strdup(token);
+}
+
+/* Unused function pointer. This won't be called anytime. */
+void*
+pf_none(ParseNode* self)
+{
+    return NULL;
+}
+
+/* Set variable. */
+void*
+pf_set_var(ParseNode* self)
+{
+    MPNumber* val;
+    val = (MPNumber *) (*(self->right->evaluate))(self->right);
+    if(!val || !(self->state->set_variable))
+    {
+        if(val)
+            free(val);
+        return NULL;
+    }
+    (*(self->state->set_variable))(self->state, self->left->token->string, val);
+    return val;
+}
+
+/* Converts Number from one unit to other. */
+void*
+pf_convert_number(ParseNode* self)
+{
+    gchar* from;
+    gchar* to;
+    gint free_from = 0;
+    gint free_to = 0;
+    MPNumber tmp;
+    MPNumber* ans;
+    ans = (MPNumber *) malloc(sizeof(MPNumber));
+    if(self->left->value)
+    {
+        from = (gchar*) self->left->value;
+        free_from = 1;
+    }
+    else
+        from = self->left->token->string;
+    if(self->right->value)
+    {
+        to = (gchar*) self->right->value;
+        free_to = 1;
+    }
+    else
+        to = self->right->token->string;
+
+    if(mp_set_from_string(self->left->left->token->string, self->state->options->base, &tmp) != 0)
+    {
+        free(ans);
+        ans = NULL;
+        goto END_PF_CONVERT_NUMBER;
+    }
+    if(!(self->state->convert))
+    {
+        free(ans);
+        ans = NULL;
+        goto END_PF_CONVERT_NUMBER;
+    }
+    if(!(*(self->state->convert))(self->state, &tmp, from, to, ans))
+    {
+        set_error(self->state, PARSER_ERR_UNKNOWN_CONVERSION, NULL);
+        free(ans);
+        ans = NULL;
+    }
+END_PF_CONVERT_NUMBER:
+    if(free_from)
+    {
+        g_free(self->left->value);
+        self->left->value = NULL;
+    }
+    if(free_to)
+    {
+        g_free(self->right->value);
+        self->right->value = NULL;
+    }
+    return ans;
+}
+
+/* Conversion rate. */
+void*
+pf_convert_1(ParseNode* self )
+{
+    gchar* from;
+    gchar* to;
+    gint free_from = 0;
+    gint free_to = 0;
+    MPNumber tmp;
+    MPNumber* ans;
+    ans = (MPNumber *) malloc(sizeof(MPNumber));
+    if(self->left->value)
+    {
+        from = (gchar*) self->left->value;
+        free_from = 1;
+    }
+    else
+        from = self->left->token->string;
+    if(self->right->value)
+    {
+        to = (gchar*) self->right->value;
+        free_to = 1;
+    }
+    else
+        to = self->right->token->string;
+    mp_set_from_integer(1, &tmp);
+    if(!(self->state->convert))
+    {
+        free(ans);
+        return NULL;
+    }
+    if(!(*(self->state->convert))(self->state, &tmp, from, to, ans))
+    {
+        set_error(self->state, PARSER_ERR_UNKNOWN_CONVERSION, NULL);
+        free(ans);
+        ans = NULL;
+    }
+    if(free_from)
+    {
+        g_free(self->left->value);
+        self->left->value = NULL;
+    }
+    if(free_to)
+    {
+        g_free(self->right->value);
+        self->right->value = NULL;
+    }
+    return ans;
+}
+
+/* Join source unit and power. */
+gchar*
+pf_make_unit(gchar* source, gchar* power)
+{
+    return g_strjoin(NULL, source, power, NULL);
+}
+
+static gchar *
+utf8_next_char(const gchar *c)
+{
+    c++;
+    while((*c & 0xC0) == 0x80)
+        c++;
+    return(gchar *) c;
+}
+
+/* Get value of variable. */
+void*
+pf_get_variable(ParseNode* self)
+{
+    gint result = 0;
+
+    const gchar *c, *next;
+    gchar *buffer;
+    MPNumber value;
+
+    MPNumber t;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+
+    if(!(self->state->get_variable))
+    {
+        free(ans);
+        return NULL;
+    }
+
+    /* If defined, then get the variable */
+    if((*(self->state->get_variable))(self->state, self->token->string, ans))
+    {
+        return ans;
+    }
+
+    /* If has more than one character then assume a multiplication of variables */
+    if(utf8_next_char(self->token->string)[0] != '\0')
+    {
+        result = 1;
+        buffer = (gchar*) malloc(sizeof(gchar) * strlen(self->token->string));
+        mp_set_from_integer(1, &value);
+        for(c = self->token->string; *c != '\0'; c = next)
+        {
+            next = utf8_next_char(c);
+            snprintf(buffer, next - c + 1, "%s", c);
+            if(!(*(self->state->get_variable))(self->state, buffer, &t))
+            {
+                result = 0;
+                break;
+            }
+            mp_multiply(&value, &t, &value);
+        }
+        free(buffer);
+        if(result)
+            mp_set_from_mp(&value, ans);
+    }
+    if(!result)
+    {
+        free (ans);
+        ans = NULL;
+        set_error(self->state, PARSER_ERR_UNKNOWN_VARIABLE, self->token->string);
+    }
+    return ans;
+}
+
+/* Get value of variable with power. */
+void*
+pf_get_variable_with_power(ParseNode* self)
+{
+    gint result = 0;
+    gint pow;
+
+    const gchar *c, *next;
+    gchar *buffer;
+    MPNumber value;
+
+    MPNumber t;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    pow = super_atoi(((LexerToken*) self->value)->string);
+
+    /* No need to free the memory. It is allocated and freed somewhere else. */
+    self->value = NULL;
+
+    if(!(self->state->get_variable))
+    {
+        free(ans);
+        return NULL;
+    }
+
+    /* If defined, then get the variable */
+    if((*(self->state->get_variable))(self->state, self->token->string, ans))
+    {
+        mp_xpowy_integer(ans, pow, ans);
+        return ans;
+    }
+
+    /* If has more than one character then assume a multiplication of variables */
+    if(utf8_next_char(self->token->string)[0] != '\0')
+    {
+        result = 1;
+        buffer = (gchar*) malloc(sizeof(gchar) * strlen(self->token->string));
+        mp_set_from_integer(1, &value);
+        for(c = self->token->string; *c != '\0'; c = next)
+        {
+            next = utf8_next_char(c);
+            snprintf(buffer, next - c + 1, "%s", c);
+            if(!(*(self->state->get_variable))(self->state, buffer, &t))
+            {
+                result = 0;
+                break;
+            }
+
+            /* If last term do power */
+            if(*next == '\0')
+                mp_xpowy_integer(&t, pow, &t);
+            mp_multiply(&value, &t, &value);
+        }
+        free(buffer);
+        if(result)
+            mp_set_from_mp(&value, ans);
+    }
+    if(!result)
+    {
+        free(ans);
+        ans = NULL;
+        set_error(self->state, PARSER_ERR_UNKNOWN_VARIABLE, self->token->string);
+    }
+    return ans;
+}
+
+/* Apply function on child. */
+void*
+pf_apply_func(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!(self->state->get_function))
+    {
+        free(val);
+        free(ans);
+        return NULL;
+    }
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    if(!(*(self->state->get_function))(self->state, self->token->string, val, ans))
+    {
+        free(val);
+        free(ans);
+        set_error(self->state, PARSER_ERR_UNKNOWN_FUNCTION, self->token->string);
+        return NULL;
+    }
+    free(val);
+    return ans;
+}
+
+/* Apply function with +ve power. */
+void*
+pf_apply_func_with_power(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* tmp;
+    MPNumber* ans;
+    gint pow;
+    tmp = (MPNumber*) malloc(sizeof(MPNumber));
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!(self->state->get_function))
+    {
+        free(tmp);
+        free(ans);
+        free(val);
+        self->value = NULL;
+        return NULL;
+    }
+    if(!val)
+    {
+        free(tmp);
+        free(ans);
+        self->value = NULL;
+        return NULL;
+    }
+    if(!(*(self->state->get_function))(self->state, self->token->string, val, tmp))
+    {
+        free(tmp);
+        free(ans);
+        free(val);
+        self->value = NULL;
+        set_error(self->state, PARSER_ERR_UNKNOWN_FUNCTION, self->token->string);
+        return NULL;
+    }
+    pow = super_atoi(((LexerToken*) self->value)->string);
+    mp_xpowy_integer(tmp, pow, ans);
+    free(val);
+    free(tmp);
+    self->value = NULL;
+    return ans;
+}
+
+/* Apply function with -ve power. */
+void*
+pf_apply_func_with_npower(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* tmp;
+    MPNumber* ans;
+    gint pow;
+    gchar* inv_name;
+    inv_name = (gchar*) malloc(sizeof(gchar) * strlen(self->token->string) + strlen("âÂ") + 1);
+    strcpy(inv_name, self->token->string);
+    strcat(inv_name, "âÂ");
+    tmp = (MPNumber*) malloc(sizeof(MPNumber));
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(tmp);
+        free(inv_name);
+        free(ans);
+        self->value = NULL;
+        return NULL;
+    }
+    if(!(self->state->get_function))
+    {
+        free(tmp);
+        free(ans);
+        free(inv_name);
+        self->value = NULL;
+        return NULL;
+    }
+    if(!(*(self->state->get_function))(self->state, inv_name, val, tmp))
+    {
+        free(tmp);
+        free(ans);
+        free(val);
+        free(inv_name);
+        self->value = NULL;
+        set_error(self->state, PARSER_ERR_UNKNOWN_FUNCTION, self->token->string);
+        return NULL;
+    }
+    pow = super_atoi(((LexerToken*) self->value)->string);
+    mp_xpowy_integer(tmp, -pow, ans);
+    free(val);
+    free(tmp);
+    free(inv_name);
+    self->value = NULL;
+    return ans;
+}
+
+/* Find nth root of child. */
+void*
+pf_do_nth_root(ParseNode* self)
+{
+    MPNumber* val;
+    gint pow;
+    MPNumber* ans;
+    pow = sub_atoi(((LexerToken*) self->value)->string);
+    self->value = NULL;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_root(val, pow, ans);
+    free(val);
+    return ans;
+}
+
+/* Find sqrt of child. */
+void*
+pf_do_sqrt(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_sqrt(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Find 3rd root of child. */
+void*
+pf_do_root_3(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_root(val, 3, ans);
+    free(val);
+    return ans;
+}
+
+/* Find 4th root of child. */
+void*
+pf_do_root_4(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_root(val, 4, ans);
+    free(val);
+    return ans;
+}
+
+/* Apply floor function. */
+void*
+pf_do_floor(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_floor(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Apply ceiling function. */
+void* pf_do_ceiling (ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_ceiling(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Round off. */
+void*
+pf_do_round(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_round(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Fraction. */
+void*
+pf_do_fraction(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_fractional_part(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Absolute value. */
+void*
+pf_do_abs(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_abs(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Find x^y for x and y being MPNumber. */
+void*
+pf_do_x_pow_y(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* pow;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->left->evaluate))(self->left);
+    pow = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val || !pow)
+    {
+        if(val)
+            free(val);
+        if(pow)
+            free(pow);
+        free(ans);
+        return NULL;
+    }
+    mp_xpowy(val, pow, ans);
+    free(val);
+    free(pow);
+    return ans;
+}
+
+/* Find x^y for MPNumber x and integer y. */
+void*
+pf_do_x_pow_y_int(ParseNode* self)
+{
+    MPNumber* val;
+    gint pow;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->left->evaluate))(self->left);
+    pow = super_atoi(self->right->token->string);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_xpowy_integer(val, pow, ans);
+    free(val);
+    return ans;
+}
+
+/* Find factorial. */
+void*
+pf_do_factorial(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_factorial(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Apply unary minus. */
+void*
+pf_unary_minus(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_invert_sign(val, ans);
+    free(val);
+    return ans;
+}
+
+/* Divide. */
+void*
+pf_do_divide(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_divide(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* Modulus. */
+void*
+pf_do_mod(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_modulus_divide(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* Multiply two numbers. */
+void*
+pf_do_multiply(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_multiply(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* Subtract two numbers. */
+void*
+pf_do_subtract(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free (right);
+        free(ans);
+        return NULL;
+    }
+    mp_subtract(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* Add two numbers. */
+void*
+pf_do_add(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_add(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/*Add (x) Percentage to value. */
+void*
+pf_do_add_percent(ParseNode* self)
+{
+    MPNumber* ans;
+    MPNumber* val;
+    MPNumber* per;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->left->evaluate))(self->left);
+    per = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val || !per)
+    {
+        if(val)
+            free(val);
+        if(per)
+            free(per);
+        free(ans);
+        return NULL;
+    }
+    mp_add_integer(per, 100, per);
+    mp_divide_integer(per, 100, per);
+    mp_multiply(val, per, ans);
+    free(val);
+    free(per);
+    return ans;
+}
+
+/* Subtract (x) Percentage to value. */
+void*
+pf_do_subtract_percent(ParseNode* self)
+{
+    MPNumber* ans;
+    MPNumber* val;
+    MPNumber* per;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->left->evaluate))(self->left);
+    per = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val || !per)
+    {
+        if(val)
+            free(val);
+        if(per)
+            free(per);
+        free(ans);
+        return NULL;
+    }
+    mp_add_integer(per, -100, per);
+    mp_divide_integer(per, -100, per);
+    mp_multiply(val, per, ans);
+    free(val);
+    free(per);
+    return ans;
+}
+
+/* Converts a constant into percentage. */
+void*
+pf_do_percent(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    mp_divide_integer(val, 100, ans);
+    free(val);
+    return ans;
+}
+
+/* NOT. */
+void*
+pf_do_not(ParseNode* self)
+{
+    MPNumber* val;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    val = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!val)
+    {
+        free(ans);
+        return NULL;
+    }
+    if(!mp_is_overflow(val, self->state->options->wordlen))
+    {
+        set_error(self->state, PARSER_ERR_OVERFLOW, NULL);
+        free(ans);
+        ans = NULL;
+    }
+    mp_not(val, self->state->options->wordlen, ans);
+    free(val);
+    return ans;
+}
+
+/* AND. */
+void*
+pf_do_and(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_and(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* OR. */
+void*
+pf_do_or(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_or(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* XOR. */
+void*
+pf_do_xor(ParseNode* self)
+{
+    MPNumber* left;
+    MPNumber* right;
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    left = (MPNumber*) (*(self->left->evaluate))(self->left);
+    right = (MPNumber*) (*(self->right->evaluate))(self->right);
+    if(!left || !right)
+    {
+        if(left)
+            free(left);
+        if(right)
+            free(right);
+        free(ans);
+        return NULL;
+    }
+    mp_xor(left, right, ans);
+    free(left);
+    free(right);
+    return ans;
+}
+
+/* Constant value. Convert into MPNumber and return. */
+void*
+pf_constant(ParseNode* self)
+{
+    MPNumber* ans;
+    ans = (MPNumber*) malloc(sizeof(MPNumber));
+    if(mp_set_from_string(self->token->string, self->state->options->base, ans) != 0)
+    {
+        /* This should never happen, as l_check_if_number() has already passed the string once. */
+        /* If the code reaches this point, something is really wrong. X( */
+        free(ans);
+        set_error(self->state, PARSER_ERR_INVALID, self->token->string);
+        return NULL;
+    }
+    return ans;
+}
+
diff --git a/src/parserfunc.h b/src/parserfunc.h
new file mode 100644
index 0000000..cf049b0
--- /dev/null
+++ b/src/parserfunc.h
@@ -0,0 +1,80 @@
+#ifndef PAESERFUNC_H
+#define PARSERFUNC_H
+
+#include "parser.h"
+
+void set_error(ParserState*, gint, const gchar*);
+
+void* pf_none(ParseNode*);
+
+void* pf_set_var(ParseNode*);
+
+void* pf_convert_number(ParseNode*);
+
+void* pf_convert_1(ParseNode*);
+
+gchar* pf_make_unit(gchar* source, gchar* power);
+
+void* pf_get_variable(ParseNode*);
+
+void* pf_get_variable_with_power(ParseNode*);
+
+void* pf_apply_func(ParseNode*);
+
+void* pf_apply_func_with_power(ParseNode*);
+
+void* pf_apply_func_with_npower(ParseNode*);
+
+void* pf_do_nth_root(ParseNode*);
+
+void* pf_do_sqrt(ParseNode*);
+
+void* pf_do_root_3(ParseNode*);
+
+void* pf_do_root_4(ParseNode*);
+
+void* pf_do_floor(ParseNode*);
+
+void* pf_do_ceiling(ParseNode*);
+
+void* pf_do_round(ParseNode*);
+
+void* pf_do_fraction(ParseNode*);
+
+void* pf_do_abs(ParseNode*);
+
+void* pf_do_x_pow_y(ParseNode*);
+
+void* pf_do_x_pow_y_int(ParseNode*);
+
+void* pf_do_factorial(ParseNode*);
+
+void* pf_unary_minus(ParseNode*);
+
+void* pf_do_divide(ParseNode*);
+
+void* pf_do_mod(ParseNode*);
+
+void* pf_do_multiply(ParseNode*);
+
+void* pf_do_subtract(ParseNode*);
+
+void* pf_do_add(ParseNode*);
+
+void* pf_do_add_percent(ParseNode*);
+
+void* pf_do_subtract_percent(ParseNode*);
+
+void* pf_do_percent(ParseNode*);
+
+void* pf_do_not(ParseNode*);
+
+void* pf_do_and(ParseNode*);
+
+void* pf_do_or(ParseNode*);
+
+void* pf_do_xor(ParseNode*);
+
+void* pf_constant(ParseNode*);
+
+#endif /* PARSERFUNC_H */
diff --git a/src/prelexer.c b/src/prelexer.c
new file mode 100644
index 0000000..a22dd0d
--- /dev/null
+++ b/src/prelexer.c
@@ -0,0 +1,214 @@
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <assert.h>
+
+#include "prelexer.h"
+
+/* Creates a scanner state which will be useful for accessing the lexer later. */
+PreLexerState*
+pl_create_scanner(const gchar* input)
+{
+    PreLexerState* state;
+    assert(input != NULL);
+    assert(g_utf8_validate(input, -1, NULL));
+    state = (PreLexerState *) malloc(sizeof(PreLexerState));
+    assert(state != NULL);
+    state->stream = g_strdup(input);
+    state->length = strlen(state->stream);    /* Can't find a GLib replacement of strlen. The mailing list discussion says, it is not implemented because strlen is perfectly capable. :) */
+    state->next_index = 0;
+    state->mark_index = 0;
+    return state;
+}
+
+/* Destroy and free memory used by LexerState object. */
+void
+pl_destroy_scanner(PreLexerState* state)
+{
+    free(state->stream);
+    free(state);
+}
+
+/* Roll back last scanned unichar. */
+void
+pl_roll_back(PreLexerState* state)
+{
+    gchar* tmp;
+    tmp = g_utf8_find_prev_char(state->stream, state->stream + state->next_index);
+    if(tmp == NULL)
+        /* Already at the beginning of the stram. Reset index. */
+        state->next_index = 0;
+    else
+        state->next_index = tmp - state->stream;
+}
+
+/* Get validated gunichar from input stream. */
+gunichar
+pl_get_next_gunichar(PreLexerState* state)
+{
+    gunichar ret;
+    if(state->next_index >= state->length)
+    {
+        /* To prevent scanning last letter multiple times, when a single unconditional rollback is used. */
+        if(state->next_index == state->length)
+            state->next_index++;
+        return 0;
+    }
+    ret = g_utf8_get_char_validated(state->stream + state->next_index, -1);
+    state->next_index = g_utf8_next_char(state->stream + state->next_index) - state->stream;
+    return ret;
+}
+
+/* Set marker index. To be used for highlighting and error reporting. */
+void
+pl_set_marker(PreLexerState* state)
+{
+    state->mark_index = state->next_index;
+}
+
+/* Get marked substring. To be used for error reporting. */
+gchar*
+pl_get_marked_substring(const PreLexerState* state)
+{
+    return g_strndup(state->stream + state->mark_index, state->next_index - state->mark_index);
+}
+
+/* Compares a list of strings with given unichar. To be used by pl_get_next_token() only. */
+static gboolean
+pl_compare_all(const gunichar ch, const gint count, gchar *arr[])
+{
+    gint l;
+    for(l = 0; l < count; l++)
+    {
+        if(ch == g_utf8_get_char_validated(arr[l], -1))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+/* Pre-Lexer tokanizer. To be called only by Lexer. */
+LexerTokenType
+pl_get_next_token(PreLexerState* state)
+{
+    gunichar ch = pl_get_next_gunichar(state);
+    if(pl_compare_all(ch, 2, (gchar*[]){",","."}))
+        return PL_DECIMAL;
+
+    if(g_unichar_isdigit(ch) || pl_compare_all(ch, 10, (gchar*[]){"ã","ã","ã","ã","ã","ã","ã","ã","ã","ã"}))
+        return PL_DIGIT;    /* 0-9 */
+
+    if(g_unichar_isxdigit(ch))
+        return PL_HEX;        /* This is supposed to report just the A-F. */
+
+    if(pl_compare_all(ch, 10, (gchar*[]){"â","Â","Â","Â","â","â","â","â","â","â"}))
+        return PL_SUPER_DIGIT;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return PL_SUPER_MINUS;
+
+    if(pl_compare_all(ch, 10, (gchar*[]){"â","â","â","â","â","â","â","â","â","â"}))
+        return PL_SUB_DIGIT;
+
+    if(pl_compare_all(ch, 15, (gchar*[]){"Â","â","â","Â","Â","â","â","â","â","â","â","â","â","â","â"}))
+        return PL_FRACTION;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"Â"}))
+        return PL_DEGREE;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"'"}))
+        return PL_MINUTE;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"\""}))
+        return PL_SECOND;
+
+    if(g_unichar_isalpha(ch))
+        return PL_LETTER;    /* All alphabets excluding A-F. [a-fA-F] are reported as PL_HEX. */
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_AND;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_OR;
+
+    if(pl_compare_all(ch, 2, (gchar*[]){"â","â"}))
+        return T_XOR;
+
+    if(pl_compare_all(ch, 2, (gchar*[]){"Â","~"}))
+        return T_NOT;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"+"}))
+        return T_ADD;
+
+    if(pl_compare_all(ch, 2, (gchar*[]){"-","â"}))
+        return T_SUBTRACT;
+
+    if(pl_compare_all(ch, 2, (gchar*[]){"*","Ã"}))
+        return T_MULTIPLY;
+
+    if(pl_compare_all(ch, 3, (gchar*[]){"/","â","Ã"}))
+        return T_DIVIDE;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_L_FLOOR;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_R_FLOOR;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_L_CEILING;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_R_CEILING;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_ROOT;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_ROOT_3;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"â"}))
+        return T_ROOT_4;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"="}))
+        return T_ASSIGN;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"("}))
+        return T_L_R_BRACKET;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){")"}))
+        return T_R_R_BRACKET;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"["}))
+        return T_L_S_BRACKET;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"]"}))
+        return T_R_S_BRACKET;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"{"}))
+        return T_L_C_BRACKET;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"}"}))
+        return T_R_C_BRACKET;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"|"}))
+        return T_ABS;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"^"}))
+        return T_POWER;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"!"}))
+        return T_FACTORIAL;
+
+    if(pl_compare_all(ch, 1, (gchar*[]){"%"}))
+        return T_PERCENTAGE;
+
+    if(pl_compare_all(ch, 4, (gchar*[]){" ","\r","\t","\n"}))
+    /* Gotta ignore'Em all!!! ;) */
+        return PL_SKIP;
+
+    if(ch == 0)
+        return PL_EOS;
+
+    /* There is no spoon. */
+    return T_UNKNOWN;
+}
diff --git a/src/prelexer.h b/src/prelexer.h
new file mode 100644
index 0000000..b27998f
--- /dev/null
+++ b/src/prelexer.h
@@ -0,0 +1,93 @@
+#ifndef PRE_LEXER_H
+#define PRE_LEXER_H
+
+#include <glib.h>
+
+/* Structure to store lexer state. */
+typedef struct
+{
+    gchar* stream;		/* Pointer to the local copy of input string. */
+    guint length;		/* Length of input string; stored to reduce calls to strlen(). */
+    guint next_index;		/* Index of next (to be read) character from input. */
+    guint mark_index;		/* Location, last marked. Useful for getting substrings as part of highlighting */
+} PreLexerState;
+
+/* Enum for tokens generated by pre-lexer and lexer. */
+typedef enum
+{
+    T_UNKNOWN=0,		//Unknown
+
+    /* These are all Pre-Lexer tokens, returned by pre-lexer */
+    PL_DECIMAL,			//Decimal saperator
+    PL_DIGIT,			//Decimal digit
+    PL_HEX,			//A-F of Hex digits
+    PL_SUPER_DIGIT,		//Super digits
+    PL_SUPER_MINUS,		//Super minus
+    PL_SUB_DIGIT,		//Sub digits
+    PL_FRACTION,		//Fractions
+    PL_DEGREE,			//Degree
+    PL_MINUTE,			//Minutes
+    PL_SECOND,		//10	//Seconds
+    PL_LETTER,			//Alphabets
+    PL_EOS,			//End of stream. Yay!!
+    PL_SKIP,			//Skip this symbol (whitespace or newline).
+
+    /* These are all tokens, returned by Lexer. */
+    T_ADD,			//Plus
+    T_SUBTRACT,			//Minus
+    T_MULTIPLY,			//Multiply
+    T_DIVIDE,			//Divide
+    T_MOD,			//Modulus
+    T_L_FLOOR,			//Floor ( Left )
+    T_R_FLOOR,		//20	//Floor ( Right )
+    T_L_CEILING,		//Ceiling ( Left )
+    T_R_CEILING,		//Ceiling ( Right )
+    T_ROOT,			//Square root
+    T_ROOT_3,			//Cube root
+    T_ROOT_4,			//Fourth root
+    T_NOT,			//Bitwise NOT
+    T_AND,			//Bitwise AND
+    T_OR,			//Bitwise OR
+    T_XOR,			//Bitwise XOR
+    T_IN,		//30	//IN ( for converter )
+    T_NUMBER,			//Number
+    T_SUP_NUMBER,		//Super Number
+    T_NSUP_NUMBER,		//Negative Super Number
+    T_SUB_NUMBER,		//Sub Number
+    T_FUNCTION,			//Function
+    T_VARIABLE,			//Variable name
+    T_ASSIGN,			//=
+    T_L_R_BRACKET,	//40	//(
+    T_R_R_BRACKET,		//)
+    T_L_S_BRACKET,		//[
+    T_R_S_BRACKET,		//]
+    T_L_C_BRACKET,		//{
+    T_R_C_BRACKET,		//}
+    T_ABS,			//|
+    T_POWER,			//^
+    T_FACTORIAL,		//!
+    T_PERCENTAGE	//49	//%
+} LexerTokenType;
+
+/* Creates a scanner state. Useful when multiple scanners are in action. */
+PreLexerState* pl_create_scanner(const gchar*);
+
+/* Destroy and free memory used by LexerState object. */
+void pl_destroy_scanner(PreLexerState*);
+
+/* Roll back last scanned unichar. */
+void pl_roll_back(PreLexerState*);
+
+/* Get validated gunichar from input stream. */
+gunichar pl_get_next_gunichar(PreLexerState*);
+
+/* Set marker index. To be used for highlighting and error reporting. */
+void pl_set_marker(PreLexerState*);
+
+/* Get marked substring. To be used for error reporting. */
+gchar* pl_get_marked_substring(const PreLexerState*);
+
+/* Get next Pre-Lexer token from stream. */
+LexerTokenType pl_get_next_token(PreLexerState*);
+
+#endif /* PRE_LEXER_H */
diff --git a/src/test-mp-equation.c b/src/test-mp-equation.c
index 3a60acb..95bb4a8 100644
--- a/src/test-mp-equation.c
+++ b/src/test-mp-equation.c
@@ -398,7 +398,7 @@ test_equations()
     test("2^1", "2", 0);
     test("2^2", "4", 0);
     test("2âÂ", "0.5", 0);
-    //test("2â", "", PARSER_ERR_MP); // FIXME: Maybe an error in bison?
+    test("2â", "", PARSER_ERR_MP);
     test("2^â1", "0.5", 0);
     test("2^(â1)", "0.5", 0);
     test("xâÂ", "0.5", 0);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]