~registry/gcalctool/trunk

« back to all changes in this revision

Viewing changes to src/parser.c

  • Committer: Robert Ancell
  • Date: 2012-10-14 03:31:40 UTC
  • Revision ID: git-v1:12ba2c81b0a81bb3ac776d1034a3c41b3173196a
Port to Vala

https://bugzilla.gnome.org/show_bug.cgi?id=640685

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <stdlib.h>
2
 
#include <stdio.h>
3
 
#include <assert.h>
4
 
#include <string.h>
5
 
 
6
 
#include "parser.h"
7
 
#include "parserfunc.h"
8
 
#include "mp-equation.h"
9
 
 
10
 
/* Converts LexerTokenType to Precedence value. */
11
 
static guint
12
 
p_get_precedence(LexerTokenType type)
13
 
{
14
 
    /* WARNING: This function doesn't work for Unary Plus and Unary Minus. Use their precedence directly while inserting them in tree. */
15
 
    if(type == T_ADD
16
 
     ||type == T_SUBTRACT)
17
 
        return P_AddSubtract;
18
 
    if(type == T_MULTIPLY)
19
 
        return P_Multiply;
20
 
    if(type == T_MOD)
21
 
        return P_Mod;
22
 
    if(type == T_DIV)
23
 
        return P_Divide;
24
 
    if(type == T_NOT)
25
 
        return P_Not;
26
 
    if(type == T_ROOT
27
 
     ||type == T_ROOT_3
28
 
     ||type == T_ROOT_4)
29
 
        return P_Root;
30
 
    if(type == T_FUNCTION)
31
 
        return P_Function;
32
 
    if(type == T_AND
33
 
     ||type == T_OR
34
 
     ||type == T_XOR)
35
 
        return P_Boolean;
36
 
    if(type == T_PERCENTAGE)
37
 
        return P_Percentage;
38
 
    if(type == T_POWER)
39
 
        return P_Power;
40
 
    if(type == T_FACTORIAL)
41
 
        return P_Factorial;
42
 
    if(type == T_NUMBER
43
 
     ||type == T_VARIABLE)
44
 
        return P_NumberVariable;
45
 
    return P_Unknown;
46
 
}
47
 
 
48
 
/* Return associativity of specific token type from precedence. */
49
 
static Associativity
50
 
p_get_associativity_p(Precedence type)
51
 
{
52
 
    if(type == P_Boolean
53
 
     ||type == P_Divide
54
 
     ||type == P_Mod
55
 
     ||type == P_Multiply
56
 
     ||type == P_AddSubtract)
57
 
        return LEFT_ASSOCIATIVE;
58
 
    if(type == P_Power)
59
 
        return RIGHT_ASSOCIATIVE;
60
 
    /* For all remaining / non-associative operators, return Left Associativity. */
61
 
    return LEFT_ASSOCIATIVE;
62
 
}
63
 
 
64
 
/* Return associativity of specific token by converting it to precedence first. */
65
 
static Associativity
66
 
p_get_associativity(LexerToken* token)
67
 
{
68
 
    return p_get_associativity_p(p_get_precedence(token->token_type));
69
 
}
70
 
 
71
 
/* Generate precedence for a node from precedence value. Includes depth_level. */
72
 
static guint
73
 
p_make_precedence_p(ParserState* state, Precedence p)
74
 
{
75
 
    return (p + (state->depth_level * P_Depth));
76
 
}
77
 
 
78
 
/* Generate precedence for a node from lexer token type. Includes depth_level. */
79
 
static guint
80
 
p_make_precedence_t(ParserState* state, LexerTokenType type)
81
 
{
82
 
    return (p_get_precedence(type) + (state->depth_level * P_Depth));
83
 
}
84
 
 
85
 
/* Allocate and create a new node. */
86
 
static ParseNode*
87
 
p_create_node(ParserState* state, LexerToken* token, guint precedence, Associativity associativity, void* value, void* (*function)(ParseNode*))
88
 
{
89
 
    ParseNode* new;
90
 
    new = (ParseNode*) malloc(sizeof(ParseNode));
91
 
    assert(new != NULL);
92
 
    new->parent = NULL;
93
 
    new->left = NULL;
94
 
    new->right = NULL;
95
 
    new->token = token;
96
 
    new->precedence = precedence;
97
 
    new->associativity = associativity;
98
 
    new->value = value;
99
 
    new->state = state;
100
 
    new->evaluate = function;
101
 
    return new;
102
 
}
103
 
 
104
 
/* Compares two nodes to decide, which will be parent and which willbe child. */
105
 
static gint
106
 
p_cmp_nodes(ParseNode* left, ParseNode* right)
107
 
{
108
 
    /* Return values.
109
 
       1 = right goes up (near root) in parse tree.
110
 
       0 = left  goes up (near root) in parse tree.
111
 
    */
112
 
    if(left == NULL)
113
 
        return 0;
114
 
    if(left->precedence > right->precedence)
115
 
    {
116
 
        return 1;
117
 
    }
118
 
    else if(left->precedence < right->precedence)
119
 
    {
120
 
        return 0;
121
 
    }
122
 
    else
123
 
    {
124
 
        if(right->associativity == RIGHT_ASSOCIATIVE)
125
 
        {
126
 
            return 0;
127
 
        }
128
 
        else
129
 
        {
130
 
            return 1;
131
 
        }
132
 
    }
133
 
}
134
 
 
135
 
/* Unified interface (unary and binary nodes) to insert node into parse tree. */
136
 
