mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 00:02:28 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
193
tool/cc/c11.l
Normal file
193
tool/cc/c11.l
Normal file
|
@ -0,0 +1,193 @@
|
|||
/* http://www.quut.com/c/ANSI-C-grammar-l-2011.html */
|
||||
|
||||
%e 1019
|
||||
%p 2807
|
||||
%n 371
|
||||
%k 284
|
||||
%a 1213
|
||||
%o 1117
|
||||
|
||||
O [0-7]
|
||||
D [0-9]
|
||||
NZ [1-9]
|
||||
L [a-zA-Z_]
|
||||
A [a-zA-Z_0-9]
|
||||
H [a-fA-F0-9]
|
||||
HP (0[xX])
|
||||
E ([Ee][+-]?{D}+)
|
||||
P ([Pp][+-]?{D}+)
|
||||
FS (f|F|l|L)
|
||||
IS (((u|U)(l|L|ll|LL)?)|((l|L|ll|LL)(u|U)?))
|
||||
CP (u|U|L)
|
||||
SP (u8|u|U|L)
|
||||
ES (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+))
|
||||
WS [ \t\v\n\f]
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include "y.tab.h"
|
||||
|
||||
extern void yyerror(const char *); /* prints grammar violation message */
|
||||
|
||||
extern int sym_type(const char *); /* returns type from symbol table */
|
||||
|
||||
#define sym_type(identifier) IDENTIFIER /* with no symbol table, fake it */
|
||||
|
||||
static void comment(void);
|
||||
static int check_type(void);
|
||||
%}
|
||||
|
||||
%%
|
||||
"/*" { comment(); }
|
||||
"//".* { /* consume //-comment */ }
|
||||
|
||||
"auto" { return(AUTO); }
|
||||
"break" { return(BREAK); }
|
||||
"case" { return(CASE); }
|
||||
"char" { return(CHAR); }
|
||||
"const" { return(CONST); }
|
||||
"continue" { return(CONTINUE); }
|
||||
"default" { return(DEFAULT); }
|
||||
"do" { return(DO); }
|
||||
"double" { return(DOUBLE); }
|
||||
"else" { return(ELSE); }
|
||||
"enum" { return(ENUM); }
|
||||
"extern" { return(EXTERN); }
|
||||
"float" { return(FLOAT); }
|
||||
"for" { return(FOR); }
|
||||
"goto" { return(GOTO); }
|
||||
"if" { return(IF); }
|
||||
"inline" { return(INLINE); }
|
||||
"int" { return(INT); }
|
||||
"long" { return(LONG); }
|
||||
"register" { return(REGISTER); }
|
||||
"restrict" { return(RESTRICT); }
|
||||
"return" { return(RETURN); }
|
||||
"short" { return(SHORT); }
|
||||
"signed" { return(SIGNED); }
|
||||
"sizeof" { return(SIZEOF); }
|
||||
"static" { return(STATIC); }
|
||||
"struct" { return(STRUCT); }
|
||||
"switch" { return(SWITCH); }
|
||||
"typedef" { return(TYPEDEF); }
|
||||
"union" { return(UNION); }
|
||||
"unsigned" { return(UNSIGNED); }
|
||||
"void" { return(VOID); }
|
||||
"volatile" { return(VOLATILE); }
|
||||
"while" { return(WHILE); }
|
||||
"_Alignas" { return ALIGNAS; }
|
||||
"_Alignof" { return ALIGNOF; }
|
||||
"_Atomic" { return ATOMIC; }
|
||||
"_Bool" { return BOOL; }
|
||||
"_Complex" { return COMPLEX; }
|
||||
"_Generic" { return GENERIC; }
|
||||
"_Imaginary" { return IMAGINARY; }
|
||||
"_Noreturn" { return NORETURN; }
|
||||
"_Static_assert" { return STATIC_ASSERT; }
|
||||
"_Thread_local" { return THREAD_LOCAL; }
|
||||
"__func__" { return FUNC_NAME; }
|
||||
|
||||
{L}{A}* { return check_type(); }
|
||||
|
||||
{HP}{H}+{IS}? { return I_CONSTANT; }
|
||||
{NZ}{D}*{IS}? { return I_CONSTANT; }
|
||||
"0"{O}*{IS}? { return I_CONSTANT; }
|
||||
{CP}?"'"([^'\\\n]|{ES})+"'" { return I_CONSTANT; }
|
||||
|
||||
{D}+{E}{FS}? { return F_CONSTANT; }
|
||||
{D}*"."{D}+{E}?{FS}? { return F_CONSTANT; }
|
||||
{D}+"."{E}?{FS}? { return F_CONSTANT; }
|
||||
{HP}{H}+{P}{FS}? { return F_CONSTANT; }
|
||||
{HP}{H}*"."{H}+{P}{FS}? { return F_CONSTANT; }
|
||||
{HP}{H}+"."{P}{FS}? { return F_CONSTANT; }
|
||||
|
||||
({SP}?\"([^"\\\n]|{ES})*\"{WS}*)+ { return STRING_LITERAL; }
|
||||
|
||||
"..." { return ELLIPSIS; }
|
||||
">>=" { return RIGHT_ASSIGN; }
|
||||
"<<=" { return LEFT_ASSIGN; }
|
||||
"+=" { return ADD_ASSIGN; }
|
||||
"-=" { return SUB_ASSIGN; }
|
||||
"*=" { return MUL_ASSIGN; }
|
||||
"/=" { return DIV_ASSIGN; }
|
||||
"%=" { return MOD_ASSIGN; }
|
||||
"&=" { return AND_ASSIGN; }
|
||||
"^=" { return XOR_ASSIGN; }
|
||||
"|=" { return OR_ASSIGN; }
|
||||
">>" { return RIGHT_OP; }
|
||||
"<<" { return LEFT_OP; }
|
||||
"++" { return INC_OP; }
|
||||
"--" { return DEC_OP; }
|
||||
"->" { return PTR_OP; }
|
||||
"&&" { return AND_OP; }
|
||||
"||" { return OR_OP; }
|
||||
"<=" { return LE_OP; }
|
||||
">=" { return GE_OP; }
|
||||
"==" { return EQ_OP; }
|
||||
"!=" { return NE_OP; }
|
||||
";" { return ';'; }
|
||||
("{"|"<%") { return '{'; }
|
||||
("}"|"%>") { return '}'; }
|
||||
"," { return ','; }
|
||||
":" { return ':'; }
|
||||
"=" { return '='; }
|
||||
"(" { return '('; }
|
||||
")" { return ')'; }
|
||||
("["|"<:") { return '['; }
|
||||
("]"|":>") { return ']'; }
|
||||
"." { return '.'; }
|
||||
"&" { return '&'; }
|
||||
"!" { return '!'; }
|
||||
"~" { return '~'; }
|
||||
"-" { return '-'; }
|
||||
"+" { return '+'; }
|
||||
"*" { return '*'; }
|
||||
"/" { return '/'; }
|
||||
"%" { return '%'; }
|
||||
"<" { return '<'; }
|
||||
">" { return '>'; }
|
||||
"^" { return '^'; }
|
||||
"|" { return '|'; }
|
||||
"?" { return '?'; }
|
||||
|
||||
{WS}+ { /* whitespace separates tokens */ }
|
||||
. { /* discard bad characters */ }
|
||||
|
||||
%%
|
||||
|
||||
int yywrap(void) /* called at end of input */
|
||||
{
|
||||
return 1; /* terminate now */
|
||||
}
|
||||
|
||||
static void comment(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = input()) != 0)
|
||||
if (c == '*')
|
||||
{
|
||||
while ((c = input()) == '*')
|
||||
;
|
||||
|
||||
if (c == '/')
|
||||
return;
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
}
|
||||
yyerror("unterminated comment");
|
||||
}
|
||||
|
||||
static int check_type(void)
|
||||
{
|
||||
switch (sym_type(yytext))
|
||||
{
|
||||
case TYPEDEF_NAME: /* previously defined */
|
||||
return TYPEDEF_NAME;
|
||||
case ENUMERATION_CONSTANT: /* previously defined */
|
||||
return ENUMERATION_CONSTANT;
|
||||
default: /* includes undefined */
|
||||
return IDENTIFIER;
|
||||
}
|
||||
}
|
535
tool/cc/c11.y
Normal file
535
tool/cc/c11.y
Normal file
|
@ -0,0 +1,535 @@
|
|||
/* http://www.quut.com/c/ANSI-C-grammar-y-2011.html */
|
||||
|
||||
%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);
|
||||
}
|
11
tool/cc/cc.mk
Normal file
11
tool/cc/cc.mk
Normal file
|
@ -0,0 +1,11 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += TOOL_CC
|
||||
|
||||
o/$(MODE)/tool/cc/c11.c: tool/cc/c11.l o/$(MODE)/third_party/lex/lex.com.dbg
|
||||
@mkdir -p $(dir $@)
|
||||
o/$(MODE)/third_party/lex/lex.com.dbg -o $@ $<
|
||||
|
||||
.PHONY: o/$(MODE)/tool/cc
|
||||
o/$(MODE)/tool/cc:
|
Loading…
Add table
Add a link
Reference in a new issue