From 26ca5ae9ef9a69ae18e0cdccdde0c58af056f4e9 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sat, 17 Sep 2016 23:56:19 +0900 Subject: [PATCH 01/21] Rewrite by a priori parser from https://www.lysator.liu.se/c/ANSI-C-grammar-y.html with trivial transformation --- src/parser.y | 439 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 332 insertions(+), 107 deletions(-) diff --git a/src/parser.y b/src/parser.y index 52aae5b1..3d12fe64 100644 --- a/src/parser.y +++ b/src/parser.y @@ -91,194 +91,419 @@ identifier : IDENTIFIER ; -expression.opt -: %empty -| expression +constant +: FLOATING_CONSTANT +| INTEGER_CONSTANT +| CHARACTER_CONSTANT ; -expression +string-literal +: STRING_LITERAL +; + +primary-expression : identifier -| INTEGER_CONSTANT +| constant +| string-literal +| '(' expression ')' ; -fundamental-specifier -: VOID -| INT -/* | CHAR */ -/* | SIGNED CHAR */ -/* | UNSIGNED CHAR */ -/* | signed.opt SHORT int.opt */ -/* | UNSIGNED SHORT int.opt */ -/* | signed.opt int.opt */ -/* | UNSIGNED int.opt */ -/* | signed.opt LONG int.opt */ -/* | UNSIGNED LONG int.opt */ -/* | FLOAT */ -/* | DOUBLE */ -/* | LONG DOUBLE */ +postfix-expression +: primary-expression +| postfix-expression '[' expression ']' +| postfix-expression '(' ')' +| postfix-expression '(' argument-expression-list ')' +| postfix-expression '.' identifier +| postfix-expression "->" identifier +| postfix-expression "++" +| postfix-expression "--" ; -storage-class-specifier.opt -: %empty -| storage-class-specifier +argument-expression-list +: assignment-expression +| argument-expression-list ',' assignment-expression ; -storage-class-specifier -: AUTO -| REGISTER -| STATIC +unary-expression +: postfix-expression +| "++" unary-expression +| "--" unary-expression +| unary-operator cast-expression +| "sizeof" unary-expression +| "sizeof" '(' type-name ')' ; -linkage-specifier.opt -: %empty -| linkage-specifier +unary-operator +: '&' +| '*' +| '+' +| '-' +| '~' +| '!' ; -linkage-specifier -: EXTERN -| STATIC +cast-expression +: unary-expression +| '(' type-name ')' cast-expression ; -type-specifier -: fundamental-specifier -/* | struct-or-union-specifier */ -/* | enum-specifier */ -/* | typedef-name */ +multiplicative-expression +: cast-expression +| multiplicative-expression '*' cast-expression +| multiplicative-expression '/' cast-expression +| multiplicative-expression '%' cast-expression ; -declaration-specifiers -: type-specifier -/* : type-specifier type-qualifier-list.opt */ -/* | type-qualifier declaration-specifiers */ +additive-expression +: multiplicative-expression +| additive-expression '+' multiplicative-expression +| additive-expression '-' multiplicative-expression ; -declaration -: declaration-specifiers declarator-list +shift-expression +: additive-expression +| shift-expression "<<" additive-expression +| shift-expression ">>" additive-expression +; + +relational-expression +: shift-expression +| relational-expression '<' shift-expression +| relational-expression '>' shift-expression +| relational-expression "<=" shift-expression +| relational-expression ">=" shift-expression ; -declarator-list.opt -: %empty -| ',' declarator-list +equality-expression +: relational-expression +| equality-expression "==" relational-expression +| equality-expression "!=" relational-expression ; -declarator-list -: declarator declarator-list.opt +and-expression +: equality-expression +| and-expression '&' equality-expression ; -init-declaration -: declaration-specifiers init-declarator-list +exclusive-or-expression +: and-expression +| exclusive-or-expression '^' and-expression ; -init-declarator-list.opt -: %empty -| ',' init-declarator-list +inclusive-or-expression +: exclusive-or-expression +| inclusive-or-expression '|' exclusive-or-expression +; + +logical-and-expression +: inclusive-or-expression +| logical-and-expression "&&" inclusive-or-expression +; + +logical-or-expression +: logical-and-expression +| logical-or-expression "||" 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 +: '=' +| "*=" +| "/=" +| "%=" +| "+=" +| "-=" +| "<<=" +| ">>=" +| "&=" +| "^=" +| "|=" +; + +expression +: assignment-expression +| expression ',' assignment-expression +; + +constant-expression +: conditional-expression +; + +declaration +: declaration-specifiers ';' +| declaration-specifiers init-declarator-list ';' +; + +declaration-specifiers +: storage-class-specifier +| storage-class-specifier declaration-specifiers +| type-specifier +| type-specifier declaration-specifiers +| type-qualifier +| type-qualifier declaration-specifiers ; init-declarator-list -: init-declarator init-declarator-list.opt +: init-declarator +| init-declarator-list ',' init-declarator ; init-declarator : declarator -/* | declarator '=' initializer */ +| declarator '=' initializer +; + +storage-class-specifier +: "typedef" +| "extern" +| "static" +| "auto" +| "register" +; + +type-specifier +: "void" +| "char" +| "short" +| "int" +| "long" +| "float" +| "double" +| "signed" +| "unsigned" +| struct-or-union-specifier +| enum-specifier +| typedef-name +; + +typedef-name +: identifier +; + +struct-or-union-specifier +: struct-or-union identifier '{' struct-declaration-list '}' +| struct-or-union '{' struct-declaration-list '}' +| struct-or-union identifier +; + +struct-or-union +: "struct" +| "union" ; -typedef-declaration -: TYPEDEF declaration +struct-declaration-list +: struct-declaration +| struct-declaration-list struct-declaration +; + +struct-declaration +: specifier-qualifier-list struct-declarator-list ';' +; + +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 +: declarator +| ':' constant-expression +| declarator ':' constant-expression +; + +enum-specifier +: "enum" '{' enumerator-list '}' +| "enum" identifier '{' enumerator-list '}' +| "enum" identifier +; + +enumerator-list +: enumerator +| enumerator-list ',' enumerator +; + +enumerator +: identifier +| identifier '=' constant-expression +; + +type-qualifier +: "const" +| "volatile" ; declarator -: direct-declarator -/* : pointer-list.opt direct-declarator */ +: pointer direct-declarator +| direct-declarator ; direct-declarator : identifier -/* | '(' declarator ')' */ -/* | array-declarator */ -/* | function-declarator */ +| '(' declarator ')' +| direct-declarator '[' constant-expression ']' +| direct-declarator '[' ']' +| direct-declarator '(' parameter-type-list ')' +| direct-declarator '(' identifier-list ')' +| direct-declarator '(' ')' +; + +pointer +: '*' +| '*' type-qualifier-list +| '*' pointer +| '*' type-qualifier-list pointer +; + +type-qualifier-list +: type-qualifier +| type-qualifier-list type-qualifier ; -parameter-declaration-list.opt -: %empty -| ',' parameter-declaration-list + +parameter-type-list +: parameter-list +| parameter-list ',' ELLIPSIS ; -parameter-declaration-list -: parameter-declaration parameter-declaration-list.opt +parameter-list +: parameter-declaration +| parameter-list ',' parameter-declaration ; parameter-declaration : declaration-specifiers declarator -/* | declaration-specifiers abstract-declarator.opt */ +| declaration-specifiers abstract-declarator +| declaration-specifiers +; + +identifier-list +: identifier +| identifier-list ',' identifier ; -statement-list.opt -: %empty -| statement-list +type-name +: specifier-qualifier-list +| specifier-qualifier-list abstract-declarator ; -statement-list -: statement statement-list.opt +abstract-declarator +: pointer +| direct-abstract-declarator +| pointer direct-abstract-declarator +; + +direct-abstract-declarator +: '(' abstract-declarator ')' +| '[' ']' +| '[' constant-expression ']' +| direct-abstract-declarator '[' ']' +| direct-abstract-declarator '[' constant-expression ']' +| '(' ')' +| '(' parameter-type-list ')' +| direct-abstract-declarator '(' ')' +| direct-abstract-declarator '(' parameter-type-list ')' +; + +initializer +: assignment-expression +| '{' initializer-list '}' +| '{' initializer-list ',' '}' +; + +initializer-list +: initializer +| initializer-list ',' initializer ; statement -: compound-statement +: labeled-statement +| compound-statement +| expression-statement +| selection-statement +| iteration-statement | jump-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 -: '{' declaration-statement-list.opt statement-list.opt '}' +: '{' '}' +| '{' statement-list '}' +| '{' declaration-list '}' +| '{' declaration-list statement-list '}' ; -declaration-statement-list.opt -: %empty -| declaration-statement-list +declaration-list +: declaration +| declaration-list declaration ; -declaration-statement-list -: declaration-statement declaration-statement-list.opt +statement-list +: statement +| statement-list statement ; -declaration-statement -: storage-class-specifier.opt init-declaration -| typedef-declaration +expression-statement +: ';' +| expression ';' ; -jump-statement -: GOTO identifier ';' -| CONTINUE ';' -| BREAK ';' -| RETURN expression.opt ';' +selection-statement +: "if" '(' expression ')' statement +| "if" '(' expression ')' statement "else" statement +| "switch" '(' expression ')' statement ; -translation-unit.opt -: %empty -| translation-unit +iteration-statement +: "while" '(' expression ')' statement +| "do" statement "while" '(' expression ')' ';' +| "for" '(' expression-statement expression-statement ')' statement +| "for" '(' expression-statement expression-statement expression ')' statement ; -translation-unit -: external-declaration translation-unit.opt +jump-statement +: "goto" identifier ';' +| "continue" ';' +| "break" ';' +| "return" ';' +| "return" expression ';' ; -external-declaration -: linkage-specifier.opt function-definition -| linkage-specifier.opt init-declaration -| typedef-declaration +translation-unit +: external-declaration +| translation-unit external-declaration ; -function-definition-declarator -: identifier '(' parameter-declaration-list ')' +external-declaration +: function-definition +| declaration ; function-definition -: declaration-specifiers function-definition-declarator compound-statement +: declaration-specifiers declarator declaration-list compound-statement +| declaration-specifiers declarator compound-statement +| declarator declaration-list compound-statement +| declarator compound-statement ; %% From 6b0e02f56e50fb38143cb175e10aceb2f9dec9bc Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sat, 17 Sep 2016 23:58:01 +0900 Subject: [PATCH 02/21] Add ELLIPSIS token --- src/lexer.l | 1 + src/parser.y | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lexer.l b/src/lexer.l index 5813707d..735869db 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -104,6 +104,7 @@ INTEGER_SUFFIX ([uU][lL]?|[Ll][uU]?) "&=" return AND_ASSIGN; "|=" return OR_ASSIGN; "^=" return XOR_ASSIGN; +"..." return ELLIPSIS; "auto" return AUTO; "break" return BREAK; diff --git a/src/parser.y b/src/parser.y index 3d12fe64..2a2ec95c 100644 --- a/src/parser.y +++ b/src/parser.y @@ -50,6 +50,7 @@ void set_yyin_string(const char *code); %token AND_ASSIGN "&=" %token OR_ASSIGN "|=" %token XOR_ASSIGN "^=" +%token ELLIPSIS "..." %token AUTO "auto" %token BREAK "break" %token CASE "case" From 82160a8d1064236a23f49635f4b682bb7363cb71 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 00:11:48 +0900 Subject: [PATCH 03/21] '<' and '>' are single character token --- src/lexer.l | 4 +--- src/parser.y | 2 -- tests/lexer_test/lexer_test.cpp | 4 ++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 735869db..68c1f870 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -24,7 +24,7 @@ IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* DIGIT8 "0"[0-7]* DIGIT10 [1-9][0-9]* DIGIT16 ("0x"|"0X")[0-9a-fA-F]+ -SINGLE_CHARACTER_TOKEN [\[\]\(\)\{\}+\-*/%&|^!?=,:;] +SINGLE_CHARACTER_TOKEN [\[\]\(\)\{\}+\-*/%<>&|^!?=,:;] INTEGER_SUFFIX ([uU][lL]?|[Ll][uU]?) %x PREPROCESS %x COMMENT @@ -88,8 +88,6 @@ INTEGER_SUFFIX ([uU][lL]?|[Ll][uU]?) ">>" return RIGHT_SHIFT; "==" return EQUAL; "!=" return NOT_EQUAL; -"<" return LESS; -">" return GREATER; "<=" return LESS_EQUAL; ">=" return GREATER_EQUAL; "&&" return AND; diff --git a/src/parser.y b/src/parser.y index 2a2ec95c..7062f00c 100644 --- a/src/parser.y +++ b/src/parser.y @@ -34,8 +34,6 @@ void set_yyin_string(const char *code); %token RIGHT_SHIFT ">>" %token EQUAL "==" %token NOT_EQUAL "!=" -%token LESS "<" -%token GREATER ">" %token LESS_EQUAL "<=" %token GREATER_EQUAL ">=" %token AND "&&" diff --git a/tests/lexer_test/lexer_test.cpp b/tests/lexer_test/lexer_test.cpp index 42544512..24bdd84a 100644 --- a/tests/lexer_test/lexer_test.cpp +++ b/tests/lexer_test/lexer_test.cpp @@ -59,8 +59,8 @@ TEST(LexerTest, HandlesSingleToken) { EXPECT_EQ('%', lex_first_token("%!n")); EXPECT_EQ(LEFT_SHIFT, lex_first_token("<<*p")); EXPECT_EQ(RIGHT_SHIFT, lex_first_token(">>*p")); - EXPECT_EQ(LESS, lex_first_token("!n")); + EXPECT_EQ('<', lex_first_token("', lex_first_token(">!n")); EXPECT_EQ(LESS_EQUAL, lex_first_token("<=!n")); EXPECT_EQ(GREATER_EQUAL, lex_first_token(">=!n")); EXPECT_EQ('=', lex_first_token("=++n")); From 91b1f88fb7740965ad42b6773d7753459d8663d0 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 00:21:51 +0900 Subject: [PATCH 04/21] Arrange %code area --- src/parser.y | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/parser.y b/src/parser.y index 7062f00c..97c51a78 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,12 +1,4 @@ %code { -#include "utility.h" - -#define AST_ERROR(lhs, rhs) \ - do { \ - yyerror("cannot parse `" lhs "` as `" rhs "`"); \ - YYERROR; \ - } while (false) - void yyerror(const char *); } From f5be7e24b9936ea0bffe8739613e7207c59c7df6 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 19:52:02 +0900 Subject: [PATCH 05/21] Prohibit old-style function declaration --- src/parser.y | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/parser.y b/src/parser.y index 97c51a78..af2e4aef 100644 --- a/src/parser.y +++ b/src/parser.y @@ -350,8 +350,6 @@ direct-declarator | direct-declarator '[' constant-expression ']' | direct-declarator '[' ']' | direct-declarator '(' parameter-type-list ')' -| direct-declarator '(' identifier-list ')' -| direct-declarator '(' ')' ; pointer @@ -383,11 +381,6 @@ parameter-declaration | declaration-specifiers ; -identifier-list -: identifier -| identifier-list ',' identifier -; - type-name : specifier-qualifier-list | specifier-qualifier-list abstract-declarator @@ -405,9 +398,7 @@ direct-abstract-declarator | '[' constant-expression ']' | direct-abstract-declarator '[' ']' | direct-abstract-declarator '[' constant-expression ']' -| '(' ')' | '(' parameter-type-list ')' -| direct-abstract-declarator '(' ')' | direct-abstract-declarator '(' parameter-type-list ')' ; @@ -491,9 +482,7 @@ external-declaration ; function-definition -: declaration-specifiers declarator declaration-list compound-statement -| declaration-specifiers declarator compound-statement -| declarator declaration-list compound-statement +: declaration-specifiers declarator compound-statement | declarator compound-statement ; From 4181214c81fed8cb3e861363c18c94bb27bcc65e Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 13:48:20 +0900 Subject: [PATCH 06/21] Resolve dangling else --- src/parser.y | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parser.y b/src/parser.y index af2e4aef..a67dcb62 100644 --- a/src/parser.y +++ b/src/parser.y @@ -74,6 +74,9 @@ void set_yyin_string(const char *code); %token VOLATILE "volatile" %token WHILE "while" +%precedence ONLY_IF +%precedence ELSE + %start translation-unit %% @@ -451,7 +454,7 @@ expression-statement ; selection-statement -: "if" '(' expression ')' statement +: "if" '(' expression ')' statement %prec ONLY_IF | "if" '(' expression ')' statement "else" statement | "switch" '(' expression ')' statement ; From 38961bce618f099191127c2b5f8e802a014345e8 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 20:15:38 +0900 Subject: [PATCH 07/21] Remove parameter-type-list --- src/parser.y | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/parser.y b/src/parser.y index a67dcb62..ba5cbd68 100644 --- a/src/parser.y +++ b/src/parser.y @@ -352,7 +352,8 @@ direct-declarator | '(' declarator ')' | direct-declarator '[' constant-expression ']' | direct-declarator '[' ']' -| direct-declarator '(' parameter-type-list ')' +| direct-declarator '(' parameter-list ')' +| direct-declarator '(' parameter-list ',' "..." ')' ; pointer @@ -367,12 +368,6 @@ type-qualifier-list | type-qualifier-list type-qualifier ; - -parameter-type-list -: parameter-list -| parameter-list ',' ELLIPSIS -; - parameter-list : parameter-declaration | parameter-list ',' parameter-declaration @@ -401,8 +396,10 @@ direct-abstract-declarator | '[' constant-expression ']' | direct-abstract-declarator '[' ']' | direct-abstract-declarator '[' constant-expression ']' -| '(' parameter-type-list ')' -| direct-abstract-declarator '(' parameter-type-list ')' +| '(' parameter-list ')' +| '(' parameter-list ',' "..." ')' +| direct-abstract-declarator '(' parameter-list ')' +| direct-abstract-declarator '(' parameter-list ',' "..." ')' ; initializer From 9d6a2d9abe9340e066164d16757ee4d4ae75476d Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 01:18:26 +0900 Subject: [PATCH 08/21] Transform argument-expression-list --- src/parser.y | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/parser.y b/src/parser.y index ba5cbd68..d896533e 100644 --- a/src/parser.y +++ b/src/parser.y @@ -114,8 +114,12 @@ postfix-expression ; argument-expression-list +: argument-expression +| argument-expression-list ',' argument-expression +; + +argument-expression : assignment-expression -| argument-expression-list ',' assignment-expression ; unary-expression From 7e24dc444d7c980f2565f711d7277d1b5786f801 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 20:07:04 +0900 Subject: [PATCH 09/21] Transform specifier-qualifier-list --- src/parser.y | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/parser.y b/src/parser.y index d896533e..3f8145ba 100644 --- a/src/parser.y +++ b/src/parser.y @@ -308,9 +308,12 @@ struct-declaration ; specifier-qualifier-list -: type-specifier specifier-qualifier-list -| type-specifier -| type-qualifier specifier-qualifier-list +: specifier-qualifier +| specifier-qualifier specifier-qualifier-list +; + +specifier-qualifier +: type-specifier | type-qualifier ; From 799f8f562c25be3fb13ed4347a7a62dcb9306707 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 19:58:01 +0900 Subject: [PATCH 10/21] Transform parameter-type-list to parameter-declaration-list --- src/parser.y | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/parser.y b/src/parser.y index 3f8145ba..00b68c4c 100644 --- a/src/parser.y +++ b/src/parser.y @@ -359,8 +359,8 @@ direct-declarator | '(' declarator ')' | direct-declarator '[' constant-expression ']' | direct-declarator '[' ']' -| direct-declarator '(' parameter-list ')' -| direct-declarator '(' parameter-list ',' "..." ')' +| direct-declarator '(' parameter-declaration-list ')' +| direct-declarator '(' parameter-declaration-list ',' "..." ')' ; pointer @@ -375,9 +375,9 @@ type-qualifier-list | type-qualifier-list type-qualifier ; -parameter-list +parameter-declaration-list : parameter-declaration -| parameter-list ',' parameter-declaration +| parameter-declaration-list ',' parameter-declaration ; parameter-declaration @@ -403,10 +403,10 @@ direct-abstract-declarator | '[' constant-expression ']' | direct-abstract-declarator '[' ']' | direct-abstract-declarator '[' constant-expression ']' -| '(' parameter-list ')' -| '(' parameter-list ',' "..." ')' -| direct-abstract-declarator '(' parameter-list ')' -| direct-abstract-declarator '(' parameter-list ',' "..." ')' +| '(' parameter-declaration-list ')' +| '(' parameter-declaration-list ',' "..." ')' +| direct-abstract-declarator '(' parameter-declaration-list ')' +| direct-abstract-declarator '(' parameter-declaration-list ',' "..." ')' ; initializer From 7ef15b6ac11581ec9dfc1d98489a806dc7f874ab Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 19:59:35 +0900 Subject: [PATCH 11/21] Transform pointer into pointer-list --- src/parser.y | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/parser.y b/src/parser.y index 00b68c4c..1888ebef 100644 --- a/src/parser.y +++ b/src/parser.y @@ -350,7 +350,7 @@ type-qualifier ; declarator -: pointer direct-declarator +: pointer-list direct-declarator | direct-declarator ; @@ -363,11 +363,14 @@ direct-declarator | direct-declarator '(' parameter-declaration-list ',' "..." ')' ; -pointer -: '*' -| '*' type-qualifier-list -| '*' pointer -| '*' type-qualifier-list pointer +pointer-list.opt +: %empty +| pointer-list +; + +pointer-list +: '*' pointer-list.opt +| '*' type-qualifier-list pointer-list.opt ; type-qualifier-list @@ -392,9 +395,9 @@ type-name ; abstract-declarator -: pointer +: pointer-list | direct-abstract-declarator -| pointer direct-abstract-declarator +| pointer-list direct-abstract-declarator ; direct-abstract-declarator From f9d64c60d7b3ae151b95fd6699c82d132905db68 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 20:18:07 +0900 Subject: [PATCH 12/21] Straightforward list transformation --- src/parser.y | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/parser.y b/src/parser.y index 1888ebef..bf602532 100644 --- a/src/parser.y +++ b/src/parser.y @@ -298,18 +298,26 @@ struct-or-union | "union" ; +struct-declaration-list.opt +: %empty +| struct-declaration-list +; + struct-declaration-list -: struct-declaration -| struct-declaration-list struct-declaration +: struct-declaration struct-declaration-list.opt ; struct-declaration : specifier-qualifier-list struct-declarator-list ';' ; +specifier-qualifier-list.opt +: %empty +| specifier-qualifier-list +; + specifier-qualifier-list -: specifier-qualifier -| specifier-qualifier specifier-qualifier-list +: specifier-qualifier specifier-qualifier-list.opt ; specifier-qualifier @@ -373,9 +381,13 @@ pointer-list | '*' type-qualifier-list pointer-list.opt ; +type-qualifier-list.opt +: %empty +| type-qualifier-list +; + type-qualifier-list -: type-qualifier -| type-qualifier-list type-qualifier +: type-qualifier type-qualifier-list.opt ; parameter-declaration-list @@ -445,14 +457,22 @@ compound-statement | '{' declaration-list statement-list '}' ; +declaration-list.opt +: %empty +| declaration-list +; + declaration-list -: declaration -| declaration-list declaration +: declaration declaration-list.opt +; + +statement-list.opt +: %empty +| statement-list ; statement-list -: statement -| statement-list statement +: statement statement-list.opt ; expression-statement From 413bf5bebf115b57a91e81902ac0f03097244a6c Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 13:10:51 +0900 Subject: [PATCH 13/21] Introduce declaration-specifiers.opt --- src/parser.y | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/parser.y b/src/parser.y index bf602532..58bc0508 100644 --- a/src/parser.y +++ b/src/parser.y @@ -241,13 +241,15 @@ declaration | declaration-specifiers init-declarator-list ';' ; +declaration-specifiers.opt +: %empty +| declaration-specifiers +; + declaration-specifiers -: storage-class-specifier -| storage-class-specifier declaration-specifiers -| type-specifier -| type-specifier declaration-specifiers -| type-qualifier -| type-qualifier declaration-specifiers +: storage-class-specifier declaration-specifiers.opt +| type-specifier declaration-specifiers.opt +| type-qualifier declaration-specifiers.opt ; init-declarator-list From e137898a6c71359dc5b80a0b33b60125d65f5216 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 13:23:17 +0900 Subject: [PATCH 14/21] Introduce identifier.opt --- src/parser.y | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/parser.y b/src/parser.y index 58bc0508..dde9602c 100644 --- a/src/parser.y +++ b/src/parser.y @@ -81,6 +81,11 @@ void set_yyin_string(const char *code); %% +identifier.opt +: %empty +| IDENTIFIER +; + identifier : IDENTIFIER ; @@ -290,8 +295,7 @@ typedef-name ; struct-or-union-specifier -: struct-or-union identifier '{' struct-declaration-list '}' -| struct-or-union '{' struct-declaration-list '}' +: struct-or-union identifier.opt '{' struct-declaration-list '}' | struct-or-union identifier ; @@ -339,8 +343,7 @@ struct-declarator ; enum-specifier -: "enum" '{' enumerator-list '}' -| "enum" identifier '{' enumerator-list '}' +: "enum" identifier.opt '{' enumerator-list '}' | "enum" identifier ; From 7eddb5746cf15b19396c43abc4dc1a4f6c057c5d Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 20:00:07 +0900 Subject: [PATCH 15/21] Introduce constant-expression.opt --- src/parser.y | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/parser.y b/src/parser.y index dde9602c..4f1c5678 100644 --- a/src/parser.y +++ b/src/parser.y @@ -237,6 +237,11 @@ expression | expression ',' assignment-expression ; +constant-expression.opt +: %empty +| constant-expression +; + constant-expression : conditional-expression ; @@ -370,8 +375,7 @@ declarator direct-declarator : identifier | '(' declarator ')' -| direct-declarator '[' constant-expression ']' -| direct-declarator '[' ']' +| direct-declarator '[' constant-expression.opt ']' | direct-declarator '(' parameter-declaration-list ')' | direct-declarator '(' parameter-declaration-list ',' "..." ')' ; @@ -419,10 +423,8 @@ abstract-declarator direct-abstract-declarator : '(' abstract-declarator ')' -| '[' ']' -| '[' constant-expression ']' -| direct-abstract-declarator '[' ']' -| direct-abstract-declarator '[' constant-expression ']' +| '[' constant-expression.opt ']' +| direct-abstract-declarator '[' constant-expression.opt ']' | '(' parameter-declaration-list ')' | '(' parameter-declaration-list ',' "..." ')' | direct-abstract-declarator '(' parameter-declaration-list ')' From ec55a6af744ebf2f70c185090a75926c5baa5b28 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 13:26:10 +0900 Subject: [PATCH 16/21] Introduce expression.opt --- src/parser.y | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/parser.y b/src/parser.y index 4f1c5678..fd80f6be 100644 --- a/src/parser.y +++ b/src/parser.y @@ -232,6 +232,11 @@ assignment-operator | "|=" ; +expression.opt +: %empty +| expression +; + expression : assignment-expression | expression ',' assignment-expression @@ -483,8 +488,7 @@ statement-list ; expression-statement -: ';' -| expression ';' +: expression.opt ';' ; selection-statement @@ -496,16 +500,14 @@ selection-statement iteration-statement : "while" '(' expression ')' statement | "do" statement "while" '(' expression ')' ';' -| "for" '(' expression-statement expression-statement ')' statement -| "for" '(' expression-statement expression-statement expression ')' statement +| "for" '(' expression.opt ';' expression.opt ';' expression.opt ')' statement ; jump-statement : "goto" identifier ';' | "continue" ';' | "break" ';' -| "return" ';' -| "return" expression ';' +| "return" expression.opt ';' ; translation-unit From 6156f7e049cc184d3ee5271f8b6c3bc3f5e13834 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 20:12:45 +0900 Subject: [PATCH 17/21] Shrink pointer-list by using type-qualifier-list.opt --- src/parser.y | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/parser.y b/src/parser.y index fd80f6be..c23dff1b 100644 --- a/src/parser.y +++ b/src/parser.y @@ -391,8 +391,7 @@ pointer-list.opt ; pointer-list -: '*' pointer-list.opt -| '*' type-qualifier-list pointer-list.opt +: '*' type-qualifier-list.opt pointer-list.opt ; type-qualifier-list.opt From 16ff4436d4b0ae2b22102e4d69ffabe1d4b2fa73 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 13:38:50 +0900 Subject: [PATCH 18/21] Shrink declarator and abstract-declarator by using pointer-list.opt --- src/parser.y | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/parser.y b/src/parser.y index c23dff1b..271cb3a7 100644 --- a/src/parser.y +++ b/src/parser.y @@ -373,8 +373,7 @@ type-qualifier ; declarator -: pointer-list direct-declarator -| direct-declarator +: pointer-list.opt direct-declarator ; direct-declarator @@ -421,8 +420,7 @@ type-name abstract-declarator : pointer-list -| direct-abstract-declarator -| pointer-list direct-abstract-declarator +| pointer-list.opt direct-abstract-declarator ; direct-abstract-declarator From dc0f88ea96d7b9e993a4c1dc2bbf3bc1136b400d Mon Sep 17 00:00:00 2001 From: hatsusato Date: Sun, 18 Sep 2016 20:01:41 +0900 Subject: [PATCH 19/21] Shrink compound-statement by using declaration-list.opt and statement-list.opt --- src/parser.y | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/parser.y b/src/parser.y index 271cb3a7..8588fb37 100644 --- a/src/parser.y +++ b/src/parser.y @@ -460,10 +460,7 @@ labeled-statement ; compound-statement -: '{' '}' -| '{' statement-list '}' -| '{' declaration-list '}' -| '{' declaration-list statement-list '}' +: '{' declaration-list.opt statement-list.opt '}' ; declaration-list.opt From b9cd5122a3f6955093717f10ddfb4980f6de28b7 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Thu, 22 Sep 2016 00:44:14 +0900 Subject: [PATCH 20/21] Return type of functions must be specified explicitly --- src/parser.y | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parser.y b/src/parser.y index 8588fb37..c426036b 100644 --- a/src/parser.y +++ b/src/parser.y @@ -516,7 +516,6 @@ external-declaration function-definition : declaration-specifiers declarator compound-statement -| declarator compound-statement ; %% From a1ae53f0af256f3cd3c332decf9a4650032e71c5 Mon Sep 17 00:00:00 2001 From: hatsusato Date: Wed, 21 Sep 2016 22:54:47 +0900 Subject: [PATCH 21/21] Add TYPENAME token --- src/parser.y | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/parser.y b/src/parser.y index c426036b..a44c2741 100644 --- a/src/parser.y +++ b/src/parser.y @@ -14,6 +14,7 @@ void set_yyin_string(const char *code); #define YYSTYPE SexprRef } +%token TYPENAME %token IDENTIFIER %token FLOATING_CONSTANT %token INTEGER_CONSTANT @@ -81,6 +82,10 @@ void set_yyin_string(const char *code); %% +typedef-name +: TYPENAME +; + identifier.opt : %empty | IDENTIFIER @@ -300,10 +305,6 @@ type-specifier | typedef-name ; -typedef-name -: identifier -; - struct-or-union-specifier : struct-or-union identifier.opt '{' struct-declaration-list '}' | struct-or-union identifier