static void
137
 
p_insert_into_tree_all(ParserState* state, ParseNode* node, guint unary_function)
138
 
{
139
 
    if(state->root == NULL)
140
 
    {
141
 
        state->root = node;
142
 
        state->right_most = state->root;
143
 
        return;
144
 
    }
145
 
    ParseNode* tmp = state->right_most;
146
 
    while(p_cmp_nodes(tmp, node))
147
 
        tmp = tmp->parent;
148
 
    if(unary_function)
149
 
    {
150
 
        /* If tmp is null, that means, we have to insert new node at root. */
151
 
        if(tmp == NULL)
152
 
        {
153
 
            node->right = state->root;
154
 
            node->right->parent = node;
155
 
 
156
 
            state->root = node;
157
 
        }
158
 
        else
159
 
        {
160
 
            node->right = tmp->right;
161
 
            if(node->right)
162
 
                node->right->parent = node;
163
 
 
164
 
            tmp->right = node;
165
 
            if(tmp->right)
166
 
                tmp->right->parent = tmp;
167
 
 
168
 
        }
169
 
        state->right_most = node;
170
 
        while(state->right_most->right != NULL)
171
 
            state->right_most = state->right_most->right;
172
 
    }
173
 
    else
174
 
    {
175
 
        /* If tmp is null, that means, we have to insert new node at root. */
176
 
        if(tmp == NULL)
177
 
        {
178
 
            node->left = state->root;
179
 
            node->left->parent = node;
180
 
 
181
 
            state->root = node;
182
 
        }
183
 
        else
184
 
        {
185
 
            node->left = tmp->right;
186
 
            if(node->left)
187
 
                node->left->parent = node;
188
 
 
189
 
            tmp->right = node;
190
 
            if(tmp->right)
191
 
                tmp->right->parent = tmp;
192
 
 
193
 
        }
194
 
        state->right_most = node;
195
 
    }
196
 
}
197
 
 
198
 
/* Insert binary node into the parse tree. */
199
 
static void
200
 
p_insert_into_tree(ParserState* state, ParseNode* node)
201
 
{
202
 
    p_insert_into_tree_all(state, node, 0);
203
 
}
204
 
 
205
 
/* Insert unary node into the parse tree. */
206
 
static void
207
 
p_insert_into_tree_unary(ParserState* state, ParseNode* node)
208
 
{
209
 
    p_insert_into_tree_all(state, node, 1);
210
 
}
211
 
 
212
 
/* Recursive call to free every node of parse-tree. */
213
 
static void
214
 
p_destroy_all_nodes(ParseNode* node)
215
 
{
216
 
    if(node == NULL)
217
 
        return;
218
 
    p_destroy_all_nodes(node->left);
219
 
    p_destroy_all_nodes(node->right);
220
 
    /* Don't call free for tokens, as they are allocated and freed in lexer. */
221
 
    /* WARNING: If node->value is freed elsewhere, please assign it NULL before calling p_destroy_all_nodes(). */
222
 
    if(node->value)
223
 
        free(node->value);
224
 
    free(node);
225
 
}
226
 
 
227
 
/* Create parser state. */
228
 
ParserState*
229
 
p_create_parser(const gchar* input, MPEquationOptions* options)
230
 
{
231
 
    ParserState* state;
232
 
    state = (ParserState*) malloc(sizeof(ParserState));
233
 
    assert(state != NULL);
234
 
    state->lexer = l_create_lexer(input, state);
235
 
    state->root = NULL;
236
 
    state->depth_level = 0;
237
 
    state->right_most = NULL;
238
 
    state->options = options;
239
 
    state->error = 0;
240
 
    state->error_token = NULL;
241
 
    state->error_token_start = 0;
242
 
    state->error_token_end = 0;
243
 
    return state;
244
 
}
245
 
 
246
 
static guint statement (ParserState*);
247
 
/* Start parsing input string. And call evaluate on success. */
248
 
guint
249
 
p_parse(ParserState* state)
250
 
{
251
 
    guint ret;
252
 
    LexerToken* token;
253
 
    MPNumber* ans;
254
 
    l_insert_all_tokens(state->lexer);
255
 
    ret = statement(state);
256
 
    token = l_get_next_token(state->lexer);
257
 
    if(token->token_type == T_ASSIGN)
258
 
    {
259
 
        token = l_get_next_token(state->lexer);
260
 
        if(token->token_type != PL_EOS)
261
 
        {
262
 
        /* Full string is not parsed. */
263
 
            if(!state->error)
264
 
                set_error(state, PARSER_ERR_INVALID, token->string, token->start_index, token->end_index);
265
 
            return PARSER_ERR_INVALID;
266
 
        }
267
 
    }
268
 
    if(token->token_type != PL_EOS)
269
 
    {
270
 
        /* Full string is not parsed. */
271
 
        if(!state->error)
272
 
            set_error(state, PARSER_ERR_INVALID, token->string, token->start_index, token->end_index);
273
 
        return PARSER_ERR_INVALID;
274
 
    }
275
 
    if(ret == 0)
276
 
        /* Input can't be parsed with grammar. */
277
 
        return PARSER_ERR_INVALID;
278
 
    ans = (MPNumber *) (*(state->root->evaluate))(state->root);
279
 
    if(ans)
280
 
    {
281
 
        mp_set_from_mp(ans, &state->ret);
282
 
        free(ans);
283
 
        return PARSER_ERR_NONE;
284
 
    }
285
 
    return PARSER_ERR_INVALID;
286
 
}
287
 
 
288
 
