1 /*
2  * aegis - project change supervisor
3  * Copyright (C) 1991-1994, 1999, 2002, 2004-2006, 2008, 2012 Peter Miller
4  * Copyright (C) 2020 Aryeh M. Friedman
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 %define api.prefix {gram_}
22 %{
23 
24 #include <common/ac/stdio.h>
25 #include <common/ac/stdlib.h>
26 #include <common/error.h>
27 
28 #include <common/nstring.h>
29 #include <common/trace.h>
30 #include <libaegis/gram.h>
31 #include <libaegis/meta_lex.h>
32 #include <libaegis/sem.h>
33 
34 #ifdef DEBUG
35 #define YYDEBUG 1
36 #endif
37 
38 %}
39 
40 %token INTEGER
41 %token NAME
42 %token REAL
43 %token STRING
44 
45 %union
46 {
47     nstring *lv_string;
48     long lv_integer;
49     double lv_real;
50 }
51 
52 %type <lv_string> NAME STRING string
53 %type <lv_integer> INTEGER integer
54 %type <lv_real> REAL real
55 
56 %%
57 
58 file
59     : turn_debug_on field_list
60     ;
61 
62 turn_debug_on
63     : /* empty */
64         {
65 #ifdef DEBUG
66             yydebug = trace_pretest_;
67 #endif
68         }
69     ;
70 
71 field_list
72     : /* empty */
73     | field_list field
74     ;
75 
76 field
77     : field_name '=' value ';'
78         {
79             sem_field_end();
80         }
81     ;
82 
83 field_name
84     : NAME
85         {
86             sem_field(*$1);
87             delete $1;
88         }
89     ;
90 
91 value
92     : integer
93         {
94             sem_integer($1);
95         }
96     | real
97         {
98             sem_real($1);
99         }
100     | string
101         {
102             sem_string(*$1);
103             delete $1;
104         }
105     | structure
106     | list
107     | enumeration
108     ;
109 
110 integer
111     : INTEGER
112         { $$ = $1; }
113     | '-' INTEGER
114         { $$ = -$2; }
115     ;
116 
117 real
118     : REAL
119         { $$ = $1; }
120     | '-' REAL
121         { $$ = -$2; }
122     ;
123 
124 string
125     : STRING
126         { $$ = $1; }
127     | string STRING
128         {
129             nstring result = *$1 + *$2;
130             delete $1;
131             delete $2;
132             $$ = new nstring(result);
133         }
134     ;
135 
136 structure
137     : '{' field_list '}'
138     ;
139 
140 list
141     : '[' optional_value_list ']'
142     ;
143 
144 optional_value_list
145     : /* empty */
146     | value_list optional_comma
147     ;
148 
149 value_list
150     : list_value
151     | value_list ',' list_value
152     ;
153 
154 list_value
155     : { sem_list(); } value { sem_list_end(); }
156     ;
157 
158 optional_comma
159     : /* empty */
160     | ','
161     ;
162 
163 enumeration
164     : NAME
165         {
166             sem_enum(*$1);
167             delete $1;
168         }
169     ;
170 
171 
172 /* vim: set ts=8 sw=4 et : */
173