RPA Toolkit
changed the callback parameters and added look ahead/back while parsing
[rpatk.git] / tests / calc-test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "rpadbex.h"
5
6
7 #define LC_STACK_SIZE 1024
8
9
10 typedef struct lc_stack_s {
11         int buf[LC_STACK_SIZE];
12         unsigned int pos;
13 } lc_stack_t;
14
15 void lc_stack_push(lc_stack_t *stack, int n)
16 {
17         if (stack->pos < LC_STACK_SIZE) {
18                 stack->pos += 1;
19                 stack->buf[stack->pos] = n;
20         }
21 }
22
23 int lc_stack_pop(lc_stack_t *stack)
24 {
25         int n = 0;
26         if (stack->pos > 0) {
27                 n = stack->buf[stack->pos];
28                 stack->pos -= 1;
29         }
30         return n;
31 }
32
33
34 int lc_print(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
35 {
36 #ifdef DEBUGPRINT
37         fprintf(stdout, "%s: ", name);
38         fwrite(input, sizeof(char), size, stdout);
39         fprintf(stdout, "\n");
40 #endif
41         return size;
42 }
43
44
45 int lc_addop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
46 {
47         lc_stack_t *stack = (lc_stack_t*)userdata;
48         int op1 = 0, op2 = 0;
49
50         op2 = lc_stack_pop(stack);
51         op1 = lc_stack_pop(stack);      
52         lc_stack_push(stack, op1 + op2);
53         lc_print(stat, name, userdata, input, size, reason);
54         return size;
55 }
56
57 int lc_subop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
58 {
59         lc_stack_t *stack = (lc_stack_t*)userdata;
60         int op1 = 0, op2 = 0;
61
62         op2 = lc_stack_pop(stack);
63         op1 = lc_stack_pop(stack);      
64         lc_stack_push(stack, op1 - op2);
65         lc_print(stat, name, userdata, input, size, reason);
66         return size;
67 }
68
69
70 int lc_divop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
71 {
72         lc_stack_t *stack = (lc_stack_t*)userdata;
73         int op1 = 0, op2 = 0;
74
75         op2 = lc_stack_pop(stack);
76         op1 = lc_stack_pop(stack);      
77         lc_stack_push(stack, op1 / op2);
78         lc_print(stat, name, userdata, input, size, reason);
79         return size;
80 }
81
82 int lc_mulop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
83 {
84         lc_stack_t *stack = (lc_stack_t*)userdata;
85         int op1 = 0, op2 = 0;
86
87         op2 = lc_stack_pop(stack);
88         op1 = lc_stack_pop(stack);      
89         lc_stack_push(stack, op1 * op2);
90         lc_print(stat, name, userdata, input, size, reason);
91         return size;
92 }
93
94 int lc_integer_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
95 {
96         lc_stack_t *stack = (lc_stack_t*)userdata;
97
98         lc_stack_push(stack, atoi(input));
99         lc_print(stat, name, userdata, input, size, reason);
100         return size;
101 }
102
103 int main(int argc, char *argv[])
104 {
105         rpa_dbex_handle hDbex;
106         lc_stack_t stack;
107         int res;
108
109         memset(&stack, 0, sizeof(stack));
110         hDbex = rpa_dbex_create();
111         /*
112          * Important: Callbacks must be specified before the rules!
113          */
114         rpa_dbex_add_callback(hDbex, "mulop", RPA_REASON_MATCHED, lc_mulop_callback, &stack);
115         rpa_dbex_add_callback(hDbex, "divop", RPA_REASON_MATCHED, lc_divop_callback, &stack);
116         rpa_dbex_add_callback(hDbex, "addop", RPA_REASON_MATCHED, lc_addop_callback, &stack);
117         rpa_dbex_add_callback(hDbex, "subop", RPA_REASON_MATCHED, lc_subop_callback, &stack);
118         rpa_dbex_add_callback(hDbex, "integer", RPA_REASON_MATCHED, lc_integer_callback, &stack);
119
120         rpa_dbex_open(hDbex);
121         res = rpa_dbex_load_string(hDbex, "S            ::= [#x20]+");
122         res = rpa_dbex_load_string(hDbex, "digit        ::= [0-9]");
123         res = rpa_dbex_load_string(hDbex, "integer      ::= <:digit:>+");
124         res = rpa_dbex_load_string(hDbex, "term         ::= <:integer:> | '('<:S:>? <:expr:> <:S:>? ')'");
125         res = rpa_dbex_load_string(hDbex, "mulop        ::= <:mulex:> <:S:>? '*' <:S:>? <:term:>");
126         res = rpa_dbex_load_string(hDbex, "divop        ::= <:mulex:> <:S:>? '/' <:S:>? <:term:>");
127         res = rpa_dbex_load_string(hDbex, "mulex        ::= <:mulop:> | <:divop:> | <:term:>");
128         res = rpa_dbex_load_string(hDbex, "addop        ::= <:expr:> <:S:>? '+' <:S:>? <:mulex:>");
129         res = rpa_dbex_load_string(hDbex, "subop        ::= <:expr:> <:S:>? '-' <:S:>? <:mulex:>");
130         res = rpa_dbex_load_string(hDbex, "expr         ::= <:addop:> | <:subop:> | <:mulex:>");
131         res = rpa_dbex_load_string(hDbex, "exec         ::= <:expr:>");
132         rpa_dbex_close(hDbex);
133         if (argc > 1) {
134                 res = rpa_dbex_parse(hDbex, rpa_dbex_default_pattern(hDbex), argv[1], argv[1], argv[1] + strlen(argv[1]));
135         }
136         rpa_dbex_destroy(hDbex);
137
138         fprintf(stdout, "%d\n", lc_stack_pop(&stack));
139         return 0;
140 }