/* Destroy parser state. */
289
 
void
290
 
p_destroy_parser(ParserState* state)
291
 
{
292
 
    /* If state has a parse tree, destroy it first. */
293
 
    if(state->root)
294
 
    {
295
 
        p_destroy_all_nodes(state->root);
296
 
    }
297
 
    l_destroy_lexer(state->lexer);
298
 
    free(state);
299
 
}
300
 
 
301
 
/* LL (*) parser. Lookahead count depends on tokens. Handle with care. :P */
302
 
 
303
 
static guint expression(ParserState* state);
304
 
static guint expression_1(ParserState* state);
305
 
static guint expression_2(ParserState* state);
306
 
static guint unit(ParserState* state);
307
 
static guint variable(ParserState* state);
308
 
static guint term(ParserState* state);
309
 
static guint term_2(ParserState* state);
310
 
 
311
 
/* Helping function to p_check_variable. */
312
 
static gchar*
313
 
utf8_next_char(const gchar* c)
314
 
{
315
 
    c++;
316
 
    while((*c & 0xC0) == 0x80)
317
 
        c++;
318
 
    return (gchar *)c;
319
 
}
320
 
 
321
 
/* 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. */
322
 
static gboolean
323
 
p_check_variable(ParserState* state, gchar* name)
324
 
{
325
 
    gint result = 0;
326
 
 
327
 
    const gchar *c, *next;
328
 
    gchar *buffer;
329
 
    MPNumber temp;
330
 
 
331
 
    if(!(state->get_variable))
332
 
    {
333
 
        return FALSE;
334
 
    }
335
 
 
336
 
    /* If defined, then get the variable */
337
 
    if((*(state->get_variable))(state, name, &temp))
338
 
    {
339
 
        return TRUE;
340
 
    }
341
 
 
342
 
    /* If has more than one character then assume a multiplication of variables */
343
 
    if(utf8_next_char(name)[0] != '\0')
344
 
    {
345
 
        result = 1;
346
 
        buffer = (gchar*) malloc(sizeof(gchar) * strlen(name));
347
 
        for(c = name; *c != '\0'; c = next)
348
 
        {
349
 
            next = utf8_next_char(c);
350
 
            snprintf(buffer, next - c + 1, "%s", c);
351
 
            if(!(*(state->get_variable))(state, buffer, &temp))
352
 
            {
353
 
                result = 0;
354
 
                break;
355
 
            }
356
 
        }
357
 
        free(buffer);
358
 
    }
359
 
    if(!result)
360
 
    {
361
 
        return FALSE;
362
 
    }
363
 
    return TRUE;
364
 
}
365
 
 
366
 
static guint
367
 
statement(ParserState* state)
368
 
{
369
 
    LexerToken* token;
370
 
    LexerToken* token_old;
371
 
    ParseNode* node;
372
 
    token = l_get_next_token(state->lexer);
373
 
    if(token->token_type == T_VARIABLE)
374
 
    {
375
 
        token_old = token;
376
 
        token = l_get_next_token(state->lexer);
377
 
        if(token->token_type == T_ASSIGN)
378
 
        {
379
 
            /* VARIABLE = expression. */
380
 
 
381
 
            node = p_create_node(state, token_old, p_make_precedence_p(state, P_NumberVariable), p_get_associativity(token_old), NULL, pf_none);
382
 
            p_insert_into_tree(state, node);
383
 
 
384
 
            node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_set_var);
385
 
            p_insert_into_tree(state, node);
386
 
 
387
 
            if(!expression(state))
388
 
                return 0;
389
 
            return 1;
390
 
        }
391
 
        else if(token->token_type == T_IN)
392
 
        {
393
 
            /* UNIT in UNIT. */
394
 
            l_roll_back(state->lexer);
395
 
            l_roll_back(state->lexer);
396
 
            if(!unit(state))
397
 
                return 0;
398
 
            l_get_next_token(state->lexer);
399
 
 
400
 
            node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_1);
401
 
            p_insert_into_tree(state, node);
402
 
 
403
 
            if(!unit(state))
404
 
                return 0;
405
 
            return 1;
406
 
        }
407
 
        else if(token->token_type == T_SUP_NUMBER)
408
 
        {
409
 
            token = l_get_next_token(state->lexer);
410
 
            if(token->token_type == T_IN)
411
 
            {
412
 
                /* UNIT in UNIT */
413
 
                l_roll_back(state->lexer);
414
 
                l_roll_back(state->lexer);
415
 
                l_roll_back(state->lexer);
416
 
                if(!unit(state))
417
 
                    return 0;
418
 
                l_get_next_token(state->lexer);
419
 
 
420
 
                node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_1);
421
 
                p_insert_into_tree(state, node);
422
 
 
423
 
                if(!unit(state))
424
 
                    return 0;
425
 
                return 1;
426
 
            }
427
 
            else
428
 
            {
429
 
                l_roll_back(state->lexer);
430
 
                l_roll_back(state->lexer);
431
 
                l_roll_back(state->lexer);
432
 
                if(!expression(state))
433
 
                    return 0;
434
 
                return 1;
435
 
            }
436
 
        }
437
 
        else
438
 
        {
439
 
            l_roll_back(state->lexer);
440
 
            l_roll_back(state->lexer);
441
 
            if(!expression(state))
442
 
                return 0;
443
 
            return 1;
444
 
        }
