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