Fixed first
[cascardo/grammar.git] / rdp.c
1 #include <rdp.h>
2 #include <stdlib.h>
3
4 struct _buffer
5 {
6   symbol_t* symbol;
7   gpointer attrib;
8 };
9
10 gpointer leaf_new (gpointer data)
11 {
12   return g_node_new (data);
13 }
14
15 gpointer tree_new (rule_t* rule)
16 {
17   return g_node_new (rule);
18 }
19
20 gpointer tree_add (gpointer tree, gpointer data)
21 {
22   return g_node_append (tree, data);
23 }
24
25 void tree_delete (gpointer tree)
26 {
27   g_node_destroy (tree);
28 }
29
30 rdp_t* rdp_new (nextcb cb, gpointer data, gint value, grammar_t* grammar)
31 {
32
33   rdp_t* parser;
34
35   parser = g_malloc (sizeof (rdp_t));
36
37   parser->cb = cb;
38   parser->data = data;
39   parser->start = symbol_new (FALSE, value);
40   parser->grammar = grammar;
41
42   parser->buffer = g_list_append (NULL, NULL);
43
44   return parser;
45
46 }
47
48 void rdp_delete (rdp_t* rdp)
49 {
50   g_free (rdp->start);
51 }
52
53 symbol_t* buffer_next (rdp_t* parser, gpointer* attrib)
54 {
55
56   buffer_t* buffer;
57
58   if (parser->buffer->next == NULL)
59     {
60       buffer = g_malloc (sizeof (buffer_t));
61       buffer->symbol = g_malloc (sizeof (symbol_t));
62       buffer->symbol->terminal = TRUE;
63       buffer->symbol->value = parser->cb (parser->data, &(buffer->attrib));
64       g_list_append (parser->buffer, buffer);
65     }
66
67   parser->buffer = g_list_next (parser->buffer);
68   buffer = (buffer_t*) parser->buffer->data;
69
70   if (attrib)
71     *attrib = buffer->attrib;
72
73   return buffer->symbol;
74       
75 }
76
77 gboolean rdp_step (rdp_t* parser, symbol_t* symbol, gpointer* attrib)
78 {
79
80   GList* l;
81   GList* buffer;
82   gpointer attr;
83
84   buffer = parser->buffer;
85
86   if (symbol != NULL && symbol->terminal)
87     {
88       symbol_t* s;
89       s = buffer_next (parser, &attr);
90       if (!symbol_equal (symbol, s))
91         {
92           parser->buffer = buffer;
93           return FALSE;
94         }
95       *attrib = leaf_new (attr);
96       return TRUE;
97     }
98
99   l = grammar_get_rules (parser->grammar, symbol);
100   for (; l != NULL; l = g_list_next (l))
101     {
102
103       rule_t* rule;
104       GList* m;
105
106       rule = (rule_t*) l->data;
107
108
109       *attrib = tree_new (symbol_copy (symbol));
110
111       m = grammar_get_rule (rule);
112
113       /*
114       if (m == NULL)
115         {
116           tree_add (*attrib, leaf_new (g_string_new ("")));
117           return TRUE;
118         }
119       */
120
121       while (m != NULL)
122         {
123
124           symbol_t* s;
125
126           s = (symbol_t*) m->data;
127
128           if (!rdp_step (parser, s, &attr))
129             {
130               parser->buffer = buffer;
131               break;
132             }
133
134           tree_add (*attrib, attr);
135
136           m = g_list_next (m);
137
138         }
139
140       if (m == NULL)
141         return TRUE;
142       else
143         tree_delete (*attrib);
144
145     }
146
147   return FALSE;
148
149 }
150
151 gpointer rdp_build (rdp_t* parser)
152 {
153
154   gpointer attrib;
155
156   if (rdp_step (parser, parser->start, &attrib))
157     return attrib;
158
159   return NULL;
160
161 }