445
 
    }
446
 
    else if(token->token_type == T_NUMBER)
447
 
    {
448
 
        token_old = token;
449
 
        token = l_get_next_token(state->lexer);
450
 
        if(token->token_type == T_VARIABLE)
451
 
        {
452
 
            token = l_get_next_token(state->lexer);
453
 
            if(token->token_type == T_IN)
454
 
            {
455
 
                /* NUMBER UNIT in UNIT */
456
 
                l_roll_back(state->lexer);
457
 
                l_roll_back(state->lexer);
458
 
 
459
 
                node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token), NULL, pf_constant);
460
 
                p_insert_into_tree(state, node);
461
 
 
462
 
                if(!unit(state))
463
 
                    return 0;
464
 
                token = l_get_next_token(state->lexer);
465
 
 
466
 
                node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_number);
467
 
                p_insert_into_tree(state, node);
468
 
 
469
 
                if(!unit(state))
470
 
                    return 0;
471
 
                return 1;
472
 
            }
473
 
            else if(token->token_type == T_SUP_NUMBER)
474
 
            {
475
 
                token = l_get_next_token(state->lexer);
476
 
                if(token->token_type == T_IN)
477
 
                {
478
 
                    /* NUMBER UNIT in UNIT */
479
 
                    l_roll_back(state->lexer);
480
 
                    l_roll_back(state->lexer);
481
 
                    l_roll_back(state->lexer);
482
 
 
483
 
                    node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token), NULL, pf_constant);
484
 
                    p_insert_into_tree(state, node);
485
 
 
486
 
                    if(!unit(state))
487
 
                        return 0;
488
 
                    token = l_get_next_token(state->lexer);
489
 
 
490
 
                    node = p_create_node(state, token, 0, p_get_associativity(token), NULL, pf_convert_number);
491
 
                    p_insert_into_tree(state, node);
492
 
 
493
 
                    if(!unit(state))
494
 
                        return 0;
495
 
                    return 1;
496
 
                }
497
 
                else
498
 
                {
499
 
                    l_roll_back(state->lexer);
500
 
                    l_roll_back(state->lexer);
501
 
                    l_roll_back(state->lexer);
502
 
                    l_roll_back(state->lexer);
503
 
                    if(!expression(state))
504
 
                        return 0;
505
 
                    return 1;
506
 
                }
507
 
            }
508
 
            else
509
 
            {
510
 
                l_roll_back(state->lexer);
511
 
                l_roll_back(state->lexer);
512
 
                l_roll_back(state->lexer);
513
 
                if(!expression(state))
514
 
                    return 0;
515
 
                return 1;
516
 
            }
517
 
        }
518
 
        else
519
 
        {
520
 
            l_roll_back(state->lexer);
521
 
            l_roll_back(state->lexer);
522
 
            if(!expression(state))
523
 
                return 0;
524
 
            return 1;
525
 
        }
526
 
    }
527
 
    else
528
 
    {
529
 
        l_roll_back(state->lexer);
530
 
        if(!expression(state))
531
 
            return 0;
532
 
        return 1;
533
 
    }
534
 
}
535
 
 
536
 
static guint
537
 
unit(ParserState* state)
538
 
{
539
 
    LexerToken* token;
540
 
    LexerToken* token_old;
541
 
    ParseNode* node;
542
 
    token = l_get_next_token(state->lexer);
543
 
    if(token->token_type == T_VARIABLE)
544
 
    {
545
 
        token_old = token;
546
 
        token = l_get_next_token(state->lexer);
547
 
        if(token->token_type == T_SUP_NUMBER)
548
 
        {
549
 
            /* VARIABLE POWER */
550
 
 
551
 
            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);
552
 
            p_insert_into_tree(state, node);
553
 
 
554
 
            return 1;
555
 
        }
556
 
        else
557
 
        {
558
 
            l_roll_back(state->lexer);
559
 
            /* VARIABLE */
560
 
 
561
 
            node = p_create_node(state, token_old, p_make_precedence_t(state, token_old->token_type), p_get_associativity(token_old), NULL, pf_none);
562
 
            p_insert_into_tree(state, node);
563
 
 
564
 
            return 1;
565
 
        }
566
 
    }
567
 
    else
568
 
    {
569
 
        l_roll_back(state->lexer);
570
 
        return 0;
571
 
    }
572
 
}
573
 
 
574
 
static guint
575
 
expression(ParserState* state)
576
 
{
577
 
    if(!expression_1(state))
578
 
        return 0;
579
 
    if(!expression_2(state))
580
 
        return 0;
581
 
    return 1;
582
 
}
583
 
 
584
 
static guint
585
 
expression_1(ParserState* state)
586
 
{
587
 
    LexerToken* token;
588
 
    ParseNode* node;
589
 
    token = l_get_next_token(state->lexer);
590
 
    if(token->token_type == PL_EOS
591
 
     ||token->token_type == T_ASSIGN)
592
 
    {
593
 
        l_roll_back(state->lexer);
594
 
        return 0;
595
 
    }
596
 
    if(token->token_type == T_L_R_BRACKET)
597
 
    {
598
 
        state->depth_level++;
599
 
        if(!expression(state))
600
 
            return 0;
601
 
        token = l_get_next_token(state->lexer);
602
 
        if(token->token_type == T_R_R_BRACKET)
603
 
        {
604
 
            state->depth_level--;
605
 
            return 1;
606
 
        }
607
 
        else
608
 
        //Expected ")" here...
609
 
            return 0;
610
 
    }
611
 
    else if(token->token_type == T_L_S_BRACKET)
612
 
    {
613
 
        state->depth_level++;
614
 
 
615
 
        /* Give round, preference of P_Unknown aka 0, to keep it on the top of expression. */
616
 
 
617
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_Unknown), p_get_associativity(token), NULL, pf_do_round);
618
 
        p_insert_into_tree_unary(state, node);
