form a semantic representation of the pipeline in preparation for actual instantiation.
[platform/upstream/gstreamer.git] / gst / parse / grammar.y
1 %{
2 #include <glib.h>
3 #include <stdio.h>
4 #include "types.h"
5 #define YYDEBUG 1
6 #define YYERROR_VERBOSE 1
7 %}
8
9 %union {
10     double d;
11     gboolean b;
12     gint i;
13     gchar *s;
14     graph_t *g;
15     connection_t *c;
16     property_t *p;
17     element_t *e;
18     hash_t *h;
19 }
20
21 %token <s> IDENTIFIER STRING
22 %token <d> FLOAT
23 %token <i> INTEGER
24 %token <b> BOOLEAN
25
26 %type <s> id
27 %type <h> qid
28 %type <g> graph bin
29 %type <e> element
30 %type <p> property_value value
31 %type <c> connection lconnection rconnection qconnection iconnection
32
33 %left '{' '}' '(' ')'
34 %left '!' '='
35 %left '+'
36 %left '.'
37
38 %start graph
39 %%
40
41 id:     IDENTIFIER
42         ;
43
44 qid:            id                   { $$ = g_new0 (hash_t, 1); $$->id2 = $1 }
45         |       id '.' id            { $$ = g_new0 (hash_t, 1); $$->id1 = $1; $$->id2 = $3; }
46         ;
47
48 value:          STRING               { $$ = g_new0 (property_t, 1); 
49                                        $$->value_type = G_TYPE_STRING; $$->value.s = $1; }
50         |       FLOAT                { $$ = g_new0 (property_t, 1);
51                                        $$->value_type = G_TYPE_DOUBLE; $$->value.d = $1; }
52         |       INTEGER              { $$ = g_new0 (property_t, 1);
53                                        $$->value_type = G_TYPE_INT; $$->value.i = $1; }
54         |       BOOLEAN              { $$ = g_new0 (property_t, 1);
55                                        $$->value_type = G_TYPE_BOOLEAN; $$->value.b = $1; }
56         ;
57
58 property_value: id '=' value         { $$ = $3; $$->name = $1; }
59         ;
60
61 element:        id                   { $$ = g_new0 (element_t, 1); $$->name = $1; }
62         ;
63
64 graph:          /* empty */          { $$ = g_new0 (graph_t, 1); }
65         |       graph element        { GList *l = $$->connections_pending;
66                                        $$ = $1;
67                                        $$->elements = g_list_append ($$->elements, $2);
68                                        $$->current = $2;
69                                        while (l) {
70                                            ((connection_t*) l->data)->sink = $$->current->name;
71                                            l = g_list_next (l);
72                                        }
73                                        if ($$->connections_pending) {
74                                            g_list_free ($$->connections_pending);
75                                            $$->connections_pending = NULL;
76                                        }
77                                      }
78         |       graph bin            { $$ = $1; $$->bins = g_list_append ($$->bins, $2); }
79         |       graph connection     { $$ = $1; $$->connections = g_list_append ($$->connections, $2);
80                                        if (!$2->src)
81                                            $2->src = $$->current->name;
82                                        if (!$2->sink)
83                                            $$->connections_pending = g_list_append ($$->connections_pending, $2);
84                                      }
85         |       graph property_value { $$ = $1;
86                                        $$->current->property_values = g_list_append ($$->current->property_values,
87                                                                                      $2);
88                                      }
89         ;
90
91 bin:            '{' graph '}'        { $$ = $2; $$->current_bin_type = "gstthread"; }
92         |       id '.' '(' graph ')' { $$ = $4; $$->current_bin_type = $1; }
93         ;
94
95 connection:     lconnection
96         |       rconnection
97         |       qconnection
98         |       iconnection
99         ;
100
101 lconnection:    qid '+' '!'          { $$ = g_new0 (connection_t, 1);
102                                        $$->src = $1->id1;
103                                        $$->src_pads = g_list_append ($$->src_pads, $1->id2);
104                                      }
105         ;
106
107 rconnection:    '!' '+' qid          { $$ = g_new0 (connection_t, 1);
108                                        $$->sink = $3->id1;
109                                        $$->sink_pads = g_list_append ($$->src_pads, $3->id2);
110                                      }
111         ;
112
113 qconnection:    qid '+' '!' '+' qid  { $$ = g_new0 (connection_t, 1);
114                                        $$->src = $1->id1;
115                                        $$->src_pads = g_list_append ($$->src_pads, $1->id2);
116                                        $$->sink = $5->id1;
117                                        $$->sink_pads = g_list_append ($$->sink_pads, $5->id2);
118                                      }
119         ;
120
121 iconnection:   '!'                   { $$ = g_new0 (connection_t, 1); }
122         |       id '+' iconnection '+' id 
123                                      { $$ = $3;
124                                        $$->src_pads = g_list_append ($$->src_pads, $1);
125                                        $$->sink_pads = g_list_append ($$->sink_pads, $5);
126                                      }
127         ;
128
129 %%
130
131 extern FILE *yyin;
132
133 int
134 yyerror (const char *s)
135 {
136   printf ("error: %s\n", s);
137   return -1;
138 }
139
140 int main (int argc, char **argv)
141 {
142     ++argv, --argc;  /* skip over program name */
143     if ( argc > 0 )
144         yyin = fopen (argv[0], "r");
145     else
146         yyin = stdin;
147
148 #ifdef DEBUG
149     yydebug = 1;
150 #endif
151
152     return yyparse();
153 }