aboutsummaryrefslogtreecommitdiff
path: root/lib/forlangrm.y
diff options
context:
space:
mode:
Diffstat (limited to 'lib/forlangrm.y')
-rw-r--r--lib/forlangrm.y237
1 files changed, 237 insertions, 0 deletions
diff --git a/lib/forlangrm.y b/lib/forlangrm.y
new file mode 100644
index 0000000..1b7781d
--- /dev/null
+++ b/lib/forlangrm.y
@@ -0,0 +1,237 @@
1%{
2/* This file is part of Eclat.
3 Copyright (C) 2012 Sergey Poznyakoff.
4
5 Eclat is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 Eclat is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Eclat. If not, see <http://www.gnu.org/licenses/>. */
17
18#include "libeclat.h"
19#include <grecs.h>
20#include <grecs-locus.h>
21#include "forlangrm.h"
22#include "forlan.h"
23
24static int yyerror(char *);
25union forlan_node *forlan_parse_tree;
26%}
27%error-verbose
28%locations
29
30%union {
31 char *string;
32 union forlan_node *node;
33 struct grecs_list *list;
34};
35
36%token <string> STRING IDENT
37%token LAST IF ELSE
38
39%left OR
40%left AND
41%left NOT
42
43%type <node> stmt stmt_cond stmt_expr stmt_blk cond bool node comp funcall arg
44%type <list> stmtlist complist arglist
45%type <string> string
46
47%%
48input : stmtlist
49 {
50 forlan_parse_tree = forlan_stmt_from_list($1);
51 }
52 ;
53
54stmtlist : stmt
55 {
56 $$ = forlan_stmt_list();
57 grecs_list_append($$, $1);
58 }
59 | stmtlist stmt
60 {
61 grecs_list_append($1, $2);
62 $$ = $1;
63 }
64 ;
65
66stmt : stmt_cond
67 | stmt_expr
68 | stmt_blk
69 ;
70
71stmt_blk : '{' stmtlist '}'
72 {
73 $$ = forlan_stmt_from_list($2);
74 }
75 ;
76
77stmt_cond : IF cond stmt
78 {
79 $$ = forlan_node_create(forlan_type_cond);
80 $$->cond.expr = $2;
81 $$->cond.iftrue = $3;
82 $$->cond.iffalse = NULL;
83 }
84 | IF cond stmt ELSE stmt
85 {
86 $$ = forlan_node_create(forlan_type_cond);
87 $$->cond.expr = $2;
88 $$->cond.iftrue = $3;
89 $$->cond.iffalse = $5;
90 }
91 ;
92
93cond : bool
94 ;
95
96bool : node
97 {
98 $$ = forlan_node_create(forlan_type_expr);
99 $$->expr.opcode = forlan_opcode_node;
100 $$->expr.arg[0] = $1;
101 }
102 | bool AND bool
103 {
104 $$ = forlan_node_create(forlan_type_expr);
105 $$->expr.opcode = forlan_opcode_and;
106 $$->expr.arg[0] = $1;
107 $$->expr.arg[1] = $3;
108 }
109 | bool OR bool
110 {
111 $$ = forlan_node_create(forlan_type_expr);
112 $$->expr.opcode = forlan_opcode_or;
113 $$->expr.arg[0] = $1;
114 $$->expr.arg[1] = $3;
115 }
116 | NOT bool
117 {
118 $$ = forlan_node_create(forlan_type_expr);
119 $$->expr.opcode = forlan_opcode_not;
120 $$->expr.arg[0] = $2;
121 }
122 | '(' bool ')'
123 {
124 $$ = $2;
125 }
126 ;
127
128node : complist
129 {
130 $$ = forlan_node_create(forlan_type_comp);
131 $$->comp.abs = 0;
132 $$->comp.node = forlan_stmt_from_list($1);
133 }
134 | '.' complist
135 {
136 $$ = forlan_node_create(forlan_type_comp);
137 $$->comp.abs = 1;
138 $$->comp.node = forlan_stmt_from_list($2);
139 }
140 | LAST
141 {
142 $$ = forlan_node_create(forlan_type_last);
143 }
144 ;
145
146complist : comp
147 {
148 $$ = forlan_stmt_list();
149 grecs_list_append($$, $1);
150 }
151 | complist '.' comp
152 {
153 grecs_list_append($1, $3);
154 $$ = $1;
155 }
156 ;
157
158comp : IDENT
159 {
160 $$ = forlan_node_create(forlan_type_lit);
161 $$->lit.string = $1;
162 }
163 | IDENT '[' string ']'
164 {
165 $$ = forlan_node_create(forlan_type_test);
166 $$->test.comp = $1;
167 $$->test.value = $3;
168 }
169 | funcall
170 ;
171
172string : IDENT
173 | STRING
174 ;
175
176funcall : IDENT '(' ')'
177 {
178 $$ = forlan_node_create(forlan_type_func);
179 $$->func.fp = $1; //FIXME
180 $$->func.args = NULL;
181 }
182 | IDENT '(' arglist ')'
183 {
184 $$ = forlan_node_create(forlan_type_func);
185 $$->func.fp = $1; //FIXME
186 $$->func.args = $3;
187 }
188 ;
189
190arglist : arg
191 {
192 $$ = forlan_stmt_list();
193 grecs_list_append($$, $1);
194 }
195 | arglist ',' arg
196 {
197 grecs_list_append($1, $3);
198 $$ = $1;
199 }
200 ;
201
202arg : node
203 | STRING
204 {
205 $$ = forlan_node_create(forlan_type_lit);
206 $$->lit.string = $1;
207 }
208 ;
209
210stmt_expr : funcall ';'
211 ;
212%%
213static int
214yyerror(char *s)
215{
216 grecs_error(&yylloc, 0, "%s", s);
217 return 0;
218}
219
220int
221forlan_parser()
222{
223 yydebug = debug_level(forlan_dbg) >= FORLAN_DBG_GRAM;
224 return yyparse();
225}
226
227int
228forlan_parse(const char *input, size_t length, struct grecs_locus_point *pt)
229{
230 int rc;
231 forlan_lex_begin(input, length, pt);
232 rc = forlan_parser();
233 forlan_lex_end();
234 return rc;
235}
236
237

Return to:

Send suggestions and report system problems to the System administrator.