619
 
 
620
 
        if(!expression(state))
621
 
            return 0;
622
 
        token = l_get_next_token(state->lexer);
623
 
        if(token->token_type == T_R_S_BRACKET)
624
 
        {
625
 
            state->depth_level--;
626
 
            return 1;
627
 
        }
628
 
        else
629
 
        //Expected "]" here...
630
 
            return 0;
631
 
    }
632
 
    else if(token->token_type == T_L_C_BRACKET)
633
 
    {
634
 
        state->depth_level++;
635
 
 
636
 
        /* Give fraction, preference of P_Unknown aka 0, to keep it on the top of expression. */
637
 
 
638
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_Unknown), p_get_associativity(token), NULL, pf_do_fraction);
639
 
        p_insert_into_tree_unary(state, node);
640
 
 
641
 
        if(!expression(state))
642
 
            return 0;
643
 
        token = l_get_next_token(state->lexer);
644
 
        if(token->token_type == T_R_C_BRACKET)
645
 
        {
646
 
            state->depth_level--;
647
 
            return 1;
648
 
        }
649
 
        else
650
 
        //Expected "}" here...
651
 
            return 0;
652
 
    }
653
 
    else if(token->token_type == T_ABS)
654
 
    {
655
 
        state->depth_level++;
656
 
 
657
 
        /* Give abs, preference of P_Unknown aka 0, to keep it on the top of expression. */
658
 
 
659
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_Unknown), p_get_associativity(token), NULL, pf_do_abs);
660
 
        p_insert_into_tree_unary(state, node);
661
 
 
662
 
        if(!expression(state))
663
 
            return 0;
664
 
        token = l_get_next_token(state->lexer);
665
 
        if(token->token_type == T_ABS)
666
 
        {
667
 
            state->depth_level--;
668
 
            return 1;
669
 
        }
670
 
        else
671
 
        //Expected "|" here...
672
 
            return 0;
673
 
    }
674
 
    else if(token->token_type == T_NOT)
675
 
    {
676
 
        /* NOT expression */
677
 
 
678
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_Not), p_get_associativity(token), NULL, pf_do_not);
679
 
        p_insert_into_tree_unary(state, node);
680
 
 
681
 
        if(!expression(state))
682
 
            return 0;
683
 
        return 1;
684
 
    }
685
 
    else if(token->token_type == T_NUMBER)
686
 
    {
687
 
        /* NUMBER */
688
 
 
689
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_constant);
690
 
        p_insert_into_tree(state, node);
691
 
 
692
 
        token = l_get_next_token(state->lexer);
693
 
        l_roll_back(state->lexer);
694
 
 
695
 
        if(token->token_type == T_FUNCTION
696
 
         ||token->token_type == T_VARIABLE
697
 
         ||token->token_type == T_SUB_NUMBER
698
 
         ||token->token_type == T_ROOT
699
 
         ||token->token_type == T_ROOT_3
700
 
         ||token->token_type == T_ROOT_4)
701
 
        {
702
 
            /* NUMBER variable. */
703
 
 
704
 
            node = p_create_node(state, NULL, p_make_precedence_p(state, P_Multiply), p_get_associativity_p(P_Multiply), NULL, pf_do_multiply);
705
 
            p_insert_into_tree(state, node);
706
 
 
707
 
            if(!variable(state))
708
 
                return 0;
709
 
            else
710
 
                return 1;
711
 
        }
712
 
        else
713
 
        {
714
 
            return 1;
715
 
        }
716
 
    }
717
 
    else if(token->token_type == T_L_FLOOR)
718
 
    {
719
 
        state->depth_level++;
720
 
        /* Give floor, preference of P_Unknown aka 0, to keep it on the top of expression. */
721
 
 
722
 
        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Unknown), p_get_associativity_p(P_Unknown), NULL, pf_do_floor);
723
 
        p_insert_into_tree_unary(state, node);
724
 
 
725
 
        if(!expression(state))
726
 
            return 0;
727
 
        token = l_get_next_token(state->lexer);
728
 
        if(token->token_type == T_R_FLOOR)
729
 
        {
730
 
            state->depth_level--;
731
 
            return 1;
732
 
        }
733
 
        else
734
 
        //Expected ⌋ here...
735
 
            return 0;
736
 
    }
737
 
    else if(token->token_type == T_L_CEILING)
738
 
    {
739
 
        state->depth_level++;
740
 
        /* Give ceiling, preference of P_Unknown aka 0, to keep it on the top of expression. */
741
 
 
742
 
        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Unknown), p_get_associativity_p(P_Unknown), NULL, pf_do_ceiling);
743
 
        p_insert_into_tree_unary(state, node);
744
 
 
745
 
        if(!expression(state))
746
 
            return 0;
747
 
        token = l_get_next_token(state->lexer);
748
 
        if(token->token_type == T_R_CEILING)
749
 
        {
750
 
            state->depth_level--;
751
 
            return 1;
752
 
        }
753
 
        else
754
 
        //Expected ⌉ here...
755
 
            return 0;
