3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;; parser.mes: This file is part of Mes.
8 ;;; Mes is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
13 ;;; Mes is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;;; GNU General Public License for more details.
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
23 ;;; parser.mes is a translation of cgram.y to Dominique Boucher's LALR.
24 ;;; It parses a minimal int main () {}, see examples/main.c
30 ;;(use-modules (srfi srfi-1))
31 (use-modules (system base lalr))
32 ;;(use-modules (ice-9 match))
35 (mes-use-module (mes lalr))))
41 (lbrace rbrace lparen rparen lbracket rbracket semicolon colon dot comma
43 Identifier NumericLiteral StringLiteral
44 break case continue goto label
48 (left: or && ! * / + -)
49 (left: bool double float enum void int struct)
56 (translation-unit *eoi*) : `(root ,@$1))
59 (external-declaration) : `(,$1)
60 (translation-unit external-declaration) : `(,@$1 ,@$2))
63 (function-definition) : $1
65 (error semicolon) : (begin (syntax-error "external declaration" @1 $1) '()))
68 (declarator compound-statement) : `(function ,$1 (signature int (formals)) ,$2)
69 (declaration-specifiers declarator compound-statement) : `(function ,$2 (signature ,$1 (formals)) ,$3)
70 (declaration-specifiers declarator declaration-list compound-statement) : `(function ,$2 (signature ,$1 ,$3) ,$4))
73 (declaration-specifiers semicolon) : `(,$1)
74 (declaration-specifiers init-declarator-list semicolon): `((,@$1 ,@$2))
78 (declaration) : `(formals ,@$1)
79 (declaration-list declaration) : `(,@$1 ,@(cdr $2)))
81 (declaration-specifiers
82 ;;(storage-class-specifier) : `(,$1)
83 (type-specifier) : `(,$1)
84 ;;(type-qualifier) : `($1)
85 ;;(storage-class-specifier declaration-specifiers) : (cons $1 $2)
86 (type-specifier declaration-specifiers) : `(,$1 ,$2)
87 ;;(type-qualifier declaration-specifiers) : (cons $1 $2)
90 ;; (storage_class_specifier
106 ;; (struct-or-enum-specifier)
115 ;; struct_or_union_specifier:
116 ;; struct_or_union_ident lbrace struct_declaration_list rbrace
117 ;; | struct_or_union_ident
120 ;; struct_or_union_ident: struct_or_union
121 ;; | struct_or_union Identifier
124 ;; struct_or_union: STRUCT { ; }
128 ;; struct_declaration_list: struct_declaration
129 ;; | struct_declaration_list struct_declaration
132 (init-declarator-list
133 ;; (init-declarator %prec comma) : `(,$1) HUH?
134 (init-declarator) : `(,$1)
135 (init-declarator-list comma init-declarator) : `(,$1)
137 ;; init_declarator_list: init_declarator %prec comma
138 ;; | init_declarator_list comma init_declarator
143 (declarator = initializer) : `(= ,$1 ,$3)
144 ;; | error { yyerror("init declarator error"); }
147 ;; struct_declaration: specifier_qualifier_list struct_declarator_list semicolon
150 ;; specifier_qualifier_list: type_specifier
152 ;; | type_specifier specifier_qualifier_list
153 ;; | type_qualifier specifier_qualifier_list
156 ;; struct_declarator_list: struct_declarator
157 ;; | struct_declarator_list comma struct_declarator
160 ;; struct_declarator: declarator
161 ;; | COLON constant_expression { ; }
162 ;; | declarator COLON constant_expression
165 ;; enum_specifier: ENUM Identifier lbrace enumerator_list rbrace { ; }
166 ;; | ENUM lbrace enumerator_list rbrace { ; }
167 ;; | ENUM Identifier { ; }
170 ;; enumerator_list: enumerator
171 ;; | enumerator_list comma enumerator
174 ;; enumerator: Identifier
175 ;; | Identifier EQ constant_expression
179 (direct-declarator) : $1
180 ;;(pointer direct-declarator)
185 ;; (lparen declarator rparen)
186 ;; (direct-declarator lbracket rbracket)
187 ;; (direct-declarator lbracket constant-expression rbracket)
188 ;; (lbracket constant-expression rbracket)
189 ;; (direct-declarator lparen parameter-type-list rparen)
190 (direct-declarator lparen rparen) : $1
191 ;; (direct-declarator lparen identifier-list rparen)
194 ;; pointer: STAR { ; }
195 ;; | STAR pointer { ; }
196 ;; | STAR type_qualifier_list { ; }
197 ;; | STAR type_qualifier_list pointer { ; }
200 ;; type_qualifier_list: type_qualifier
201 ;; | type_qualifier_list type_qualifier
204 ;; parameter_type_list: parameter_list
205 ;; | parameter_list comma ELLIPSIS
208 ;; parameter_list: parameter_declaration
209 ;; | parameter_list comma parameter_declaration
212 ;; parameter_declaration:
213 ;; declaration_specifiers declarator
214 ;; | declaration_specifiers
215 ;; | declaration_specifiers abstract_declarator
218 ;; identifier_list: Identifier
219 ;; | identifier_list comma Identifier
220 ;; | error { yyerror("identifier list error"); }
224 ;;(assignment-expression %prec comma) HUH?
225 (assignment-expression) : $1
226 ;; initializer: assignment_expression %prec comma
227 ;; | lbrace initializer_list rbrace { ; }
228 ;; | lbrace initializer_list comma rbrace { ; }
232 ;; initializer_list: initializer %prec comma
233 ;; | initializer_list comma initializer
236 ;; type_name: specifier_qualifier_list
237 ;; | specifier_qualifier_list abstract_declarator
240 ;; abstract_declarator: pointer
241 ;; | direct_abstract_declarator
242 ;; | pointer direct_abstract_declarator
245 ;; direct_abstract_declarator:
246 ;; lparen abstract_declarator rparen { ; }
247 ;; | lbrace rbrace { ; }
248 ;; | direct_abstract_declarator lbrace rbrace
249 ;; | lbrace constant_expression rbrace { ; }
250 ;; | direct_abstract_declarator lbrace constant_expression rbrace
251 ;; | lparen rparen { ; }
252 ;; | direct_abstract_declarator lparen rparen
253 ;; | lparen parameter_list rparen { ; }
254 ;; | direct_abstract_declarator lparen parameter_list rparen
259 ;;(labeled-statement)
260 (expression-statement) : $1
261 (compound-statement) : $1
262 ;;(selection-statement)
263 (iteration-statement) : $1
264 (jump-statement) : $1
266 (error semicolon) : (begin (syntax-error "statement error" @1 $1) '())
267 (error rbrace) : (begin (syntax-error "statement error" @1 $1) '()))
270 ;; labeled_statement:
271 ;; Identifier COLON statement
272 ;; | CASE x COLON statement { ; }
273 ;; | DEFAULT COLON statement { ; }
276 (expression-statement
280 (lbrace rbrace) : '(compound)
281 (lbrace declaration-list rbrace) : `(compound ,$2)
282 (lbrace statement-list rbrace) : `(compound ,@$2)
283 (lbrace declaration-list statement-list rbrace) : `(compound ,$2 ,@$3))
287 (statement-list statement) : `(,@$1 ,$2))
289 ;; selection_statement:
290 ;; IF lparen x rparen statement { ; }
291 ;; | IF lparen x rparen statement ELSE statement { ; }
292 ;; | SWITCH lparen x rparen statement { ; }
296 ;; iteration_statement:
297 ;; WHILE lparen x rparen statement { ; }
298 ;; | DO statement WHILE lparen x rparen semicolon { ; }
299 (for lparen forcntrl rparen statement) : `(for ,@$3 ,$5))
302 ;; | semicolon semicolon x { ; }
303 ;; | semicolon x semicolon { ; }
304 ;; | semicolon x semicolon x { ; }
305 ;; | x semicolon semicolon
306 ;; | x semicolon semicolon x
307 ;; | x semicolon x semicolon
308 (x semicolon x semicolon x) : `((start ,$1) (test ,$3) (step ,$5)))
311 (goto Identifier semicolon) : `(goto ,$2)
312 (continue semicolon) : '(continue)
313 (break semicolon) : '(break)
314 (return semicolon) : '(return)
315 (return x semicolon) : `(return ,$2))
318 (assignment-expression) : $1
319 (x comma assignment-expression) : `(,$1 ,@$3))
321 (assignment-expression
322 (equality-expression) : $1 ;; skip some
323 ;;(conditional-expression) : $1
324 (unary-expression assignment-operator assignment-expression) : `(,$2 ,$1 ,$3))
340 ;; conditional_expression: logical_or_expression
341 ;; | logical_or_expression IF_THEN x COLON conditional_expression
344 ;; constant_expression: conditional_expression
347 ;; logical_or_expression: logical_and_expression
348 ;; | logical_or_expression OROR logical_and_expression
351 ;; logical_and_expression: inclusive_or_expression
352 ;; | logical_and_expression ANDAND inclusive_or_expression
355 ;; inclusive_or_expression: exclusive_or_expression
356 ;; | inclusive_or_expression OR exclusive_or_expression
359 ;; exclusive_or_expression: and_expression
360 ;; | exclusive_or_expression XOR and_expression
363 ;; and_expression: equality_expression
364 ;; | and_expression AND equality_expression
368 (relational-expression) : $1
369 (equality-expression == relational-expression) : `(== ,$1 ,$3)
370 (equality-expression != relational-expression) : `(!= ,$1 ,$3))
372 (relational-expression
373 (shift-expression) : $1
374 (relational-expression < shift-expression) : `(< ,$1 ,$3)
375 (relational-expression <= shift-expression) : `(<= ,$1 ,$3)
376 (relational-expression > shift-expression) : `(> ,$1 ,$3)
377 (relational-expression >= shift-expression) : `(>= ,$1 ,$3))
380 (unary-expression) : $1 ;; skip some
381 ;; shift_expression: additive_expression
382 ;; | shift_expression LTLT additive_expression
383 ;; | shift_expression GTGT additive_expression
386 ;; additive_expression: multiplicative_expression
387 ;; | additive_expression PLUS multiplicative_expression
388 ;; | additive_expression MINUS multiplicative_expression
391 ;; multiplicative_expression: cast_expression
392 ;; | multiplicative_expression STAR cast_expression
393 ;; | multiplicative_expression DIV cast_expression
394 ;; | multiplicative_expression MOD cast_expression
397 ;; cast_expression: unary_expression
398 ;; | lparen type_name rparen cast_expression { ; }
402 (postfix-expression) : $1
403 (++ unary-expression) : `(++x ,$2)
404 (-- unary-expression) : `(--x ,$2)
405 ;; | SIZEOF unary_expression { ; }
406 ;; | SIZEOF lparen type_name rparen %prec SIZEOF { ; }
407 ;; | STAR cast_expression { ; }
408 ;; | AND cast_expression { ; }
409 ;; | MINUS cast_expression { ; }
410 ;; | PLUS cast_expression { ; }
411 ;; | NEG cast_expression { ; }
412 ;; | NOT cast_expression { ; }
417 (primary-expression) : $1
418 ;; | postfix_expression lbracket x rbracket
419 (postfix-expression lparen rparen) : `(call ,$1 (arguments))
420 (postfix-expression lparen argument-expression-list rparen) : `(call ,$1 ,$3)
421 ;; | postfix_expression FOLLOW Identifier
422 ;; | postfix_expression DOT Identifier
423 (postfix-expression ++) : `(x++ ,$1)
424 (postfix-expression --) : `(x-- ,$1)
429 (NumericLiteral) : $1
439 (argument-expression-list
440 (assignment-expression) : `(arguments ,$1)
441 (argument-expression-list comma assignment-expression): `(,@$1 ,@(cdr $3)))))