Implemented read-yacc to convert a yacc grammar into a define-parser form.

Pascal J. Bourguignon [2015-07-06 20:44]
Implemented read-yacc to convert a yacc grammar into a define-parser form.
Filename
languages/c11/README
languages/c11/com.informatimago.languages.c11.asd
languages/c11/packages.lisp
languages/c11/parser.lisp
languages/c11/parser.yacc
languages/c11/read-yacc.lisp
languages/c11/scanner.lex
languages/c11/scanner.lisp
diff --git a/languages/c11/README b/languages/c11/README
new file mode 100644
index 0000000..0c0f10e
--- /dev/null
+++ b/languages/c11/README
@@ -0,0 +1,6 @@
+Implement a parser for the language ISO/IEC 9899:2011 (C11).
+
+
+
+http://www.quut.com/c/ANSI-C-grammar-l-2011.html
+http://www.quut.com/c/ANSI-C-grammar-y.html
diff --git a/languages/c11/com.informatimago.languages.c11.asd b/languages/c11/com.informatimago.languages.c11.asd
new file mode 100644
index 0000000..1a3c272
--- /dev/null
+++ b/languages/c11/com.informatimago.languages.c11.asd
@@ -0,0 +1,60 @@
+;;;; -*- mode:lisp;coding:utf-8 -*-
+;;;;**************************************************************************
+;;;;FILE:               com.informatimago.languages.c11.asd
+;;;;LANGUAGE:           Common-Lisp
+;;;;SYSTEM:             Common-Lisp
+;;;;USER-INTERFACE:     NONE
+;;;;DESCRIPTION
+;;;;
+;;;;    ASD file to load the com.informatimago.languages.c11 library.
+;;;;
+;;;;AUTHORS
+;;;;    <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
+;;;;MODIFICATIONS
+;;;;    2015-06-28 <PJB> Created.
+;;;;BUGS
+;;;;LEGAL
+;;;;    AGPL3
+;;;;
+;;;;    Copyright Pascal J. Bourguignon 2015 - 2015
+;;;;
+;;;;    This program is free software: you can redistribute it and/or modify
+;;;;    it under the terms of the GNU Affero General Public License as published by
+;;;;    the Free Software Foundation, either version 3 of the License, or
+;;;;    (at your option) any later version.
+;;;;
+;;;;    This program 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 Affero General Public License for more details.
+;;;;
+;;;;    You should have received a copy of the GNU Affero General Public License
+;;;;    along with this program.  If not, see http://www.gnu.org/licenses/
+;;;;**************************************************************************
+
+(asdf:defsystem "com.informatimago.languages.c11"
+  ;; system attributes:
+  :description "A parser for the standard ANSI C 2011."
+  :author     "Pascal J. Bourguignon <pjb@informatimago.com>"
+  :maintainer "Pascal J. Bourguignon <pjb@informatimago.com>"
+  :licence "AGPL3"
+  ;; component  attributes:
+  :version "0.0.0"
+  :properties ((#:author-email                   . "pjb@informatimago.com")
+               (#:date                           . "Summer 2015")
+               ((#:albert #:output-dir)          . "/tmp/documentation/com.informatimago.languages.c11/")
+               ((#:albert #:formats)             . ("docbook"))
+               ((#:albert #:docbook #:template)  . "book")
+               ((#:albert #:docbook #:bgcolor)   . "white")
+               ((#:albert #:docbook #:textcolor) . "black"))
+  #+asdf-unicode :encoding #+asdf-unicode :utf-8
+  :depends-on ("com.informatimago.common-lisp.cesarum"
+               "com.informatimago.tools.reader-macro"
+               "com.informatimago.languages.cpp"
+               "yacc")
+  :components ((:file "packages"        :depends-on  ())
+               (:file "read-yacc"       :depends-on  ("packages"))
+               (:file "parser"          :depends-on  ("packages" "read-yacc")))
+  :in-order-to ((asdf:test-op (asdf:test-op "com.informatimago.languages.c11.test"))))
+
+;;;; THE END ;;;;
diff --git a/languages/c11/packages.lisp b/languages/c11/packages.lisp
new file mode 100644
index 0000000..73f75a1
--- /dev/null
+++ b/languages/c11/packages.lisp
@@ -0,0 +1,51 @@
+;;;; -*- mode:lisp;coding:utf-8 -*-
+;;;;**************************************************************************
+;;;;FILE:               packages.lisp
+;;;;LANGUAGE:           Common-Lisp
+;;;;SYSTEM:             Common-Lisp
+;;;;USER-INTERFACE:     NONE
+;;;;DESCRIPTION
+;;;;
+;;;;    Defines the packages for the C11 parser.
+;;;;
+;;;;AUTHORS
+;;;;    <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
+;;;;MODIFICATIONS
+;;;;    2015-07-02 <PJB> Created.
+;;;;BUGS
+;;;;LEGAL
+;;;;    AGPL3
+;;;;
+;;;;    Copyright Pascal J. Bourguignon 2015 - 2015
+;;;;
+;;;;    This program is free software: you can redistribute it and/or modify
+;;;;    it under the terms of the GNU Affero General Public License as published by
+;;;;    the Free Software Foundation, either version 3 of the License, or
+;;;;    (at your option) any later version.
+;;;;
+;;;;    This program 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 Affero General Public License for more details.
+;;;;
+;;;;    You should have received a copy of the GNU Affero General Public License
+;;;;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;;;**************************************************************************
+
+(defpackage "COM.INFORMATIMAGO.LANGUAGES.C11"
+  (:use "COMMON-LISP"))
+
+(defpackage "COM.INFORMATIMAGO.LANGUAGES.C11.PARSER"
+  (:use "COMMON-LISP"
+        "YACC"
+        "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.LIST"
+        "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.STREAM"
+        "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.STRING"
+        "COM.INFORMATIMAGO.COMMON-LISP.PARSER.PARSER"
+        "COM.INFORMATIMAGO.COMMON-LISP.PARSER.SCANNER"
+        "COM.INFORMATIMAGO.COMMON-LISP.REGEXP.REGEXP"
+        "COM.INFORMATIMAGO.LANGUAGES.CPP"
+        "COM.INFORMATIMAGO.TOOLS.READER-MACRO"
+        ))
+
+;;;; THE END ;;;;
diff --git a/languages/c11/parser.lisp b/languages/c11/parser.lisp
new file mode 100644
index 0000000..ffec915
--- /dev/null
+++ b/languages/c11/parser.lisp
@@ -0,0 +1,275 @@
+;;;; -*- mode:lisp;coding:utf-8 -*-
+;;;;**************************************************************************
+;;;;FILE:               parser.lisp
+;;;;LANGUAGE:           Common-Lisp
+;;;;SYSTEM:             Common-Lisp
+;;;;USER-INTERFACE:     NONE
+;;;;DESCRIPTION
+;;;;
+;;;;    C11 parser.
+;;;;
+;;;;AUTHORS
+;;;;    <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
+;;;;MODIFICATIONS
+;;;;    2015-07-02 <PJB> Created.
+;;;;BUGS
+;;;;LEGAL
+;;;;    AGPL3
+;;;;
+;;;;    Copyright Pascal J. Bourguignon 2015 - 2015
+;;;;
+;;;;    This program is free software: you can redistribute it and/or modify
+;;;;    it under the terms of the GNU Affero General Public License as published by
+;;;;    the Free Software Foundation, either version 3 of the License, or
+;;;;    (at your option) any later version.
+;;;;
+;;;;    This program 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 Affero General Public License for more details.
+;;;;
+;;;;    You should have received a copy of the GNU Affero General Public License
+;;;;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;;;**************************************************************************
+(in-package "COM.INFORMATIMAGO.LANGUAGES.C11.PARSER")
+
+
+#|
+(defmethod accept ((scanner buffered-scanner) token)
+  (if (word-equal token (scanner-current-token scanner))
+      (prog1 (list (token-kind (scanner-current-token scanner))
+                   (scanner-current-text scanner)
+                   (scanner-column scanner))
+        (scan-next-token scanner))
+      (error 'unexpected-token-error
+             :line   (scanner-line   scanner)
+             :column (scanner-column scanner)
+             :state  (scanner-state  scanner)
+             :current-token (scanner-current-token scanner)
+             :scanner scanner
+             :expected-token token
+             :format-control "Expected ~S, not ~A (~S)~%"
+             :format-arguments (list
+                                token
+                                (scanner-current-token scanner)
+                                (scanner-current-text scanner)))))
+
+|#
+
+
+(DEFINE-PARSER *C11-PARSER*
+  (:START-SYMBOL |translation_unit|)
+  (:TERMINALS (
+               ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL CASE
+               DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN STRUCT UNION
+               ENUM ELLIPSIS COMPLEX IMAGINARY BOOL CHAR SHORT INT LONG SIGNED UNSIGNED
+               FLOAT DOUBLE VOID CONST RESTRICT VOLATILE TYPEDEF EXTERN STATIC AUTO
+               REGISTER INLINE TYPEDEF_NAME ENUMERATION_CONSTANT XOR_ASSIGN OR_ASSIGN
+               SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN AND_OP OR_OP MUL_ASSIGN
+               DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP
+               LE_OP GE_OP EQ_OP NE_OP IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL
+               FUNC_NAME SIZEOF))
+  (|primary_expression| IDENTIFIER |constant| |string| (\( |expression| \))
+                        |generic_selection|)
+  (|constant| I_CONSTANT F_CONSTANT ENUMERATION_CONSTANT)
+  (|enumeration_constant| IDENTIFIER)
+  (|string| STRING_LITERAL FUNC_NAME)
+  (|generic_selection|
+   (GENERIC \( |assignment_expression| \, |generic_assoc_list| \)))
+  (|generic_assoc_list| |generic_association|
+                        (|generic_assoc_list| \, |generic_association|))
+  (|generic_association| (|type_name| \: |assignment_expression|)
+                         (DEFAULT \: |assignment_expression|))
+  (|postfix_expression| |primary_expression|
+                        (|postfix_expression| [ |expression| ]) (|postfix_expression| \( \))
+                        (|postfix_expression| \( |argument_expression_list| \))
+                        (|postfix_expression| |.| IDENTIFIER)
+                        (|postfix_expression| PTR_OP IDENTIFIER) (|postfix_expression| INC_OP)
+                        (|postfix_expression| DEC_OP) (\( |type_name| \) { |initializer_list| })
+                        (\( |type_name| \) { |initializer_list| \, }))
+  (|argument_expression_list| |assignment_expression|
+                              (|argument_expression_list| \, |assignment_expression|))
+  (|unary_expression| |postfix_expression| (INC_OP |unary_expression|)
+                      (DEC_OP |unary_expression|) (|unary_operator| |cast_expression|)
+                      (SIZEOF |unary_expression|) (SIZEOF \( |type_name| \))
+                      (ALIGNOF \( |type_name| \)))
+  (|unary_operator| & * + - ~ !)
+  (|cast_expression| |unary_expression| (\( |type_name| \) |cast_expression|))
+  (|multiplicative_expression| |cast_expression|
+                               (|multiplicative_expression| * |cast_expression|)
+                               (|multiplicative_expression| / |cast_expression|)
+                               (|multiplicative_expression| % |cast_expression|))
+  (|additive_expression| |multiplicative_expression|
+                         (|additive_expression| + |multiplicative_expression|)
+                         (|additive_expression| - |multiplicative_expression|))
+  (|shift_expression| |additive_expression|
+                      (|shift_expression| LEFT_OP |additive_expression|)
+                      (|shift_expression| RIGHT_OP |additive_expression|))
+  (|relational_expression| |shift_expression|
+                           (|relational_expression| < |shift_expression|)
+                           (|relational_expression| > |shift_expression|)
+                           (|relational_expression| LE_OP |shift_expression|)
+                           (|relational_expression| GE_OP |shift_expression|))
+  (|equality_expression| |relational_expression|
+                         (|equality_expression| EQ_OP |relational_expression|)
+                         (|equality_expression| NE_OP |relational_expression|))
+  (|and_expression| |equality_expression|
+                    (|and_expression| & |equality_expression|))
+  (|exclusive_or_expression| |and_expression|
+                             (|exclusive_or_expression| ^ |and_expression|))
+  (|inclusive_or_expression| |exclusive_or_expression|
+                             (|inclusive_or_expression| \| |exclusive_or_expression|))
+  (|logical_and_expression| |inclusive_or_expression|
+                            (|logical_and_expression| AND_OP |inclusive_or_expression|))
+  (|logical_or_expression| |logical_and_expression|
+                           (|logical_or_expression| OR_OP |logical_and_expression|))
+  (|conditional_expression| |logical_or_expression|
+                            (|logical_or_expression| ? |expression| \: |conditional_expression|))
+  (|assignment_expression| |conditional_expression|
+                           (|unary_expression| |assignment_operator| |assignment_expression|))
+  (|assignment_operator| = MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
+                         SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN)
+  (|expression| |assignment_expression|
+                (|expression| \, |assignment_expression|))
+  (|constant_expression| |conditional_expression|)
+  (|declaration| (|declaration_specifiers| \;)
+                 (|declaration_specifiers| |init_declarator_list| \;)
+                 |static_assert_declaration|)
+  (|declaration_specifiers|
+   (|storage_class_specifier| |declaration_specifiers|)
+   |storage_class_specifier| (|type_specifier| |declaration_specifiers|)
+   |type_specifier| (|type_qualifier| |declaration_specifiers|)
+   |type_qualifier| (|function_specifier| |declaration_specifiers|)
+   |function_specifier| (|alignment_specifier| |declaration_specifiers|)
+   |alignment_specifier|)
+  (|init_declarator_list| |init_declarator|
+                          (|init_declarator_list| \, |init_declarator|))
+  (|init_declarator| (|declarator| = |initializer|) |declarator|)
+  (|storage_class_specifier| TYPEDEF EXTERN STATIC THREAD_LOCAL AUTO REGISTER)
+  (|type_specifier| VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED BOOL
+                    COMPLEX IMAGINARY |atomic_type_specifier| |struct_or_union_specifier|
+                    |enum_specifier| TYPEDEF_NAME)
+  (|struct_or_union_specifier|
+   (|struct_or_union| { |struct_declaration_list| })
+   (|struct_or_union| IDENTIFIER { |struct_declaration_list| })
+   (|struct_or_union| IDENTIFIER))
+  (|struct_or_union| STRUCT UNION)
+  (|struct_declaration_list| |struct_declaration|
+                             (|struct_declaration_list| |struct_declaration|))
+  (|struct_declaration| (|specifier_qualifier_list| \;)
+                        (|specifier_qualifier_list| |struct_declarator_list| \;)
+                        |static_assert_declaration|)
+  (|specifier_qualifier_list| (|type_specifier| |specifier_qualifier_list|)
+                              |type_specifier| (|type_qualifier| |specifier_qualifier_list|)
+                              |type_qualifier|)
+  (|struct_declarator_list| |struct_declarator|
+                            (|struct_declarator_list| \, |struct_declarator|))
+  (|struct_declarator| (\: |constant_expression|)
+                       (|declarator| \: |constant_expression|) |declarator|)
+  (|enum_specifier| (ENUM { |enumerator_list| })
+                    (ENUM { |enumerator_list| \, }) (ENUM IDENTIFIER { |enumerator_list| })
+                    (ENUM IDENTIFIER { |enumerator_list| \, }) (ENUM IDENTIFIER))
+  (|enumerator_list| |enumerator| (|enumerator_list| \, |enumerator|))
+  (|enumerator| (|enumeration_constant| = |constant_expression|)
+                |enumeration_constant|)
+  (|atomic_type_specifier| (ATOMIC \( |type_name| \)))
+  (|type_qualifier| CONST RESTRICT VOLATILE ATOMIC)
+  (|function_specifier| INLINE NORETURN)
+  (|alignment_specifier| (ALIGNAS \( |type_name| \))
+                         (ALIGNAS \( |constant_expression| \)))
+  (|declarator| (|pointer| |direct_declarator|) |direct_declarator|)
+  (|direct_declarator| IDENTIFIER (\( |declarator| \))
+                       (|direct_declarator| [ ]) (|direct_declarator| [ * ])
+                       (|direct_declarator| [ STATIC |type_qualifier_list| |assignment_expression|
+                                                     ])
+                       (|direct_declarator| [ STATIC |assignment_expression| ])
+                       (|direct_declarator| [ |type_qualifier_list| * ])
+                       (|direct_declarator| [ |type_qualifier_list| STATIC |assignment_expression|
+                                                                    ])
+                       (|direct_declarator| [ |type_qualifier_list| |assignment_expression| ])
+                       (|direct_declarator| [ |type_qualifier_list| ])
+                       (|direct_declarator| [ |assignment_expression| ])
+                       (|direct_declarator| \( |parameter_type_list| \))
+                       (|direct_declarator| \( \)) (|direct_declarator| \( |identifier_list| \)))
+  (|pointer| (* |type_qualifier_list| |pointer|) (* |type_qualifier_list|)
+             (* |pointer|) *)
+  (|type_qualifier_list| |type_qualifier|
+                         (|type_qualifier_list| |type_qualifier|))
+  (|parameter_type_list| (|parameter_list| \, ELLIPSIS) |parameter_list|)
+  (|parameter_list| |parameter_declaration|
+                    (|parameter_list| \, |parameter_declaration|))
+  (|parameter_declaration| (|declaration_specifiers| |declarator|)
+                           (|declaration_specifiers| |abstract_declarator|) |declaration_specifiers|)
+  (|identifier_list| IDENTIFIER (|identifier_list| \, IDENTIFIER))
+  (|type_name| (|specifier_qualifier_list| |abstract_declarator|)
+               |specifier_qualifier_list|)
+  (|abstract_declarator| (|pointer| |direct_abstract_declarator|) |pointer|
+                         |direct_abstract_declarator|)
+  (|direct_abstract_declarator| (\( |abstract_declarator| \)) ([ ]) ([ * ])
+                                ([ STATIC |type_qualifier_list| |assignment_expression| ])
+                                ([ STATIC |assignment_expression| ])
+                                ([ |type_qualifier_list| STATIC |assignment_expression| ])
+                                ([ |type_qualifier_list| |assignment_expression| ])
+                                ([ |type_qualifier_list| ]) ([ |assignment_expression| ])
+                                (|direct_abstract_declarator| [ ]) (|direct_abstract_declarator| [ * ])
+                                (|direct_abstract_declarator| [ STATIC |type_qualifier_list|
+                                                                       |assignment_expression| ])
+                                (|direct_abstract_declarator| [ STATIC |assignment_expression| ])
+                                (|direct_abstract_declarator| [ |type_qualifier_list|
+                                                                |assignment_expression| ])
+                                (|direct_abstract_declarator| [ |type_qualifier_list| STATIC
+                                                                                      |assignment_expression| ])
+                                (|direct_abstract_declarator| [ |type_qualifier_list| ])
+                                (|direct_abstract_declarator| [ |assignment_expression| ]) (\( \))
+                                (\( |parameter_type_list| \)) (|direct_abstract_declarator| \( \))
+                                (|direct_abstract_declarator| \( |parameter_type_list| \)))
+  (|initializer| ({ |initializer_list| }) ({ |initializer_list| \, })
+                 |assignment_expression|)
+  (|initializer_list| (|designation| |initializer|) |initializer|
+                      (|initializer_list| \, |designation| |initializer|)
+                      (|initializer_list| \, |initializer|))
+  (|designation| (|designator_list| =))
+  (|designator_list| |designator| (|designator_list| |designator|))
+  (|designator| ([ |constant_expression| ]) (|.| IDENTIFIER))
+  (|static_assert_declaration|
+   (STATIC_ASSERT \( |constant_expression| \, STRING_LITERAL \) \;))
+  (|statement| |labeled_statement| |compound_statement| |expression_statement|
+               |selection_statement| |iteration_statement| |jump_statement|)
+  (|labeled_statement| (IDENTIFIER \: |statement|)
+                       (CASE |constant_expression| \: |statement|) (DEFAULT \: |statement|))
+  (|compound_statement| ({ }) ({ |block_item_list| }))
+  (|block_item_list| |block_item| (|block_item_list| |block_item|))
+  (|block_item| |declaration| |statement|)
+  (|expression_statement| \; (|expression| \;))
+  (|selection_statement| (IF \( |expression| \) |statement| ELSE |statement|)
+                         (IF \( |expression| \) |statement|) (SWITCH \( |expression| \) |statement|))
+  (|iteration_statement| (WHILE \( |expression| \) |statement|)
+                         (DO |statement| WHILE  \( |expression| \) \;)
+                         (FOR \( |expression_statement| |expression_statement| \) |statement|)
+                         (FOR \( |expression_statement| |expression_statement| |expression| \)
+                           |statement|)
+                         (FOR \( |declaration| |expression_statement| \) |statement|)
+                         (FOR \( |declaration| |expression_statement| |expression| \) |statement|))
+  (|jump_statement| (GOTO IDENTIFIER \;) (CONTINUE \;) (BREAK \;) (RETURN \;)
+                    (RETURN |expression| \;))
+  (|translation_unit| |external_declaration|
+                      (|translation_unit| |external_declaration|))
+  (|external_declaration| |function_definition| |declaration|)
+  (|function_definition|
+   (|declaration_specifiers| |declarator| |declaration_list|
+                             |compound_statement|)
+   (|declaration_specifiers| |declarator| |compound_statement|))
+  (|declaration_list| |declaration| (|declaration_list| |declaration|)))
+
+
+(defun make-list-lexer (tokens)
+  (lambda ()
+    (if tokens
+        (let ((token (pop tokens)))
+          (values (token-kind token) token))
+        (values nil nil))))
+
+;; (parse-with-lexer (make-list-lexer *tc*) *c11-parser*)
+
+
+;;;; THE END ;;;;
diff --git a/languages/c11/parser.yacc b/languages/c11/parser.yacc
new file mode 100644
index 0000000..bb3ac7a
--- /dev/null
+++ b/languages/c11/parser.yacc
@@ -0,0 +1,544 @@
+/*  Note: There are two shift/reduce conflicts, correctly resolved by default: */
+/*                                                                             */
+/*   IF '(' expression ')' statement _ ELSE statement                          */
+/*                                                                             */
+/* and                                                                         */
+/*                                                                             */
+/*   ATOMIC _ '(' type_name ')'                                                */
+/*                                                                             */
+/* where "_" has been used to flag the points of ambiguity.                    */
+
+%token	IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL FUNC_NAME SIZEOF
+%token	PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
+%token	AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
+%token	SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
+%token	XOR_ASSIGN OR_ASSIGN
+%token	TYPEDEF_NAME ENUMERATION_CONSTANT
+
+%token	TYPEDEF EXTERN STATIC AUTO REGISTER INLINE
+%token	CONST RESTRICT VOLATILE
+%token	BOOL CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE VOID
+%token	COMPLEX IMAGINARY
+%token	STRUCT UNION ENUM ELLIPSIS
+
+%token	CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
+
+%token	ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL
+
+%start translation_unit
+%%
+
+primary_expression
+	: IDENTIFIER
+	| constant
+	| string
+	| '(' expression ')'
+	| generic_selection
+	;
+
+constant
+	: I_CONSTANT		/* includes character_constant */
+	| F_CONSTANT
+	| ENUMERATION_CONSTANT	/* after it has been defined as such */
+	;
+
+enumeration_constant		/* before it has been defined as such */
+	: IDENTIFIER
+	;
+
+string
+	: STRING_LITERAL
+	| FUNC_NAME
+	;
+
+generic_selection
+	: GENERIC '(' assignment_expression ',' generic_assoc_list ')'
+	;
+
+generic_assoc_list
+	: generic_association
+	| generic_assoc_list ',' generic_association
+	;
+
+generic_association
+	: type_name ':' assignment_expression
+	| DEFAULT ':' assignment_expression
+	;
+
+postfix_expression
+	: primary_expression
+	| postfix_expression '[' expression ']'
+	| postfix_expression '(' ')'
+	| postfix_expression '(' argument_expression_list ')'
+	| postfix_expression '.' IDENTIFIER
+	| postfix_expression PTR_OP IDENTIFIER
+	| postfix_expression INC_OP
+	| postfix_expression DEC_OP
+	| '(' type_name ')' '{' initializer_list '}'
+	| '(' type_name ')' '{' initializer_list ',' '}'
+	;
+
+argument_expression_list
+	: assignment_expression
+	| argument_expression_list ',' assignment_expression
+	;
+
+unary_expression
+	: postfix_expression
+	| INC_OP unary_expression
+	| DEC_OP unary_expression
+	| unary_operator cast_expression
+	| SIZEOF unary_expression
+	| SIZEOF '(' type_name ')'
+	| ALIGNOF '(' type_name ')'
+	;
+
+unary_operator
+	: '&'
+	| '*'
+	| '+'
+	| '-'
+	| '~'
+	| '!'
+	;
+
+cast_expression
+	: unary_expression
+	| '(' type_name ')' cast_expression
+	;
+
+multiplicative_expression
+	: cast_expression
+	| multiplicative_expression '*' cast_expression
+	| multiplicative_expression '/' cast_expression
+	| multiplicative_expression '%' cast_expression
+	;
+
+additive_expression
+	: multiplicative_expression
+	| additive_expression '+' multiplicative_expression
+	| additive_expression '-' multiplicative_expression
+	;
+
+shift_expression
+	: additive_expression
+	| shift_expression LEFT_OP additive_expression
+	| shift_expression RIGHT_OP additive_expression
+	;
+
+relational_expression
+	: shift_expression
+	| relational_expression '<' shift_expression
+	| relational_expression '>' shift_expression
+	| relational_expression LE_OP shift_expression
+	| relational_expression GE_OP shift_expression
+	;
+
+equality_expression
+	: relational_expression
+	| equality_expression EQ_OP relational_expression
+	| equality_expression NE_OP relational_expression
+	;
+
+and_expression
+	: equality_expression
+	| and_expression '&' equality_expression
+	;
+
+exclusive_or_expression
+	: and_expression
+	| exclusive_or_expression '^' and_expression
+	;
+
+inclusive_or_expression
+	: exclusive_or_expression
+	| inclusive_or_expression '|' exclusive_or_expression
+	;
+
+logical_and_expression
+	: inclusive_or_expression
+	| logical_and_expression AND_OP inclusive_or_expression
+	;
+
+logical_or_expression
+	: logical_and_expression
+	| logical_or_expression OR_OP logical_and_expression
+	;
+
+conditional_expression
+	: logical_or_expression
+	| logical_or_expression '?' expression ':' conditional_expression
+	;
+
+assignment_expression
+	: conditional_expression
+	| unary_expression assignment_operator assignment_expression
+	;
+
+assignment_operator
+	: '='
+	| MUL_ASSIGN
+	| DIV_ASSIGN
+	| MOD_ASSIGN
+	| ADD_ASSIGN
+	| SUB_ASSIGN
+	| LEFT_ASSIGN
+	| RIGHT_ASSIGN
+	| AND_ASSIGN
+	| XOR_ASSIGN
+	| OR_ASSIGN
+	;
+
+expression
+	: assignment_expression
+	| expression ',' assignment_expression
+	;
+
+constant_expression
+	: conditional_expression	/* with constraints */
+	;
+
+declaration
+	: declaration_specifiers ';'
+	| declaration_specifiers init_declarator_list ';'
+	| static_assert_declaration
+	;
+
+declaration_specifiers
+	: storage_class_specifier declaration_specifiers
+	| storage_class_specifier
+	| type_specifier declaration_specifiers
+	| type_specifier
+	| type_qualifier declaration_specifiers
+	| type_qualifier
+	| function_specifier declaration_specifiers
+	| function_specifier
+	| alignment_specifier declaration_specifiers
+	| alignment_specifier
+	;
+
+init_declarator_list
+	: init_declarator
+	| init_declarator_list ',' init_declarator
+	;
+
+init_declarator
+	: declarator '=' initializer
+	| declarator
+	;
+
+storage_class_specifier
+	: TYPEDEF	/* identifiers must be flagged as TYPEDEF_NAME */
+	| EXTERN
+	| STATIC
+	| THREAD_LOCAL
+	| AUTO
+	| REGISTER
+	;
+
+type_specifier
+	: VOID
+	| CHAR
+	| SHORT
+	| INT
+	| LONG
+	| FLOAT
+	| DOUBLE
+	| SIGNED
+	| UNSIGNED
+	| BOOL
+	| COMPLEX
+	| IMAGINARY	  	/* non-mandated extension */
+	| atomic_type_specifier
+	| struct_or_union_specifier
+	| enum_specifier
+	| TYPEDEF_NAME		/* after it has been defined as such */
+	;
+
+struct_or_union_specifier
+	: struct_or_union '{' struct_declaration_list '}'
+	| struct_or_union IDENTIFIER '{' struct_declaration_list '}'
+	| struct_or_union IDENTIFIER
+	;
+
+struct_or_union
+	: STRUCT
+	| UNION
+	;
+
+struct_declaration_list
+	: struct_declaration
+	| struct_declaration_list struct_declaration
+	;
+
+struct_declaration
+	: specifier_qualifier_list ';'	/* for anonymous struct/union */
+	| specifier_qualifier_list struct_declarator_list ';'
+	| static_assert_declaration
+	;
+
+specifier_qualifier_list
+	: type_specifier specifier_qualifier_list
+	| type_specifier
+	| type_qualifier specifier_qualifier_list
+	| type_qualifier
+	;
+
+struct_declarator_list
+	: struct_declarator
+	| struct_declarator_list ',' struct_declarator
+	;
+
+struct_declarator
+	: ':' constant_expression
+	| declarator ':' constant_expression
+	| declarator
+	;
+
+enum_specifier
+	: ENUM '{' enumerator_list '}'
+	| ENUM '{' enumerator_list ',' '}'
+	| ENUM IDENTIFIER '{' enumerator_list '}'
+	| ENUM IDENTIFIER '{' enumerator_list ',' '}'
+	| ENUM IDENTIFIER
+	;
+
+enumerator_list
+	: enumerator
+	| enumerator_list ',' enumerator
+	;
+
+enumerator	/* identifiers must be flagged as ENUMERATION_CONSTANT */
+	: enumeration_constant '=' constant_expression
+	| enumeration_constant
+	;
+
+atomic_type_specifier
+	: ATOMIC '(' type_name ')'
+	;
+
+type_qualifier
+	: CONST
+	| RESTRICT
+	| VOLATILE
+	| ATOMIC
+	;
+
+function_specifier
+	: INLINE
+	| NORETURN
+	;
+
+alignment_specifier
+	: ALIGNAS '(' type_name ')'
+	| ALIGNAS '(' constant_expression ')'
+	;
+
+declarator
+	: pointer direct_declarator
+	| direct_declarator
+	;
+
+direct_declarator
+	: IDENTIFIER
+	| '(' declarator ')'
+	| direct_declarator '[' ']'
+	| direct_declarator '[' '*' ']'
+	| direct_declarator '[' STATIC type_qualifier_list assignment_expression ']'
+	| direct_declarator '[' STATIC assignment_expression ']'
+	| direct_declarator '[' type_qualifier_list '*' ']'
+	| direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
+	| direct_declarator '[' type_qualifier_list assignment_expression ']'
+	| direct_declarator '[' type_qualifier_list ']'
+	| direct_declarator '[' assignment_expression ']'
+	| direct_declarator '(' parameter_type_list ')'
+	| direct_declarator '(' ')'
+	| direct_declarator '(' identifier_list ')'
+	;
+
+pointer
+	: '*' type_qualifier_list pointer
+	| '*' type_qualifier_list
+	| '*' pointer
+	| '*'
+	;
+
+type_qualifier_list
+	: type_qualifier
+	| type_qualifier_list type_qualifier
+	;
+
+
+parameter_type_list
+	: parameter_list ',' ELLIPSIS
+	| parameter_list
+	;
+
+parameter_list
+	: parameter_declaration
+	| parameter_list ',' parameter_declaration
+	;
+
+parameter_declaration
+	: declaration_specifiers declarator
+	| declaration_specifiers abstract_declarator
+	| declaration_specifiers
+	;
+
+identifier_list
+	: IDENTIFIER
+	| identifier_list ',' IDENTIFIER
+	;
+
+type_name
+	: specifier_qualifier_list abstract_declarator
+	| specifier_qualifier_list
+	;
+
+abstract_declarator
+	: pointer direct_abstract_declarator
+	| pointer
+	| direct_abstract_declarator
+	;
+
+direct_abstract_declarator
+	: '(' abstract_declarator ')'
+	| '[' ']'
+	| '[' '*' ']'
+	| '[' STATIC type_qualifier_list assignment_expression ']'
+	| '[' STATIC assignment_expression ']'
+	| '[' type_qualifier_list STATIC assignment_expression ']'
+	| '[' type_qualifier_list assignment_expression ']'
+	| '[' type_qualifier_list ']'
+	| '[' assignment_expression ']'
+	| direct_abstract_declarator '[' ']'
+	| direct_abstract_declarator '[' '*' ']'
+	| direct_abstract_declarator '[' STATIC type_qualifier_list assignment_expression ']'
+	| direct_abstract_declarator '[' STATIC assignment_expression ']'
+	| direct_abstract_declarator '[' type_qualifier_list assignment_expression ']'
+	| direct_abstract_declarator '[' type_qualifier_list STATIC assignment_expression ']'
+	| direct_abstract_declarator '[' type_qualifier_list ']'
+	| direct_abstract_declarator '[' assignment_expression ']'
+	| '(' ')'
+	| '(' parameter_type_list ')'
+	| direct_abstract_declarator '(' ')'
+	| direct_abstract_declarator '(' parameter_type_list ')'
+	;
+
+initializer
+	: '{' initializer_list '}'
+	| '{' initializer_list ',' '}'
+	| assignment_expression
+	;
+
+initializer_list
+	: designation initializer
+	| initializer
+	| initializer_list ',' designation initializer
+	| initializer_list ',' initializer
+	;
+
+designation
+	: designator_list '='
+	;
+
+designator_list
+	: designator
+	| designator_list designator
+	;
+
+designator
+	: '[' constant_expression ']'
+	| '.' IDENTIFIER
+	;
+
+static_assert_declaration
+	: STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';'
+	;
+
+statement
+	: labeled_statement
+	| compound_statement
+	| expression_statement
+	| selection_statement
+	| iteration_statement
+	| jump_statement
+	;
+
+labeled_statement
+	: IDENTIFIER ':' statement
+	| CASE constant_expression ':' statement
+	| DEFAULT ':' statement
+	;
+
+compound_statement
+	: '{' '}'
+	| '{'  block_item_list '}'
+	;
+
+block_item_list
+	: block_item
+	| block_item_list block_item
+	;
+
+block_item
+	: declaration
+	| statement
+	;
+
+expression_statement
+	: ';'
+	| expression ';'
+	;
+
+selection_statement
+	: IF '(' expression ')' statement ELSE statement
+	| IF '(' expression ')' statement
+	| SWITCH '(' expression ')' statement
+	;
+
+iteration_statement
+	: WHILE '(' expression ')' statement
+	| DO statement WHILE '(' expression ')' ';'
+	| FOR '(' expression_statement expression_statement ')' statement
+	| FOR '(' expression_statement expression_statement expression ')' statement
+	| FOR '(' declaration expression_statement ')' statement
+	| FOR '(' declaration expression_statement expression ')' statement
+	;
+
+jump_statement
+	: GOTO IDENTIFIER ';'
+	| CONTINUE ';'
+	| BREAK ';'
+	| RETURN ';'
+	| RETURN expression ';'
+	;
+
+translation_unit
+	: external_declaration
+	| translation_unit external_declaration
+	;
+
+external_declaration
+	: function_definition
+	| declaration
+	;
+
+function_definition
+	: declaration_specifiers declarator declaration_list compound_statement
+	| declaration_specifiers declarator compound_statement
+	;
+
+declaration_list
+	: declaration
+	| declaration_list declaration
+	;
+
+%%
+#include <stdio.h>
+
+void yyerror(const char *s)
+{
+	fflush(stdout);
+	fprintf(stderr, "*** %s\n", s);
+}
diff --git a/languages/c11/read-yacc.lisp b/languages/c11/read-yacc.lisp
new file mode 100644
index 0000000..a9c92f6
--- /dev/null
+++ b/languages/c11/read-yacc.lisp
@@ -0,0 +1,250 @@
+;;;; -*- mode:lisp;coding:utf-8 -*-
+;;;;**************************************************************************
+;;;;FILE:               read-yacc.lisp
+;;;;LANGUAGE:           Common-Lisp
+;;;;SYSTEM:             Common-Lisp
+;;;;USER-INTERFACE:     NONE
+;;;;DESCRIPTION
+;;;;
+;;;;    Parses yacc files, to generate the grammar in sexp form.
+;;;;
+;;;;AUTHORS
+;;;;    <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
+;;;;MODIFICATIONS
+;;;;    2015-07-02 <PJB> Created.
+;;;;BUGS
+;;;;LEGAL
+;;;;    AGPL3
+;;;;
+;;;;    Copyright Pascal J. Bourguignon 2015 - 2015
+;;;;
+;;;;    This program is free software: you can redistribute it and/or modify
+;;;;    it under the terms of the GNU Affero General Public License as published by
+;;;;    the Free Software Foundation, either version 3 of the License, or
+;;;;    (at your option) any later version.
+;;;;
+;;;;    This program 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 Affero General Public License for more details.
+;;;;
+;;;;    You should have received a copy of the GNU Affero General Public License
+;;;;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;;;**************************************************************************
+(in-package "COM.INFORMATIMAGO.LANGUAGES.C11.PARSER")
+
+(defun remove-comments (text &key (single-line-comments t))
+  (flet ((concatenate-chunks (chunks)
+           (mapconcat (function identity) chunks " ")))
+    (loop
+      :with state := :top
+      :with chunks := '()
+      :with start := (ecase state
+                       (:top 0)
+                       (:in-multiline-comment (length text)))
+      :with i := 0
+      :while (< i (length text))
+      :do (let ((ch (aref text i)))
+            (ecase state
+              (:top
+               (case ch
+                 ((#\")     (incf i) (setf state :in-string))
+                 ((#\')     (incf i) (setf state :in-character))
+                 ((#\/)
+                  (incf i)
+                  (when (< i (length text))
+                    (let ((ch (aref text i)))
+                      (case ch
+                        ((#\/) ;;single line comment
+                         (when single-line-comments
+                           (return-from remove-comments
+                             (values (concatenate-chunks (nreverse (cons (subseq text start (1- i)) chunks)))
+                                     state))))
+                        ((#\*)
+                         (incf i)
+                         (push (subseq text start (- i 2)) chunks)
+                         (setf state :in-multiline-comment
+                               start (length text)))))))
+                 (otherwise (incf i))))
+              (:in-multiline-comment
+               (case ch
+                 ((#\*)
+                  (incf i)
+                  (when (< i (length text))
+                    (let ((ch (aref text i)))
+                      (when (char= ch #\/)
+                        (incf i)
+                        (setf start i)
+                        (setf state :top)))))
+                 (otherwise
+                  (incf i))))
+              (:in-string
+               (case ch
+                 ((#\\)
+                  (incf i)
+                  (if (< i (length text))
+                      (incf i)
+                      (progn (error "backslash in string literal at the end of the line")
+                             (setf state :top))))
+                 ((#\")
+                  (incf i)
+                  (setf state :top))
+                 (otherwise (incf i))))
+              (:in-character
+               (case ch
+                 ((#\\)
+                  (incf i)
+                  (if (< i (length text))
+                      (incf i)
+                      (progn (error "backslash in character literal at the end of the line")
+                             (setf state :top))))
+                 ((#\')
+                  (incf i)
+                  (setf state :top))
+                 (otherwise (incf i))))))
+      :finally (return (case state
+                         (:in-string
+                          (error "unterminated string literal at the end of the line")
+                          (values (concatenate-chunks (nreverse chunks)) :top))
+                         (:in-character
+                          (error "unterminated character literal at the end of the line")
+                          (values (concatenate-chunks (nreverse chunks)) :top))
+                         (:top
+                          (values (concatenate-chunks (nreverse (if (< start (length text))
+                                                                    (cons (subseq text start) chunks)
+                                                                    chunks)))
+                                  state))
+                         (:in-multiline-comment
+                          (values (concatenate-chunks (nreverse chunks))
+                                  state)))))))
+
+(defun test/remove-comments ()
+ (assert (equal (multiple-value-list (remove-comments "hello \"world/*\" /*comment*/ /*another/*comment*/ boy // the end */ really"))
+                '("hello \"world/*\"     boy "
+                  :top)))
+  :success)
+
+(defun read-delimited-string (stream ch)
+  (let ((buffer (make-array 80 :element-type 'character :initial-element #\space
+                               :fill-pointer 0 :adjustable t)))
+    (flet ((save (ch)
+             (vector-push-extend ch buffer (length buffer))))
+      (declare (inline save))
+      (loop
+        :with terminator = ch
+        :for ch = (read-char stream nil nil)
+        :while ch
+        :do  (cond
+               ((char= terminator ch)
+                (loop-finish))
+               ((char= #\\ ch)
+                (let ((ch (read-char stream nil nil)))
+                  (unless ch
+                    (error "unterminated ~:[string~;character~] literal ending with incomplete escape"
+                           (char= terminator #\')))
+                  (save ch)))
+               (t
+                (save ch)))
+        :finally (return buffer)))))
+
+
+(defparameter *yacc-readtable* (let ((rt (copy-readtable nil)))
+                                 (setf (readtable-case rt) :preserve)
+                                 (remove-all-macro-characters rt)
+                                 (set-macro-character #\" 'read-delimited-string nil rt)
+                                 (set-macro-character #\' 'read-delimited-string nil rt)
+                                 (set-macro-character #\: 'read-colon nil rt)
+                                 rt))
+
+(defun read-header (stream)
+  (let ((*readtable*  *yacc-readtable*))
+    (loop
+      :with tokens := '()
+      :with start := nil
+      :for line = (let ((line (read-line stream nil nil)))
+                    (when line
+                      (string-trim *whitespaces* (remove-comments line))))
+      :while (and line (string/= "%%" line))
+      :when (plusp (length line))
+        :do (with-input-from-string (in line)
+              (let ((directive (read in)))
+                (case directive
+                  ((|%token|)
+                   (setf tokens (nconc (loop
+                                         :for token := (read in nil nil)
+                                         :while token
+                                         :do (check-type token symbol)
+                                         :collect token) tokens)))
+                  ((|%start|)
+                   (setf start (read in nil nil))
+                   (check-type start symbol))
+                  (otherwise
+                   (format *error-output* "Unexpected yacc directive: ~S~%" directive)))))
+      :finally (return (list :start start :tokens tokens)))))
+
+
+(define-parser *Yacc-parser*
+  (:start-symbol rules)
+  (:terminals (lchar \: \| identifier \;))
+  (rules        (rule)
+                (rule rules #'cons))
+  (rule         (identifier \: alternatives \;
+                            (lambda (i c as s)
+                              (declare (ignore c s))
+                              (cons i (mapcar (lambda (a)
+                                                (if (and (listp a) (= 1 (length a)))
+                                                    (first a)
+                                                    a))
+                                              as)))))
+  (alternatives (rhs)
+                (rhs \| alternatives
+                     (lambda (r p a)
+                       (declare (ignore p))
+                       (if r
+                           (cons r a)
+                           a))))
+  (rhs          ()
+                (term rhs #'cons))
+  (term         lchar
+                identifier))
+
+(defun make-lexer (scanner)
+  (lambda ()
+    (let ((token (scan-next-token scanner)))
+      (if (eq (token-kind token) 'com.informatimago.common-lisp.parser.scanner::<END\ OF\ SOURCE>)
+          (values nil nil)
+          (values (token-kind token) token)))))
+
+(defun read-rules (stream)
+  (let* ((lines   (remove "" (mapcar (lambda (line) (string-trim *whitespaces* line))
+                                   (stream-to-string-list stream))
+                        :test (function string=)))
+         (end     (member "%%" lines :test (function string=)))
+         (scanner (make-instance 'c11-scanner :source (remove-comments (mapconcat (function identity) (ldiff lines end) " "))))
+         (lexer   (make-lexer scanner)))
+    #-(and)
+    (parse-with-lexer lexer *yacc-parser*)
+    (maptree (lambda (token)
+               (ecase (token-kind token)
+                 ((identifier) (intern (token-text token)))
+                 ((lchar)      (intern (string (code-char (character-value (token-text token))))))))
+             (print (parse-with-lexer lexer *yacc-parser*)))))
+
+(defun read-footer (stream)
+  )
+
+(defun read-yacc (stream name)
+  (let* ((header (read-header stream))
+         (rules  (read-rules  stream)))
+    (pprint `(define-parser ,name
+               (:start-symbol ,(getf header :start (first (first rules))))
+               (:terminals ,(getf header :tokens))
+               ,@rules))))
+
+#-(and) (
+
+ (with-open-file (stream #P"~/src/public/lisp/languages/c11/parser.yacc")
+   (read-yacc stream))
+         )
+
+;;;; THE END ;;;;
diff --git a/languages/c11/scanner.lex b/languages/c11/scanner.lex
new file mode 100644
index 0000000..0baead6
--- /dev/null
+++ b/languages/c11/scanner.lex
@@ -0,0 +1,176 @@
+
+D			[0-9]
+L			[a-zA-Z_]
+H			[a-fA-F0-9]
+E			[Ee][+-]?{D}+
+FS			(f|F|l|L)
+IS			(u|U|l|L)*
+
+%{
+#include <stdio.h>
+#include "y.tab.h"
+
+void count();
+%}
+
+%%
+"/*"			{ comment(); }
+
+"auto"			{ count(); return(AUTO); }
+"break"			{ count(); return(BREAK); }
+"case"			{ count(); return(CASE); }
+"char"			{ count(); return(CHAR); }
+"const"			{ count(); return(CONST); }
+"continue"		{ count(); return(CONTINUE); }
+"default"		{ count(); return(DEFAULT); }
+"do"			{ count(); return(DO); }
+"double"		{ count(); return(DOUBLE); }
+"else"			{ count(); return(ELSE); }
+"enum"			{ count(); return(ENUM); }
+"extern"		{ count(); return(EXTERN); }
+"float"			{ count(); return(FLOAT); }
+"for"			{ count(); return(FOR); }
+"goto"			{ count(); return(GOTO); }
+"if"			{ count(); return(IF); }
+"int"			{ count(); return(INT); }
+"long"			{ count(); return(LONG); }
+"register"		{ count(); return(REGISTER); }
+"return"		{ count(); return(RETURN); }
+"short"			{ count(); return(SHORT); }
+"signed"		{ count(); return(SIGNED); }
+"sizeof"		{ count(); return(SIZEOF); }
+"static"		{ count(); return(STATIC); }
+"struct"		{ count(); return(STRUCT); }
+"switch"		{ count(); return(SWITCH); }
+"typedef"		{ count(); return(TYPEDEF); }
+"union"			{ count(); return(UNION); }
+"unsigned"		{ count(); return(UNSIGNED); }
+"void"			{ count(); return(VOID); }
+"volatile"		{ count(); return(VOLATILE); }
+"while"			{ count(); return(WHILE); }
+
+{L}({L}|{D})*		{ count(); return(check_type()); }
+
+0[xX]{H}+{IS}?		{ count(); return(CONSTANT); }
+0{D}+{IS}?		{ count(); return(CONSTANT); }
+{D}+{IS}?		{ count(); return(CONSTANT); }
+L?'(\\.|[^\\'])+'	{ count(); return(CONSTANT); } /* ' */
+
+{D}+{E}{FS}?		{ count(); return(CONSTANT); }
+{D}*"."{D}+({E})?{FS}?	{ count(); return(CONSTANT); }
+{D}+"."{D}*({E})?{FS}?	{ count(); return(CONSTANT); }
+
+L?\"(\\.|[^\\"])*\"	{ count(); return(STRING_LITERAL); } /* " */
+
+"..."			{ count(); return(ELLIPSIS); }
+">>="			{ count(); return(RIGHT_ASSIGN); }
+"<<="			{ count(); return(LEFT_ASSIGN); }
+"+="			{ count(); return(ADD_ASSIGN); }
+"-="			{ count(); return(SUB_ASSIGN); }
+"*="			{ count(); return(MUL_ASSIGN); }
+"/="			{ count(); return(DIV_ASSIGN); }
+"%="			{ count(); return(MOD_ASSIGN); }
+"&="			{ count(); return(AND_ASSIGN); }
+"^="			{ count(); return(XOR_ASSIGN); }
+"|="			{ count(); return(OR_ASSIGN); }
+">>"			{ count(); return(RIGHT_OP); }
+"<<"			{ count(); return(LEFT_OP); }
+"++"			{ count(); return(INC_OP); }
+"--"			{ count(); return(DEC_OP); }
+"->"			{ count(); return(PTR_OP); }
+"&&"			{ count(); return(AND_OP); }
+"||"			{ count(); return(OR_OP); }
+"<="			{ count(); return(LE_OP); }
+">="			{ count(); return(GE_OP); }
+"=="			{ count(); return(EQ_OP); }
+"!="			{ count(); return(NE_OP); }
+";"			{ count(); return(';'); }
+("{"|"<%")		{ count(); return('{'); }
+("}"|"%>")		{ count(); return('}'); }
+","			{ count(); return(','); }
+":"			{ count(); return(':'); }
+"="			{ count(); return('='); }
+"("			{ count(); return('('); }
+")"			{ count(); return(')'); }
+("["|"<:")		{ count(); return('['); }
+("]"|":>")		{ count(); return(']'); }
+"."			{ count(); return('.'); }
+"&"			{ count(); return('&'); }
+"!"			{ count(); return('!'); }
+"~"			{ count(); return('~'); }
+"-"			{ count(); return('-'); }
+"+"			{ count(); return('+'); }
+"*"			{ count(); return('*'); }
+"/"			{ count(); return('/'); }
+"%"			{ count(); return('%'); }
+"<"			{ count(); return('<'); }
+">"			{ count(); return('>'); }
+"^"			{ count(); return('^'); }
+"|"			{ count(); return('|'); }
+"?"			{ count(); return('?'); }
+
+[ \t\v\n\f]		{ count(); }
+.			{ /* ignore bad characters */ }
+
+%%
+
+yywrap()
+{
+	return(1);
+}
+
+
+comment()
+{
+	char c, c1;
+
+loop:
+	while ((c = input()) != '*' && c != 0)
+		putchar(c);
+
+	if ((c1 = input()) != '/' && c != 0)
+	{
+		unput(c1);
+		goto loop;
+	}
+
+	if (c != 0)
+		putchar(c1);
+}
+
+
+int column = 0;
+
+void count()
+{
+	int i;
+
+	for (i = 0; yytext[i] != '\0'; i++)
+		if (yytext[i] == '\n')
+			column = 0;
+		else if (yytext[i] == '\t')
+			column += 8 - (column % 8);
+		else
+			column++;
+
+	ECHO;
+}
+
+
+int check_type()
+{
+/*
+* pseudo code --- this is what it should check
+*
+*	if (yytext == type_name)
+*		return(TYPE_NAME);
+*
+*	return(IDENTIFIER);
+*/
+
+/*
+*	it actually will only return IDENTIFIER
+*/
+
+	return(IDENTIFIER);
+}
diff --git a/languages/c11/scanner.lisp b/languages/c11/scanner.lisp
new file mode 100644
index 0000000..a412e95
--- /dev/null
+++ b/languages/c11/scanner.lisp
@@ -0,0 +1,157 @@
+;;;; -*- mode:lisp;coding:utf-8 -*-
+;;;;**************************************************************************
+;;;;FILE:               scanner.lisp
+;;;;LANGUAGE:           Common-Lisp
+;;;;SYSTEM:             Common-Lisp
+;;;;USER-INTERFACE:     NONE
+;;;;DESCRIPTION
+;;;;
+;;;;    C11 Scanner.
+;;;;
+;;;;AUTHORS
+;;;;    <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
+;;;;MODIFICATIONS
+;;;;    2015-07-02 <PJB> Created.
+;;;;BUGS
+;;;;LEGAL
+;;;;    AGPL3
+;;;;
+;;;;    Copyright Pascal J. Bourguignon 2015 - 2015
+;;;;
+;;;;    This program is free software: you can redistribute it and/or modify
+;;;;    it under the terms of the GNU Affero General Public License as published by
+;;;;    the Free Software Foundation, either version 3 of the License, or
+;;;;    (at your option) any later version.
+;;;;
+;;;;    This program 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 Affero General Public License for more details.
+;;;;
+;;;;    You should have received a copy of the GNU Affero General Public License
+;;;;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;;;**************************************************************************
+(in-package "COM.INFORMATIMAGO.LANGUAGES.C11.PARSER")
+
+(define-scanner c11-scanner
+  :terminals  (
+               "!" "!=" "%" "%=" "%>" "&" "&&" "&=" "(" ")"
+               "*" "*=" "+" "++" "+=" "," "-" "--" "-=" "->" "." "..."
+               "/" "/=" ":" ":>" ";" "<" "<%" "<:" "<<" "<<=" "<=" "="
+               "==" ">" ">=" ">>" ">>=" "?" "[" "]" "^" "^=" "_Bool"
+               "_Complex" "_Imaginary" "__asm__" "__builtin_va_list"
+               "__const" "__inline" "__inline__" "__restrict" "asm"
+               "auto" "break" "case" "char" "const" "continue"
+               "default" "do" "double" "else" "enum" "extern" "float"
+               "for" "goto" "if" "inline" "int" "long" "register"
+               "restrict" "return" "short" "signed" "sizeof" "static"
+               "struct" "switch" "typedef" "union" "unsigned" "void"
+               "volatile" "while" "{" "|" "|=" "||" "}" "~" "~="
+               (identifier "[a-zA-Z_$][a-zA-Z_$0-9]*")
+               (hex        "0[xX][0-9A-Fa-f]+[uUlL]*")
+               (oct        "0[0-7]+[uUlL]*")
+               (dec        "[0-9]+[uUlL]*")
+               (lchar      "L?'(\\.|[^\\'])+'")
+               (flt1       "[0-9]+[Ee][-+]?[0-9]+[fFlL]?")
+               (flt2       "[0-9]*\\.[0-9]+([Ee][-+]?[0-9]+)?[fFlL]?")
+               (flt3       "[0-9]+\\.[0-9]*([Ee][-+]?[0-9]+)?[fFlL]?")
+               (str        "L?\"(\\.|[^\\\"])*\""))
+  :alphanumerics "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$"
+  :spaces (load-time-value  (coerce (remove-duplicates
+                                     '(#\Space
+                                       #\Newline
+                                       #+has-tab     #\Tab
+                                       #+has-page    #\Page
+                                       #+has-null    #\Null
+                                       #+(and has-return   (not newline-is-return))   #\Return
+                                       #+(and has-linefeed (not newline-is-linefeed)) #\Linefeed))
+                                    'string)))
+
+
+(defparameter *c11-literal-tokens*
+  '("!" "!=" "%" "%=" "%>" "&" "&&" "&=" "(" ")"
+    "*" "*=" "+" "++" "+=" "," "-" "--" "-=" "->" "." "..."
+    "/" "/=" ":" ":>" ";" "<" "<%" "<:" "<<" "<<=" "<=" "="
+    "==" ">" ">=" ">>" ">>=" "?" "[" "]" "^" "^=" "_Bool"
+    "_Complex" "_Imaginary" "__asm__" "__builtin_va_list"
+    "__const" "__inline" "__inline__" "__restrict" "asm"
+    "auto" "break" "case" "char" "const" "continue"
+    "default" "do" "double" "else" "enum" "extern" "float"
+    "for" "goto" "if" "inline" "int" "long" "register"
+    "restrict" "return" "short" "signed" "sizeof" "static"
+    "struct" "switch" "typedef" "union" "unsigned" "void"
+    "volatile" "while" "{" "|" "|=" "||" "}" "~" "~="))
+
+(defparameter *c11-literal-tokens-map*
+  (let ((table (make-hash-table :test 'equal)))
+    (dolist (token *c11-literal-tokens* table)
+      (setf (gethash token table) (intern token)))))
+
+(defparameter *c11-regexp-tokens*
+  ;; order matters
+  '((lchar      "L?'(\\.|[^\\'])+'")
+    (str        "L?\"(\\.|[^\\\"])*\"")
+    (identifier "[a-zA-Z_$][a-zA-Z_$0-9]*")
+    (flt1       "[0-9]+[Ee][-+]?[0-9]+[fFlL]?")
+    (flt2       "[0-9]*\\.[0-9]+([Ee][-+]?[0-9]+)?[fFlL]?")
+    (flt3       "[0-9]+\\.[0-9]*([Ee][-+]?[0-9]+)?[fFlL]?")
+    (hex        "0[xX][0-9A-Fa-f]+[uUlL]*")
+    (oct        "0[0-7]+[uUlL]*")
+    (dec        "[0-9]+[uUlL]*")))
+
+(defun compute-token-kind (token)
+  (let ((text  (token-text token)))
+    (or (gethash text *c11-literal-tokens-map*)
+        (first (find-if (lambda (entry)
+                          (string-match (format nil "^~A$" (second entry)) text))
+                        *c11-regexp-tokens*)))))
+
+
+#-(and) (
+         (mapcar 'compute-token-kind (subseq *tc* 0 100))
+         (|typedef| |unsigned| |int| identifier \; |typedef| |signed| |char| identifier \; |typedef| |unsigned| |char| identifier \; |typedef| |short| identifier \; |typedef| |unsigned| |short| identifier \; |typedef| |int| identifier \; |typedef| |unsigned| |int| identifier \; |typedef| |long| |long| identifier \; |typedef| |unsigned| |long| |long| identifier \; |typedef| |long| identifier \; |typedef| |unsigned| |int| identifier \; |typedef| |int| identifier \; |typedef| |union| { |char| identifier [ dec ] \; |long| |long| identifier \; } identifier \; |typedef| identifier identifier \; |typedef| |int| identifier \; |typedef| |unsigned| |long| identifier \; |typedef| |__builtin_va_list| identifier \; |typedef| identifier identifier \; |typedef| identifier identifier \; |typedef| identifier)
+
+         ("typedef" "unsigned" "int" "bool_bf" ";" "typedef" "signed" "char" "__int8_t" ";" "typedef" "unsigned" "char" "__uint8_t" ";" "typedef" "short" "__int16_t" ";" "typedef" "unsigned" "short" "__uint16_t" ";" "typedef" "int" "__int32_t" ";" "typedef" "unsigned" "int" "__uint32_t" ";" "typedef" "long" "long" "__int64_t" ";" "typedef" "unsigned" "long" "long" "__uint64_t" ";" "typedef" "long" "__darwin_intptr_t" ";" "typedef" "unsigned" "int" "__darwin_natural_t" ";" "typedef" "int" "__darwin_ct_rune_t" ";" "typedef" "union" "{" "char" "__mbstate8" "[" "128" "]" ";" "long" "long" "_mbstateL" ";" "}" "__mbstate_t" ";" "typedef" "__mbstate_t" "__darwin_mbstate_t" ";" "typedef" "int" "__darwin_ptrdiff_t" ";" "typedef" "unsigned" "long" "__darwin_size_t" ";" "typedef" "__builtin_va_list" "__darwin_va_list" ";" "typedef" "__darwin_ct_rune_t" "__darwin_wchar_t" ";" "typedef" "__darwin_wchar_t" "__darwin_rune_t" ";" "typedef" "__darwin_ct_rune_t")
+
+
+
+         (let ((*readtable*               vacietis:c-readtable)
+               (vacietis:*compiler-state* (vacietis:make-compiler-state)))
+           (with-open-file (src #P"~/src/lisp/c/duff-device.c")
+             (read src)))
+
+         (defparameter *s* (make-instance 'c11-scanner :source (com.informatimago.common-lisp.cesarum.file:text-file-contents
+                                                                #P"~/src/public/lisp/languages/cpp/tests/out.c")))
+         (defparameter *t*
+           (let ((scanner  (make-instance 'c11-scanner :source (com.informatimago.common-lisp.cesarum.file:text-file-contents
+                                                                #P"~/src/public/lisp/languages/cpp/tests/out.c"))))
+             (loop for token =  (scan-next-token scanner)
+                   until (eq (token-kind token) 'com.informatimago.common-lisp.parser.scanner::<END\ OF\ SOURCE>)
+                   collect (print token))))
+
+         (defparameter *tc*
+           (reduce (function append)
+                   (reverse (com.informatimago.languages.cpp::context-output-lines
+                             (cpp-e "/Users/pjb/src/public/lisp/languages/cpp/tests/emacs.c"
+                                    :trace-includes t
+                                    :defines '("__GNUC__" "4" "__STDC__" "1" "__x86_64__" "1")
+                                    :includes '("/Users/pjb/src/macosx/emacs-24.5/src/")
+                                    :include-bracket-directories '("/Users/pjb/src/macosx/emacs-24.5/src/"
+                                                                   "/Users/pjb/src/macosx/emacs-24.5/lib/"
+                                                                   "/Users/pjb/src/macosx/gcc-4.9.2/gcc/ginclude/"
+                                                                   "/usr/include/")
+                                    :write-processed-lines nil)))
+                   :initial-value '()))
+
+         (dolist (token *tc*)
+           (setf (token-kind token) (compute-token-kind token)))
+
+         (defparameter *yacc*
+           (let ((scanner  (make-instance 'c11-scanner :source (com.informatimago.common-lisp.cesarum.file:text-file-contents
+                                                                #P"scanner.yacc"))))
+             (loop for token =  (scan-next-token scanner)
+                   until (eq (token-kind token) 'com.informatimago.common-lisp.parser.scanner::<END\ OF\ SOURCE>)
+                   collect (print token))))
+
+         )
+;;;; THE END ;;;;
ViewGit