756
 
    }
757
 
    else if(token->token_type == T_SUBTRACT)
758
 
    {
759
 
        /* UnaryMinus expression */
760
 
 
761
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_UnaryMinus), p_get_associativity_p(P_UnaryMinus), NULL, pf_unary_minus);
762
 
        p_insert_into_tree_unary(state, node);
763
 
 
764
 
        if(!expression_1(state))
765
 
            return 0;
766
 
        return 1;
767
 
    }
768
 
    else if(token->token_type == T_ADD)
769
 
    {
770
 
        token = l_get_next_token(state->lexer);
771
 
        if(token->token_type == T_NUMBER)
772
 
        {
773
 
            /* UnaryPlus expression */
774
 
            /* Ignore T_ADD. It is not required. */
775
 
 
776
 
            node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_constant);
777
 
            p_insert_into_tree(state, node);
778
 
            return 1;
779
 
        }
780
 
        else
781
 
        {
782
 
            return 0;
783
 
        }
784
 
    }
785
 
    else
786
 
    {
787
 
        l_roll_back(state->lexer);
788
 
        if(!variable(state))
789
 
            return 0;
790
 
        else
791
 
            return 1;
792
 
    }
793
 
}
794
 
 
795
 
static guint
796
 
expression_2(ParserState* state)
797
 
{
798
 
    LexerToken* token;
799
 
    ParseNode* node;
800
 
    token = l_get_next_token(state->lexer);
801
 
    if(token->token_type == T_L_R_BRACKET)
802
 
    {
803
 
        /* expression "(" expression ")" */
804
 
 
805
 
        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Multiply), p_get_associativity_p(P_Multiply), NULL, pf_do_multiply);
806
 
        p_insert_into_tree(state, node);
807
 
 
808
 
        state->depth_level++;
809
 
        if(!expression(state))
810
 
            return 0;
811
 
        token = l_get_next_token(state->lexer);
812
 
        if(token->token_type == T_R_R_BRACKET)
813
 
        {
814
 
            state->depth_level--;
815
 
            if(!expression_2(state))
816
 
                return 0;
817
 
            return 1;
818
 
        }
819
 
        else
820
 
        {
821
 
            return 0;
822
 
        }
823
 
    }
824
 
    else if(token->token_type == T_POWER)
825
 
    {
826
 
        /* expression "^" expression */
827
 
 
828
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_x_pow_y);
829
 
        p_insert_into_tree(state, node);
830
 
 
831
 
        if(!expression_1(state))
832
 
            return 0;
833
 
        if(!expression_2(state))
834
 
            return 0;
835
 
        return 1;
836
 
    }
837
 
    else if(token->token_type == T_SUP_NUMBER)
838
 
    {
839
 
        /* expression T_SUP_NUMBER */
840
 
 
841
 
        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);
842
 
        p_insert_into_tree(state, node);
843
 
 
844
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_NumberVariable), p_get_associativity_p(P_NumberVariable), NULL, pf_none);
845
 
        p_insert_into_tree(state, node);
846
 
 
847
 
        if(!expression_2(state))
848
 
            return 0;
849
 
        return 1;
850
 
    }
851
 
    else if(token->token_type == T_NSUP_NUMBER)
852
 
    {
853
 
        /* expression T_NSUP_NUMBER */
854
 
 
855
 
        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);
856
 
        p_insert_into_tree(state, node);
857
 
 
858
 
        node = p_create_node(state, token, p_make_precedence_p(state, P_NumberVariable), p_get_associativity_p(P_NumberVariable), NULL, pf_none);
859
 
        p_insert_into_tree(state, node);
860
 
 
861
 
        if(!expression_2(state))
862
 
            return 0;
863
 
        return 1;
864
 
    }
865
 
    else if(token->token_type == T_FACTORIAL)
866
 
    {
867
 
        /* expression T_FACTORIAL */
868
 
 
869
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_factorial);
870
 
        p_insert_into_tree_unary(state, node);
871
 
 
872
 
        if(!expression_2(state))
873
 
            return 0;
874
 
        return 1;
875
 
    }
876
 
    else if(token->token_type == T_MULTIPLY)
877
 
    {
878
 
        /* expression T_MULTIPLY expression */
879
 
 
880
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_multiply);
881
 
        p_insert_into_tree(state, node);
882
 
 
883
 
        if(!expression_1(state))
884
 
            return 0;
885
 
        if(!expression_2(state))
886
 
            return 0;
887
 
        return 1;
888
 
    }
889
 
    else if(token->token_type == T_PERCENTAGE)
890
 
    {
891
 
        /* expression % */
892
 
 
893
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_percent);
894
 
        p_insert_into_tree_unary(state, node);
895
 
 
896
 
        if(!expression_2(state))
897
 
            return 0;
898
 
        return 1;
899
 
    }
900
 
    else if(token->token_type == T_AND)
901
 
    {
902
 
        /* expression T_AND expression */
903
 
 
904
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_and);
905
 
        p_insert_into_tree(state, node);
906
 
 
907
 
        if(!expression_1(state))
908
 
            return 0;
909
 
        if(!expression_2(state))
910
 
            return 0;
911
 
        return 1;
912
 
    }
913
 
    else if(token->token_type == T_OR)
914
 
    {
915
 
        /* expression T_OR expression */
916
 
 
917
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_or);
918
 
        p_insert_into_tree(state, node);
919
 
 
920
 
        if(!expression_1(state))
921
 
            return 0;
