2016-10-12 21:40:11 +00:00
|
|
|
;;; -*-scheme-*-
|
|
|
|
|
|
|
|
;;; Mes --- Maxwell Equations of Software
|
|
|
|
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
|
|
|
|
;;;
|
|
|
|
;;; parser.mes: This file is part of Mes.
|
|
|
|
;;;
|
|
|
|
;;; Mes is free software; you can redistribute it and/or modify it
|
|
|
|
;;; under the terms of the GNU General Public License as published by
|
|
|
|
;;; the Free Software Foundation; either version 3 of the License, or (at
|
|
|
|
;;; your option) any later version.
|
|
|
|
;;;
|
|
|
|
;;; Mes is distributed in the hope that it will be useful, but
|
|
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
;;; GNU General Public License for more details.
|
|
|
|
;;;
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
|
|
|
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
;;; parser.mes is a translation of cgram.y to Dominique Boucher's LALR.
|
|
|
|
;;; It parses a minimal int main () {}, see examples/main.c
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
2016-07-24 21:18:53 +00:00
|
|
|
(cond-expand
|
|
|
|
(guile
|
2016-12-17 09:57:38 +00:00
|
|
|
(use-modules (system base lalr)))
|
2016-07-24 21:18:53 +00:00
|
|
|
(mes
|
2016-12-07 19:26:41 +00:00
|
|
|
(mes-use-module (mes lalr))))
|
2016-07-24 21:18:53 +00:00
|
|
|
|
2016-11-21 08:36:32 +00:00
|
|
|
(gc)
|
2016-07-24 21:18:53 +00:00
|
|
|
(define c-parser
|
|
|
|
(lalr-parser
|
|
|
|
|
|
|
|
(lbrace rbrace lparen rparen lbracket rbracket semicolon colon dot comma
|
|
|
|
=
|
2016-08-13 23:44:42 +00:00
|
|
|
Identifier NumericLiteral StringLiteral
|
2016-07-24 21:18:53 +00:00
|
|
|
break case continue goto label
|
|
|
|
return switch
|
2016-08-14 12:42:52 +00:00
|
|
|
for
|
2016-11-20 20:17:49 +00:00
|
|
|
If else
|
2016-07-24 21:18:53 +00:00
|
|
|
(left: or && ! * / + -)
|
|
|
|
(left: bool double float enum void int struct)
|
2016-08-14 12:42:52 +00:00
|
|
|
(left: < > <= >=)
|
|
|
|
(left: ++ --)
|
2016-07-24 21:18:53 +00:00
|
|
|
(nonassoc: == !=)
|
|
|
|
)
|
|
|
|
|
|
|
|
(program
|
|
|
|
(translation-unit *eoi*) : `(root ,@$1))
|
|
|
|
|
|
|
|
(translation-unit
|
|
|
|
(external-declaration) : `(,$1)
|
|
|
|
(translation-unit external-declaration) : `(,@$1 ,@$2))
|
|
|
|
|
|
|
|
(external-declaration
|
|
|
|
(function-definition) : $1
|
|
|
|
(declaration) : $1
|
|
|
|
(error semicolon) : (begin (syntax-error "external declaration" @1 $1) '()))
|
|
|
|
|
|
|
|
(function-definition
|
|
|
|
(declarator compound-statement) : `(function ,$1 (signature int (formals)) ,$2)
|
|
|
|
(declaration-specifiers declarator compound-statement) : `(function ,$2 (signature ,$1 (formals)) ,$3)
|
|
|
|
(declaration-specifiers declarator declaration-list compound-statement) : `(function ,$2 (signature ,$1 ,$3) ,$4))
|
|
|
|
|
|
|
|
(declaration
|
|
|
|
(declaration-specifiers semicolon) : `(,$1)
|
2016-08-14 12:42:52 +00:00
|
|
|
(declaration-specifiers init-declarator-list semicolon): `((,@$1 ,@$2))
|
2016-07-24 21:18:53 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
(declaration-list
|
2016-08-14 12:42:52 +00:00
|
|
|
(declaration) : `(formals ,@$1)
|
2016-07-24 21:18:53 +00:00
|
|
|
(declaration-list declaration) : `(,@$1 ,@(cdr $2)))
|
|
|
|
|
|
|
|
(declaration-specifiers
|
|
|
|
;;(storage-class-specifier) : `(,$1)
|
|
|
|
(type-specifier) : `(,$1)
|
|
|
|
;;(type-qualifier) : `($1)
|
|
|
|
;;(storage-class-specifier declaration-specifiers) : (cons $1 $2)
|
2016-08-14 12:42:52 +00:00
|
|
|
(type-specifier declaration-specifiers) : `(,$1 ,$2)
|
2016-07-24 21:18:53 +00:00
|
|
|
;;(type-qualifier declaration-specifiers) : (cons $1 $2)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; (storage_class_specifier
|
|
|
|
;; (auto)
|
|
|
|
;; (extern)
|
|
|
|
;; (register)
|
|
|
|
;; (static)
|
|
|
|
;; (typedef))
|
|
|
|
|
|
|
|
(type-specifier
|
|
|
|
;; (char) : $1
|
|
|
|
;; (double) : $1
|
|
|
|
;; (void) : $1
|
|
|
|
;; (float)
|
|
|
|
(int) : 'int
|
|
|
|
;; (long)
|
|
|
|
;; (short)
|
|
|
|
;; (unsigned)
|
|
|
|
;; (struct-or-enum-specifier)
|
|
|
|
;; (enum-specifier)
|
|
|
|
;; (type-name)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; (type-qualifier
|
|
|
|
;; (const)
|
|
|
|
;; (volatile))
|
|
|
|
|
|
|
|
;; struct_or_union_specifier:
|
|
|
|
;; struct_or_union_ident lbrace struct_declaration_list rbrace
|
|
|
|
;; | struct_or_union_ident
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; struct_or_union_ident: struct_or_union
|
|
|
|
;; | struct_or_union Identifier
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; struct_or_union: STRUCT { ; }
|
|
|
|
;; | UNION { ; }
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; struct_declaration_list: struct_declaration
|
|
|
|
;; | struct_declaration_list struct_declaration
|
|
|
|
;; ;
|
|
|
|
|
2016-08-14 12:42:52 +00:00
|
|
|
(init-declarator-list
|
|
|
|
;; (init-declarator %prec comma) : `(,$1) HUH?
|
|
|
|
(init-declarator) : `(,$1)
|
|
|
|
(init-declarator-list comma init-declarator) : `(,$1)
|
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
;; init_declarator_list: init_declarator %prec comma
|
|
|
|
;; | init_declarator_list comma init_declarator
|
|
|
|
;; ;
|
|
|
|
|
2016-08-14 12:42:52 +00:00
|
|
|
(init-declarator
|
|
|
|
(declarator) : $1
|
|
|
|
(declarator = initializer) : `(= ,$1 ,$3)
|
|
|
|
;; | error { yyerror("init declarator error"); }
|
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
;; struct_declaration: specifier_qualifier_list struct_declarator_list semicolon
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; specifier_qualifier_list: type_specifier
|
|
|
|
;; | type_qualifier
|
|
|
|
;; | type_specifier specifier_qualifier_list
|
|
|
|
;; | type_qualifier specifier_qualifier_list
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; struct_declarator_list: struct_declarator
|
|
|
|
;; | struct_declarator_list comma struct_declarator
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; struct_declarator: declarator
|
|
|
|
;; | COLON constant_expression { ; }
|
|
|
|
;; | declarator COLON constant_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; enum_specifier: ENUM Identifier lbrace enumerator_list rbrace { ; }
|
|
|
|
;; | ENUM lbrace enumerator_list rbrace { ; }
|
|
|
|
;; | ENUM Identifier { ; }
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; enumerator_list: enumerator
|
|
|
|
;; | enumerator_list comma enumerator
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; enumerator: Identifier
|
|
|
|
;; | Identifier EQ constant_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
(declarator
|
|
|
|
(direct-declarator) : $1
|
|
|
|
;;(pointer direct-declarator)
|
|
|
|
)
|
|
|
|
|
|
|
|
(direct-declarator
|
|
|
|
(Identifier) : $1
|
|
|
|
;; (lparen declarator rparen)
|
|
|
|
;; (direct-declarator lbracket rbracket)
|
|
|
|
;; (direct-declarator lbracket constant-expression rbracket)
|
|
|
|
;; (lbracket constant-expression rbracket)
|
|
|
|
;; (direct-declarator lparen parameter-type-list rparen)
|
|
|
|
(direct-declarator lparen rparen) : $1
|
|
|
|
;; (direct-declarator lparen identifier-list rparen)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; pointer: STAR { ; }
|
|
|
|
;; | STAR pointer { ; }
|
|
|
|
;; | STAR type_qualifier_list { ; }
|
|
|
|
;; | STAR type_qualifier_list pointer { ; }
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; type_qualifier_list: type_qualifier
|
|
|
|
;; | type_qualifier_list type_qualifier
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; parameter_type_list: parameter_list
|
|
|
|
;; | parameter_list comma ELLIPSIS
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; parameter_list: parameter_declaration
|
|
|
|
;; | parameter_list comma parameter_declaration
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; parameter_declaration:
|
|
|
|
;; declaration_specifiers declarator
|
|
|
|
;; | declaration_specifiers
|
|
|
|
;; | declaration_specifiers abstract_declarator
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; identifier_list: Identifier
|
|
|
|
;; | identifier_list comma Identifier
|
|
|
|
;; | error { yyerror("identifier list error"); }
|
|
|
|
;; ;
|
|
|
|
|
2016-08-14 12:42:52 +00:00
|
|
|
(initializer
|
|
|
|
;;(assignment-expression %prec comma) HUH?
|
|
|
|
(assignment-expression) : $1
|
|
|
|
;; initializer: assignment_expression %prec comma
|
|
|
|
;; | lbrace initializer_list rbrace { ; }
|
|
|
|
;; | lbrace initializer_list comma rbrace { ; }
|
|
|
|
;; ;
|
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
;; initializer_list: initializer %prec comma
|
|
|
|
;; | initializer_list comma initializer
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; type_name: specifier_qualifier_list
|
|
|
|
;; | specifier_qualifier_list abstract_declarator
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; abstract_declarator: pointer
|
|
|
|
;; | direct_abstract_declarator
|
|
|
|
;; | pointer direct_abstract_declarator
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; direct_abstract_declarator:
|
|
|
|
;; lparen abstract_declarator rparen { ; }
|
|
|
|
;; | lbrace rbrace { ; }
|
|
|
|
;; | direct_abstract_declarator lbrace rbrace
|
|
|
|
;; | lbrace constant_expression rbrace { ; }
|
|
|
|
;; | direct_abstract_declarator lbrace constant_expression rbrace
|
|
|
|
;; | lparen rparen { ; }
|
|
|
|
;; | direct_abstract_declarator lparen rparen
|
|
|
|
;; | lparen parameter_list rparen { ; }
|
|
|
|
;; | direct_abstract_declarator lparen parameter_list rparen
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
|
|
|
|
(statement
|
|
|
|
;;(labeled-statement)
|
|
|
|
(expression-statement) : $1
|
|
|
|
(compound-statement) : $1
|
|
|
|
;;(selection-statement)
|
2016-08-14 12:42:52 +00:00
|
|
|
(iteration-statement) : $1
|
2016-07-24 21:18:53 +00:00
|
|
|
(jump-statement) : $1
|
|
|
|
(semicolon) : '()
|
|
|
|
(error semicolon) : (begin (syntax-error "statement error" @1 $1) '())
|
|
|
|
(error rbrace) : (begin (syntax-error "statement error" @1 $1) '()))
|
|
|
|
|
|
|
|
|
|
|
|
;; labeled_statement:
|
|
|
|
;; Identifier COLON statement
|
|
|
|
;; | CASE x COLON statement { ; }
|
|
|
|
;; | DEFAULT COLON statement { ; }
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
(expression-statement
|
|
|
|
(x semicolon) : $1)
|
|
|
|
|
|
|
|
(compound-statement
|
|
|
|
(lbrace rbrace) : '(compound)
|
2016-08-14 12:42:52 +00:00
|
|
|
(lbrace declaration-list rbrace) : `(compound ,$2)
|
2016-07-24 21:18:53 +00:00
|
|
|
(lbrace statement-list rbrace) : `(compound ,@$2)
|
2016-08-14 12:42:52 +00:00
|
|
|
(lbrace declaration-list statement-list rbrace) : `(compound ,$2 ,@$3))
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
(statement-list
|
|
|
|
(statement) : `(,$1)
|
2016-08-13 23:44:42 +00:00
|
|
|
(statement-list statement) : `(,@$1 ,$2))
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
;; selection_statement:
|
|
|
|
;; IF lparen x rparen statement { ; }
|
|
|
|
;; | IF lparen x rparen statement ELSE statement { ; }
|
|
|
|
;; | SWITCH lparen x rparen statement { ; }
|
|
|
|
;; ;
|
|
|
|
|
2016-08-14 12:42:52 +00:00
|
|
|
(iteration-statement
|
|
|
|
;; iteration_statement:
|
|
|
|
;; WHILE lparen x rparen statement { ; }
|
|
|
|
;; | DO statement WHILE lparen x rparen semicolon { ; }
|
|
|
|
(for lparen forcntrl rparen statement) : `(for ,@$3 ,$5))
|
|
|
|
|
|
|
|
(forcntrl
|
|
|
|
;; | semicolon semicolon x { ; }
|
|
|
|
;; | semicolon x semicolon { ; }
|
|
|
|
;; | semicolon x semicolon x { ; }
|
|
|
|
;; | x semicolon semicolon
|
|
|
|
;; | x semicolon semicolon x
|
|
|
|
;; | x semicolon x semicolon
|
|
|
|
(x semicolon x semicolon x) : `((start ,$1) (test ,$3) (step ,$5)))
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
(jump-statement
|
2016-08-14 12:42:52 +00:00
|
|
|
(goto Identifier semicolon) : `(goto ,$2)
|
2016-07-24 21:18:53 +00:00
|
|
|
(continue semicolon) : '(continue)
|
|
|
|
(break semicolon) : '(break)
|
|
|
|
(return semicolon) : '(return)
|
|
|
|
(return x semicolon) : `(return ,$2))
|
|
|
|
|
|
|
|
(x
|
|
|
|
(assignment-expression) : $1
|
2016-08-14 12:42:52 +00:00
|
|
|
(x comma assignment-expression) : `(,$1 ,@$3))
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
(assignment-expression
|
2016-08-14 12:42:52 +00:00
|
|
|
(equality-expression) : $1 ;; skip some
|
|
|
|
;;(conditional-expression) : $1
|
2016-07-24 21:18:53 +00:00
|
|
|
(unary-expression assignment-operator assignment-expression) : `(,$2 ,$1 ,$3))
|
|
|
|
|
|
|
|
(assignment-operator
|
2016-08-14 12:42:52 +00:00
|
|
|
(=) : '=)
|
2016-07-24 21:18:53 +00:00
|
|
|
;; | PLUSEQ { ; }
|
|
|
|
;; | MINUSEQ { ; }
|
|
|
|
;; | MUEQ { ; }
|
|
|
|
;; | DIVEQ { ; }
|
|
|
|
;; | MODEQ { ; }
|
|
|
|
;; | SLEQ { ; }
|
|
|
|
;; | SREQ { ; }
|
|
|
|
;; | ANEQ { ; }
|
|
|
|
;; | OREQ { ; }
|
|
|
|
;; | XOREQ { ; }
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; conditional_expression: logical_or_expression
|
|
|
|
;; | logical_or_expression IF_THEN x COLON conditional_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; constant_expression: conditional_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; logical_or_expression: logical_and_expression
|
|
|
|
;; | logical_or_expression OROR logical_and_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; logical_and_expression: inclusive_or_expression
|
|
|
|
;; | logical_and_expression ANDAND inclusive_or_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; inclusive_or_expression: exclusive_or_expression
|
|
|
|
;; | inclusive_or_expression OR exclusive_or_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; exclusive_or_expression: and_expression
|
|
|
|
;; | exclusive_or_expression XOR and_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; and_expression: equality_expression
|
|
|
|
;; | and_expression AND equality_expression
|
|
|
|
;; ;
|
|
|
|
|
2016-08-14 12:42:52 +00:00
|
|
|
(equality-expression
|
|
|
|
(relational-expression) : $1
|
|
|
|
(equality-expression == relational-expression) : `(== ,$1 ,$3)
|
|
|
|
(equality-expression != relational-expression) : `(!= ,$1 ,$3))
|
|
|
|
|
|
|
|
(relational-expression
|
|
|
|
(shift-expression) : $1
|
|
|
|
(relational-expression < shift-expression) : `(< ,$1 ,$3)
|
|
|
|
(relational-expression <= shift-expression) : `(<= ,$1 ,$3)
|
|
|
|
(relational-expression > shift-expression) : `(> ,$1 ,$3)
|
|
|
|
(relational-expression >= shift-expression) : `(>= ,$1 ,$3))
|
|
|
|
|
|
|
|
(shift-expression
|
|
|
|
(unary-expression) : $1 ;; skip some
|
|
|
|
;; shift_expression: additive_expression
|
|
|
|
;; | shift_expression LTLT additive_expression
|
|
|
|
;; | shift_expression GTGT additive_expression
|
|
|
|
;; ;
|
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
;; additive_expression: multiplicative_expression
|
|
|
|
;; | additive_expression PLUS multiplicative_expression
|
|
|
|
;; | additive_expression MINUS multiplicative_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; multiplicative_expression: cast_expression
|
|
|
|
;; | multiplicative_expression STAR cast_expression
|
|
|
|
;; | multiplicative_expression DIV cast_expression
|
|
|
|
;; | multiplicative_expression MOD cast_expression
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
;; cast_expression: unary_expression
|
|
|
|
;; | lparen type_name rparen cast_expression { ; }
|
|
|
|
;; ;
|
|
|
|
|
|
|
|
(unary-expression
|
2016-08-13 23:44:42 +00:00
|
|
|
(postfix-expression) : $1
|
2016-08-14 12:42:52 +00:00
|
|
|
(++ unary-expression) : `(++x ,$2)
|
|
|
|
(-- unary-expression) : `(--x ,$2)
|
2016-07-24 21:18:53 +00:00
|
|
|
;; | SIZEOF unary_expression { ; }
|
|
|
|
;; | SIZEOF lparen type_name rparen %prec SIZEOF { ; }
|
|
|
|
;; | STAR cast_expression { ; }
|
|
|
|
;; | AND cast_expression { ; }
|
|
|
|
;; | MINUS cast_expression { ; }
|
|
|
|
;; | PLUS cast_expression { ; }
|
|
|
|
;; | NEG cast_expression { ; }
|
|
|
|
;; | NOT cast_expression { ; }
|
|
|
|
;; ;
|
2016-08-14 12:42:52 +00:00
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
|
2016-08-13 23:44:42 +00:00
|
|
|
(postfix-expression
|
|
|
|
(primary-expression) : $1
|
2016-08-14 12:42:52 +00:00
|
|
|
;; | postfix_expression lbracket x rbracket
|
2016-08-13 23:44:42 +00:00
|
|
|
(postfix-expression lparen rparen) : `(call ,$1 (arguments))
|
2016-08-14 12:42:52 +00:00
|
|
|
(postfix-expression lparen argument-expression-list rparen) : `(call ,$1 ,$3)
|
|
|
|
;; | postfix_expression FOLLOW Identifier
|
|
|
|
;; | postfix_expression DOT Identifier
|
|
|
|
(postfix-expression ++) : `(x++ ,$1)
|
|
|
|
(postfix-expression --) : `(x-- ,$1)
|
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
|
|
|
|
(primary-expression
|
|
|
|
(Identifier): $1
|
2016-08-13 23:44:42 +00:00
|
|
|
(NumericLiteral) : $1
|
2016-08-14 12:42:52 +00:00
|
|
|
;; INT_LITERAL
|
|
|
|
;; CHAR_LITERAL
|
|
|
|
;; FLOAT_LITERAL
|
|
|
|
;; STRING_LITERAL
|
2016-08-13 23:44:42 +00:00
|
|
|
(StringLiteral) : $1
|
2016-08-14 12:42:52 +00:00
|
|
|
;; lparen x rparen
|
2016-08-13 23:44:42 +00:00
|
|
|
)
|
2016-07-24 21:18:53 +00:00
|
|
|
;;
|
|
|
|
|
2016-08-13 23:44:42 +00:00
|
|
|
(argument-expression-list
|
|
|
|
(assignment-expression) : `(arguments ,$1)
|
2016-08-14 12:42:52 +00:00
|
|
|
(argument-expression-list comma assignment-expression): `(,@$1 ,@(cdr $3)))))
|