mes/module/language/c/parser.mes

459 lines
14 KiB
Plaintext
Raw Normal View History

Prepare for 0.1 release: new directory structure. * scripts/elf.mes: New file. * scripts/include.mes: New file. * scripts/mescc.mes: New file. * scripts/paren.mes: New file. * scripts/repl.mes: New file. * doc/examples/main.c: Move from ./main.c. * module/mes/base-0.mes: Move from ./base0.mes. * module/mes/base.mes: Move from top. * module/mes/elf.mes: Likewise. * module/mes/let-syntax.mes: Likewise. * module/mes/let.mes: Likewise. * module/mes/mes.mes: Likewise. * module/mes/quasiquote.mes: Likewise. * module/mes/repl.mes: Likewise. * module/mes/scm.mes: Likewise. * module/mes/syntax.mes: Likewise. * module/mes/lalr-0.mes: Move from lib/lalr.mes. * module/mes/lalr.mes: Move from lib/lalr.scm. * module/mes/match.mes: Move from lib/match.scm. * module/mes/record-0.mes: Move from lib/record.mes. * module/mes/record.mes: Move from lib/record.scm. * module/mes/test.mes: Move flom lib/. * module/rnrs/bytevectors.mes: Move from lib/rnrs. * module/srfi/srfi-0.mes: Move from lib/srfi. * module/srfi/srfi-1.mes: Likewise. * module/srfi/srfi-9.mes: Likewise. * module/language/c/lexer.mes: Move from ./c-lexer.scm. * module/language/c/parser.mes: Move from ./mescc.scm. * module/language/c/compiler.mes: New file, split from parser.mes. * module/language/paren.mes: Move from ./paren.scm. * module/mes/libc-i386.mes: New file, split from elf.mes. * tests/base.test: Move from test/. * tests/closure.test: Likewise. * tests/let-syntax.test: Likewise. * tests/let.test: Likewise. * tests/match.test: Likewise. * tests/quasiquote.test: Likewise. * tests/record.test: Likewise. * tests/scm.test: Likewise. * hello.S: Remove. * hello.c: Remove. * loop2.mes: Remove. * test/foo.test: Remove.
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
Prepare for 0.1 release: new directory structure. * scripts/elf.mes: New file. * scripts/include.mes: New file. * scripts/mescc.mes: New file. * scripts/paren.mes: New file. * scripts/repl.mes: New file. * doc/examples/main.c: Move from ./main.c. * module/mes/base-0.mes: Move from ./base0.mes. * module/mes/base.mes: Move from top. * module/mes/elf.mes: Likewise. * module/mes/let-syntax.mes: Likewise. * module/mes/let.mes: Likewise. * module/mes/mes.mes: Likewise. * module/mes/quasiquote.mes: Likewise. * module/mes/repl.mes: Likewise. * module/mes/scm.mes: Likewise. * module/mes/syntax.mes: Likewise. * module/mes/lalr-0.mes: Move from lib/lalr.mes. * module/mes/lalr.mes: Move from lib/lalr.scm. * module/mes/match.mes: Move from lib/match.scm. * module/mes/record-0.mes: Move from lib/record.mes. * module/mes/record.mes: Move from lib/record.scm. * module/mes/test.mes: Move flom lib/. * module/rnrs/bytevectors.mes: Move from lib/rnrs. * module/srfi/srfi-0.mes: Move from lib/srfi. * module/srfi/srfi-1.mes: Likewise. * module/srfi/srfi-9.mes: Likewise. * module/language/c/lexer.mes: Move from ./c-lexer.scm. * module/language/c/parser.mes: Move from ./mescc.scm. * module/language/c/compiler.mes: New file, split from parser.mes. * module/language/paren.mes: Move from ./paren.scm. * module/mes/libc-i386.mes: New file, split from elf.mes. * tests/base.test: Move from test/. * tests/closure.test: Likewise. * tests/let-syntax.test: Likewise. * tests/let.test: Likewise. * tests/match.test: Likewise. * tests/quasiquote.test: Likewise. * tests/record.test: Likewise. * tests/scm.test: Likewise. * hello.S: Remove. * hello.c: Remove. * loop2.mes: Remove. * test/foo.test: Remove.
2016-10-12 21:40:11 +00:00
(use-modules (srfi srfi-1))
;;(use-modules (system base lalr))
(use-modules (ice-9 match)))
2016-07-24 21:18:53 +00:00
(mes
Prepare for 0.1 release: new directory structure. * scripts/elf.mes: New file. * scripts/include.mes: New file. * scripts/mescc.mes: New file. * scripts/paren.mes: New file. * scripts/repl.mes: New file. * doc/examples/main.c: Move from ./main.c. * module/mes/base-0.mes: Move from ./base0.mes. * module/mes/base.mes: Move from top. * module/mes/elf.mes: Likewise. * module/mes/let-syntax.mes: Likewise. * module/mes/let.mes: Likewise. * module/mes/mes.mes: Likewise. * module/mes/quasiquote.mes: Likewise. * module/mes/repl.mes: Likewise. * module/mes/scm.mes: Likewise. * module/mes/syntax.mes: Likewise. * module/mes/lalr-0.mes: Move from lib/lalr.mes. * module/mes/lalr.mes: Move from lib/lalr.scm. * module/mes/match.mes: Move from lib/match.scm. * module/mes/record-0.mes: Move from lib/record.mes. * module/mes/record.mes: Move from lib/record.scm. * module/mes/test.mes: Move flom lib/. * module/rnrs/bytevectors.mes: Move from lib/rnrs. * module/srfi/srfi-0.mes: Move from lib/srfi. * module/srfi/srfi-1.mes: Likewise. * module/srfi/srfi-9.mes: Likewise. * module/language/c/lexer.mes: Move from ./c-lexer.scm. * module/language/c/parser.mes: Move from ./mescc.scm. * module/language/c/compiler.mes: New file, split from parser.mes. * module/language/paren.mes: Move from ./paren.scm. * module/mes/libc-i386.mes: New file, split from elf.mes. * tests/base.test: Move from test/. * tests/closure.test: Likewise. * tests/let-syntax.test: Likewise. * tests/let.test: Likewise. * tests/match.test: Likewise. * tests/quasiquote.test: Likewise. * tests/record.test: Likewise. * tests/scm.test: Likewise. * hello.S: Remove. * hello.c: Remove. * loop2.mes: Remove. * test/foo.test: Remove.
2016-10-12 21:40:11 +00:00
(mes-use-module (mes base-0))
(mes-use-module (mes base))
(mes-use-module (mes quasiquote))
(mes-use-module (mes let))
(mes-use-module (mes scm))
(mes-use-module (mes syntax))
(mes-use-module (srfi srfi-0))
(mes-use-module (mes record-0))
(mes-use-module (mes record))
(mes-use-module (srfi srfi-9))
(mes-use-module (mes lalr-0))
(mes-use-module (mes lalr))
(mes-use-module (mes let-syntax))
(mes-use-module (srfi srfi-1))
(mes-use-module (mes match))
(mes-use-module (rnrs bytevectors))
(mes-use-module (mes elf))
(mes-use-module (mes libc-i386))))
2016-07-24 21:18:53 +00:00
(define c-parser
(lalr-parser
(lbrace rbrace lparen rparen lbracket rbracket semicolon colon dot comma
=
Identifier NumericLiteral StringLiteral
2016-07-24 21:18:53 +00:00
break case continue goto label
return switch
for
If else
2016-07-24 21:18:53 +00:00
(left: or && ! * / + -)
(left: bool double float enum void int struct)
(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)
(declaration-specifiers init-declarator-list semicolon): `((,@$1 ,@$2))
2016-07-24 21:18:53 +00:00
)
(declaration-list
(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)
(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
;; ;
(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
;; ;
(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"); }
;; ;
(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)
(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)
(lbrace declaration-list rbrace) : `(compound ,$2)
2016-07-24 21:18:53 +00:00
(lbrace statement-list rbrace) : `(compound ,@$2)
(lbrace declaration-list statement-list rbrace) : `(compound ,$2 ,@$3))
2016-07-24 21:18:53 +00:00
(statement-list
(statement) : `(,$1)
(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 { ; }
;; ;
(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
(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
(x comma assignment-expression) : `(,$1 ,@$3))
2016-07-24 21:18:53 +00:00
(assignment-expression
(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-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
;; ;
(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
(postfix-expression) : $1
(++ 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-07-24 21:18:53 +00:00
(postfix-expression
(primary-expression) : $1
;; | postfix_expression lbracket x rbracket
(postfix-expression lparen rparen) : `(call ,$1 (arguments))
(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
(NumericLiteral) : $1
;; INT_LITERAL
;; CHAR_LITERAL
;; FLOAT_LITERAL
;; STRING_LITERAL
(StringLiteral) : $1
;; lparen x rparen
)
2016-07-24 21:18:53 +00:00
;;
(argument-expression-list
(assignment-expression) : `(arguments ,$1)
(argument-expression-list comma assignment-expression): `(,@$1 ,@(cdr $3)))))