922
 
        if(!expression_2(state))
923
 
            return 0;
924
 
        return 1;
925
 
    }
926
 
    else if(token->token_type == T_XOR)
927
 
    {
928
 
        /* expression T_XOR expression */
929
 
 
930
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_xor);
931
 
        p_insert_into_tree(state, node);
932
 
 
933
 
        if(!expression_1(state))
934
 
            return 0;
935
 
        if(!expression_2(state))
936
 
            return 0;
937
 
        return 1;
938
 
    }
939
 
    else if(token->token_type == T_DIV)
940
 
    {
941
 
        /* expression T_DIV expression */
942
 
 
943
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_divide);
944
 
        p_insert_into_tree(state, node);
945
 
 
946
 
        if(!expression_1(state))
947
 
            return 0;
948
 
        if(!expression_2(state))
949
 
            return 0;
950
 
        return 1;
951
 
    }
952
 
    else if(token->token_type == T_MOD)
953
 
    {
954
 
        /* expression T_MOD expression */
955
 
 
956
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_mod);
957
 
        p_insert_into_tree(state, node);
958
 
 
959
 
        if(!expression_1(state))
960
 
            return 0;
961
 
        if(!expression_2(state))
962
 
            return 0;
963
 
        return 1;
964
 
    }
965
 
    else if(token->token_type == T_ADD)
966
 
    {
967
 
        /* expression T_ADD expression */
968
 
 
969
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_add);
970
 
        p_insert_into_tree(state, node);
971
 
 
972
 
        if(!expression_1(state))
973
 
            return 0;
974
 
        token = l_get_next_token(state->lexer);
975
 
        if(token->token_type == T_PERCENTAGE)
976
 
        {
977
 
            //FIXME: This condition needs to be verified for all cases.. :(
978
 
            if(node->right->precedence > P_Percentage)
979
 
            {
980
 
                node->precedence = P_Percentage;
981
 
                node->evaluate = pf_do_add_percent;
982
 
                return 1;
983
 
            }
984
 
            else
985
 
            {
986
 
                /* Assume '%' to be part of 'expression T_PERCENTAGE' statement. */
987
 
                l_roll_back(state->lexer);
988
 
                if(!expression_2(state))
989
 
                    return 1;
990
 
            }
991
 
        }
992
 
        else
993
 
        {
994
 
            l_roll_back(state->lexer);
995
 
        }
996
 
        if(!expression_2(state))
997
 
            return 0;
998
 
        return 1;
999
 
    }
1000
 
    else if(token->token_type == T_SUBTRACT)
1001
 
    {
1002
 
        /* expression T_SUBTRACT expression */
1003
 
 
1004
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_subtract);
1005
 
        p_insert_into_tree(state, node);
1006
 
 
1007
 
        if(!expression_1(state))
1008
 
            return 0;
1009
 
        token = l_get_next_token(state->lexer);
1010
 
        if(token->token_type == T_PERCENTAGE)
1011
 
        {
1012
 
            //FIXME: This condition needs to be verified for all cases.. :(
1013
 
            if(node->right->precedence > P_Percentage)
1014
 
            {
1015
 
                node->precedence = P_Percentage;
1016
 
                node->evaluate = pf_do_subtract_percent;
1017
 
                return 1;
1018
 
            }
1019
 
            else
1020
 
            {
1021
 
                /* Assume '%' to be part of 'expression T_PERCENTAGE' statement. */
1022
 
                l_roll_back(state->lexer);
1023
 
                if(!expression_2 (state))
1024
 
                    return 1;
1025
 
            }
1026
 
        }
1027
 
        else
1028
 
        {
1029
 
            l_roll_back(state->lexer);
1030
 
        }
1031
 
        if(!expression_2(state))
1032
 
            return 0;
1033
 
        return 1;
1034
 
    }
1035
 
    else
1036
 
    {
1037
 
        l_roll_back(state->lexer);
1038
 
        return 1;
1039
 
    }
1040
 
}
1041
 
 
1042
 
static guint
1043
 
variable(ParserState* state)
1044
 
{
1045
 
    LexerToken* token;
1046
 
    LexerToken* token_old;
1047
 
    ParseNode* node;
1048
 
    token = l_get_next_token(state->lexer);
1049
 
    if(token->token_type == T_FUNCTION)
1050
 
    {
1051
 
        token_old = token;
1052
 
        token = l_get_next_token(state->lexer);
1053
 
        if(token->token_type == T_SUP_NUMBER)
1054
 
        {
1055
 
            /* FUNCTION SUP_NUMBER expression */
1056
 
            /* Pass power as void * value. That will be taken care in pf_apply_func_with_powre. */
1057
 
 
1058
 
            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);
1059
 
            p_insert_into_tree_unary(state, node);
1060
 
 
1061
 
            if(!expression(state))
1062
 
                return 0;
1063
 
            return 1;
1064
 
        }
1065
 
        else if(token->token_type == T_NSUP_NUMBER)
1066
 
        {
1067
 
            /* FUNCTION NSUP_NUMBER expression */
1068
 
            /* Pass power as void * value. That will be taken care in pf_apply_func_with_npowre. */
1069
 
 
1070
 
            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);
1071
 
            p_insert_into_tree_unary(state, node);
1072
 
 
1073
 
            if(!expression(state))
1074
 
                return 0;
1075
 
            return 1;
1076
 
        }
1077
 
        else
