new parser that uses flex and bison
[platform/upstream/gstreamer.git] / gst / parse / grammar.y
1 %{
2 #include <glib.h>
3 #include <stdio.h>
4 #include "../gstparse.h"
5 #include "types.h"
6
7 #define YYDEBUG 1
8 #define YYERROR_VERBOSE 1
9 #define YYPARSE_PARAM pgraph
10
11 static int yylex (void *lvalp);
12 static int yyerror (const char *s);
13 %}
14
15 %union {
16     gchar *s;
17     GValue *v;
18     graph_t *g;
19     connection_t *c;
20     property_t *p;
21     element_t *e;
22 }
23
24 %token <s> IDENTIFIER
25 %token <c> CONNECTION BCONNECTION
26 %token <v> VALUE
27
28 %type <s> id
29 %type <g> graph bin
30 %type <e> element
31 %type <p> property_value value
32 %type <c> connection rconnection
33
34 %left '{' '}' '(' ')'
35 %left '!' '='
36 %left ','
37 %left '.'
38
39 %pure_parser
40
41 %start graph
42 %%
43
44 id:     IDENTIFIER
45         ;
46
47 value:          VALUE                { $$ = g_new0 (property_t, 1); $$->value = $1; }
48         ;
49
50 property_value: id '=' value         { $$ = $3; $$->name = $1; }
51         ;
52
53 element:        id                   { static int i = 0; $$ = g_new0 (element_t, 1);
54                                        $$->type = $1; $$->index = ++i; }
55         ;
56
57 graph:          /* empty */          { $$ = g_new0 (graph_t, 1); *((graph_t**) pgraph) = $$; }
58         |       graph element        { GList *l;
59                                        $$ = $1; l = $$->connections_pending;
60                                        $$->elements = g_list_append ($$->elements, $2);
61                                        $$->current = $2;
62                                        if (!$$->first)
63                                            $$->first = $$->current;
64                                        while (l) {
65                                            ((connection_t*) l->data)->sink_index = $$->current->index;
66                                            l = g_list_next (l);
67                                        }
68                                        if ($$->connections_pending) {
69                                            g_list_free ($$->connections_pending);
70                                            $$->connections_pending = NULL;
71                                        }
72                                      }
73         |       graph bin            { GList *l; $$ = $1; l = $$->connections_pending;
74                                        *((graph_t**) pgraph) = $$;
75                                        $$->bins = g_list_append ($$->bins, $2);
76                                        $2->parent = $$;
77                                        $$->current = $2->first;
78                                        if (!$$->first)
79                                            $$->first = $$->current;
80                                        while (l) {
81                                            ((connection_t*) l->data)->sink_index = $$->current->index;
82                                            l = g_list_next (l);
83                                        }
84                                        if ($$->connections_pending) {
85                                            g_list_free ($$->connections_pending);
86                                            $$->connections_pending = NULL;
87                                        }
88                                        $$->current = $2->current;
89                                      }
90         |       graph connection     { $$ = $1;
91                                        $$->connections = g_list_append ($$->connections, $2);
92                                        $2->src_index = $$->current->index;
93                                        if (!$2->sink_name)
94                                            $$->connections_pending = g_list_append ($$->connections_pending, $2);
95                                      }
96         |       graph property_value { $$ = $1;
97                                        $$->current->property_values = g_list_append ($$->current->property_values,
98                                                                                      $2);
99                                      }
100         ;
101
102 bin:            '{' graph '}'        { $$ = $2; $$->current_bin_type = "thread"; }
103         |       id '.' '(' graph ')' { $$ = $4; $$->current_bin_type = $1; }
104         ;
105
106 connection:     CONNECTION
107         |       rconnection
108         ;
109
110 rconnection:   '!'                   { $$ = g_new0 (connection_t, 1); }
111         |       BCONNECTION          { $$ = $1; }
112         |       id ',' rconnection ',' id 
113                                      { $$ = $3;
114                                        $$->src_pads = g_list_prepend ($$->src_pads, $1);
115                                        $$->sink_pads = g_list_append ($$->sink_pads, $5);
116                                      }
117         ;
118
119 %%
120
121 extern FILE *yyin;
122 int _gst_parse_yylex (YYSTYPE *lvalp);
123
124 static int yylex (void *lvalp) {
125     return _gst_parse_yylex ((YYSTYPE*) lvalp);
126 }
127
128 static int
129 yyerror (const char *s)
130 {
131   printf ("error: %s\n", s);
132   return -1;
133 }
134
135 int yy_scan_string (char*);
136
137 graph_t * _gst_parse_launch (const gchar *str, GError **error)
138 {
139     graph_t *g = NULL;
140     gchar *dstr;
141     
142     g_return_val_if_fail (str != NULL, NULL);
143
144     dstr = g_strdup (str);
145     yy_scan_string (dstr);
146
147 #ifdef DEBUG
148     yydebug = 1;
149 #endif
150
151     if (yyparse (&g) != 0) {
152         g_set_error (error,
153                      GST_PARSE_ERROR,
154                      GST_PARSE_ERROR_SYNTAX,
155                      "Invalid syntax");
156         g_free (dstr);
157         return NULL;
158     }
159     
160     g_assert (g != NULL);
161
162     g_free (dstr);
163
164     return g;
165 }