1078
 
        {
1079
 
            l_roll_back(state->lexer);
1080
 
            /* FUNCTION expression */
1081
 
 
1082
 
            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);
1083
 
            p_insert_into_tree_unary(state, node);
1084
 
 
1085
 
            if(!expression(state))
1086
 
                return 0;
1087
 
            return 1;
1088
 
        }
1089
 
    }
1090
 
    else if(token->token_type == T_SUB_NUMBER)
1091
 
    {
1092
 
        token_old = token;
1093
 
        token = l_get_next_token(state->lexer);
1094
 
        if(token->token_type == T_ROOT)
1095
 
        {
1096
 
            /* SUB_NUM ROOT expression */
1097
 
            /* Pass SUB_NUM as void* value in node. pf_do_nth_root will take care of it. */
1098
 
 
1099
 
            node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), token_old, pf_do_nth_root);
1100
 
            p_insert_into_tree_unary(state, node);
1101
 
 
1102
 
            if(!expression (state))
1103
 
                return 0;
1104
 
            return 1;
1105
 
        }
1106
 
        else
1107
 
        {
1108
 
            return 0;
1109
 
        }
1110
 
    }
1111
 
    else if(token->token_type == T_ROOT)
1112
 
    {
1113
 
        /* ROOT expression */
1114
 
 
1115
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_sqrt);
1116
 
        p_insert_into_tree_unary(state, node);
1117
 
 
1118
 
        if(!expression(state))
1119
 
            return 0;
1120
 
        return 1;
1121
 
    }
1122
 
    else if(token->token_type == T_ROOT_3)
1123
 
    {
1124
 
        /* ROOT_3 expression */
1125
 
 
1126
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_root_3);
1127
 
        p_insert_into_tree_unary(state, node);
1128
 
 
1129
 
        if(!expression(state))
1130
 
            return 0;
1131
 
        return 1;
1132
 
    }
1133
 
    else if(token->token_type == T_ROOT_4)
1134
 
    {
1135
 
        /* ROOT_4 expression */
1136
 
 
1137
 
        node = p_create_node(state, token, p_make_precedence_t(state, token->token_type), p_get_associativity(token), NULL, pf_do_root_4);
1138
 
        p_insert_into_tree_unary(state, node);
1139
 
 
1140
 
        if(!expression(state))
1141
 
            return 0;
1142
 
        return 1;
1143
 
    }
1144
 
    else if(token->token_type == T_VARIABLE)
1145
 
    {
1146
 
        l_roll_back(state->lexer);
1147
 
        //TODO: unknown function ERROR for (T_VARIABLE T_SUP_NUMBER expression).
1148
 
        if(!term(state))
1149
 
            return 0;
1150
 
        return 1;
1151
 
    }
1152
 
    else
1153
 
    {
1154
 
        return 0;
1155
 
    }
1156
 
}
1157
 
 
1158
 
static guint
1159
 
term(ParserState* state)
1160
 
{
1161
 
    LexerToken* token;
1162
 
    LexerToken* token_old;
1163
 
    ParseNode* node;
1164
 
    token = l_get_next_token(state->lexer);
1165
 
    if(token->token_type == T_VARIABLE)
1166
 
    {
1167
 
        token_old = token;
1168
 
        /* Check if the token is a valid variable or not. */
1169
 
        if(!p_check_variable(state, token->string))
1170
 
        {
1171
 
            set_error(state, PARSER_ERR_UNKNOWN_VARIABLE, token->string, token->start_index, token->end_index);
1172
 
            return 0;
1173
 
        }
1174
 
        token = l_get_next_token(state->lexer);
1175
 
        if(token->token_type == T_SUP_NUMBER)
1176
 
        {
1177
 
            /* VARIABLE SUP_NUMBER */
1178
 
            /* Pass power as void* value. pf_get_variable_with_power will take care of it. */
1179
 
 
1180
 
            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);
1181
 
            p_insert_into_tree(state, node);
1182
 
 
1183
 
        }
1184
 
        else
1185
 
        {
1186
 
            l_roll_back(state->lexer);
1187
 
            /* VARIABLE */
1188
 
 
1189
 
            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);
1190
 
            p_insert_into_tree(state, node);
1191
 
 
1192
 
        }
1193
 
        if(!term_2(state))
1194
 
            return 0;
1195
 
        return 1;
1196
 
    }
1197
 
    else
1198
 
    {
1199
 
        return 0;
1200
 
    }
1201
 
}
1202
 
 
1203
 
static guint
1204
 
term_2(ParserState* state)
1205
 
{
1206
 
    LexerToken* token;
1207
 
    ParseNode* node;
1208
 
    token = l_get_next_token(state->lexer);
1209
 
    l_roll_back(state->lexer);
1210
 
    if(token->token_type == PL_EOS
1211
 
     ||token->token_type == T_ASSIGN)
1212
 
    {
1213
 
        return 1;
1214
 
    }
1215
 
    if(token->token_type == T_VARIABLE)
1216
 
    {
1217
 
        /* Insert multiply in between two distinct (variable). */
1218
 
 
1219
 
        node = p_create_node(state, NULL, p_make_precedence_p(state, P_Multiply), p_get_associativity_p(P_Multiply), NULL, pf_do_multiply);
1220
 
        p_insert_into_tree(state, node);
1221
 
 
1222
 
        if(!term(state))
1223
 
            return 0;
1224
 
        return 1;
1225
 
    }
1226
 
    else
1227
 
    {
1228
 
        return 1;
1229
 
    }
1230
 
}