📄 yacc.y
字号:
%{
/***********************************************************
Yacc script of DCC
dusiqi 2007
***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "utility.h"
#include "syntax.h"
#include "symbol.h"
#include "genasm.h"
extern bool all_id_flag;
extern int blocklevel;
int yylex();
void yyerror(char *info);
#define alloca malloc
%}
/*the if-else shift/reduce conflict,
we shift default according to bison agorithm*/
%expect 1
%token IDENTIFIER USERTYPE CINT CUINT CFLOAT SCHAR STRING CBOOL
/*basic data type*/
%token SHORT LONG SIGNED UNSIGNED BOOL VOID CHAR INT FLOAT DOUBLE STRUCT UNION ENUM TYPEDEF
/*storage class*/
%token STATIC EXTERN AUTO CONST ELLIPSIS VOLATILE REGISTER
/*basic statement*/
%token IF ELSE FOR WHILE DO SWITCH CASE DEFAULT GOTO RETURN BREAK CONTINUE ASM
/*operator*/
%token NTOMEM PTOMEM SIZEOF INCR DECR
%token LSH RSH EQ UEQ GTR GEQ LES LEQ LAND LOR
%token ASSIGN ADDAS SUBAS MULAS DIVAS MODAS LSHAS RSHAS XORAS ORAS ANDAS
%union{
StmtNode *stmt;
ExpNode *exp;
Symbol *sym;
Type *type;
enum en_sc sc;
enum en_bt bt;
SuperType *st;
/* for constant */
ConstValue val;
}
%type <stmt>declaration struct_declaration_list
struct_declaration statement labeled_statement
compound_statement expression_statement selection_statement
iteration_statement jump_statement statement_list
%type <exp> initializer initializer_list null_expression expression
primary_expression postfix_expression unary_expression
multiplicative_expression additive_expression
shift_expression relational_expression equality_expression
and_expression exclusive_or_expression inclusive_or_expression
logical_and_expression logical_or_expression conditional_expression
assignment_expression
%type <sym> init_declarator_list enumerator_list enumerator init_declarator
declarator_list declarator direct_declarator parameter_type_list
parameter_list parameter_declaration
%type <st> declaration_specifiers
%type <sc> storage_specifier
%type <bt> basic_type basic_type_word struct
%type <type> type_specifier struct_specifier enum_specifier
abstract_type_specifier pointer USERTYPE
%type <val> IDENTIFIER CINT CUINT CFLOAT SCHAR STRING CBOOL
assignment_operator unary_operator
%start C_code
%% /* Grammar for DCC */
C_code
: translation_unit
| C_code translation_unit
;
translation_unit
: function_definition
| global_declaration
;
function_definition
: declaration_specifiers declarator
{
global_define($1, $2);
prepare_local($2);
}
compound_statement
{
gen_funcbody($4);
exit_local();
}
;
global_declaration
: declaration
{
global_define($1->spec, $1->declist);
}
;
declaration
: declaration_specifiers ';'
{
$$=newDeclStmt($1, NULL, currentfile, lineno);
}
| declaration_specifiers init_declarator_list ';'
{
$$=newDeclStmt($1, $2, currentfile, lineno);
}
;
declaration_specifiers
: type_specifier
{
$$ = newSuperType(UNKNOWN, $1);
}
| storage_specifier type_specifier
{
$$ = newSuperType($1, $2);
}
;
storage_specifier
: TYPEDEF
{$$=sc_typedef;}
| EXTERN
{$$=sc_external;}
| STATIC
{$$=sc_static;}
| AUTO
{$$=sc_auto;}
| REGISTER
{$$ = sc_register;}
;
type_specifier
: basic_type
{$$=newType(NULL, $1, NULL);}
| struct_specifier
{$$=$1;}
| enum_specifier
{$$=newType(NULL, bt_long, NULL);}
| USERTYPE
{$$=$1;}
;
basic_type
: basic_type_word
{$$=$1;}
| basic_type_word basic_type
{$$=check_basictype($1, $2);}
;
basic_type_word
: VOID
{$$ = bt_void;}
| CHAR
{$$ = bt_char;}
| SHORT
{$$ = bt_short;}
| INT
{$$ = bt_int;}
| UNSIGNED
{$$ = bt_unsignedint;}
| LONG
{$$ = bt_long;}
| SIGNED
{$$ = bt_int;}
| FLOAT
{$$ = bt_float;}
| DOUBLE
{$$ = bt_double;}
| BOOL
{$$ = bt_long;}
;
struct_specifier
: struct IDENTIFIER
{
Type *one = newType($2.s, $1, NULL);
//maybe one is not true
$<type>$=add_newType(one);
}
'{' struct_declaration_list '}'
{
$$=$<type>3;
$$->memlist = member_declare($1, $5, &($$->size));
}
| struct '{' struct_declaration_list '}'
{
$$ = newType(NULL, $1, NULL);
$$->memlist = member_declare($1, $3, &($$->size));
}
| struct IDENTIFIER
{
Type *one = newType($2.s, $1, NULL);
$$=add_newType(one);
}
;
struct
: STRUCT
{$$=bt_struct;}
| UNION
{$$=bt_union;}
;
struct_declaration_list
: struct_declaration
{$$=$1;}
| struct_declaration_list struct_declaration
{
appendObject(&$1, $2);
$$=$1;
}
;
struct_declaration
: declaration_specifiers declarator_list ';'
{
$$=newDeclStmt($1, $2, currentfile, lineno);
}
;
enum_specifier
: ENUM '{' enumerator_list '}'
{}
| ENUM IDENTIFIER '{' enumerator_list '}'
{}
| ENUM IDENTIFIER
{}
;
enumerator_list
: enumerator
{
if($1->value.i==UNKNOWN)
$1->value.i=0;
$$ = $1;
}
| enumerator_list ',' enumerator
{
if($3->value.i==UNKNOWN)
$3->value.i=$1->value.i+1;
$$ = $3;
}
;
enumerator
: IDENTIFIER
{
$$ = newEnumerator($1.s, NULL);
}
| IDENTIFIER ASSIGN assignment_expression
{
$$ = newEnumerator($1.s, $3);
}
;
abstract_type_specifier
: type_specifier
{$$ = $1;}
| type_specifier pointer
{$$ = compoundType($2, $1);}
;
pointer
: '*'
{
$$=newType(NULL, bt_pointer, NULL);
}
| '*' pointer
{
$2->subtype = newType(NULL, bt_pointer, NULL);
$$=$2;
}
;
init_declarator_list
: init_declarator
{$$=$1;}
| init_declarator_list ',' init_declarator
{
appendObject(&$1, $3);
$$=$1;
}
;
init_declarator
: declarator
{$$=$1;}
| declarator ASSIGN initializer
{
$1->init = $3;
$$=$1;
}
;
declarator_list
: declarator
{$$=$1;}
| declarator_list ',' declarator
{
appendObject(&$1, $3);
$$ = $1;
}
;
declarator
: pointer direct_declarator
{
$2->datatype = compoundType($2->datatype, $1);
$$ = $2;
}
| direct_declarator
{$$ = $1;}
;
direct_declarator
: IDENTIFIER
{
$$ = newSymbol($1.s, UNKNOWN, NULL);
}
| '(' declarator ')'
{$$=$2;}
| direct_declarator '[' assignment_expression ']'
{
Type *extype = newType(NULL, bt_pointer, $3);
$1->datatype = compoundType($1->datatype, extype);
$$ = $1;
}
| direct_declarator '[' ']'
{
Type *extype = newType(NULL, bt_pointer, evaluate_void_exp());
$1->datatype = compoundType($1->datatype, extype);
$$ = $1;
}
| direct_declarator '(' parameter_type_list ')'
{
Type *func = newType(NULL, bt_func, NULL);
func->arglist = $3;
$1->datatype = compoundType($1->datatype, func);
$$ = $1;
}
| direct_declarator '(' ')'
{
Type *func = newType(NULL, bt_func, NULL);
func->arglist = newSymbol(NULL, UNKNOWN,
newType(NULL, bt_void, NULL));
$1->datatype = compoundType($1->datatype, func);
$$ = $1;
}
;
parameter_type_list
: parameter_list
{
$$=$1;
}
| parameter_list ',' ELLIPSIS
{
Symbol *one;
one = newSymbol("...", sc_arg, newType(NULL, bt_ellipsis, NULL));
appendObject(&$1, one);
$$ = $1;
}
;
parameter_list
: parameter_declaration
{
$$ = $1;
}
| parameter_list ',' parameter_declaration
{
appendObject(&$1, $3);
$$ = $1;
}
;
parameter_declaration
: type_specifier declarator
{
$2->storage_class = sc_arg;
$2->datatype = compoundType($2->datatype, $1);
$$=$2;
}
| type_specifier pointer
{
$$=newSymbol(NULL, sc_arg, compoundType($2, $1));
}
;
initializer
: assignment_expression
{
$$ = $1;
}
| '{' initializer_list '}'
{
$$ = evaluate_brace_exp($2);
}
;
initializer_list
: initializer
{
$$ = $1;
}
| initializer_list ',' initializer
{
appendObject(&$1, $3);
$$ = $1;
}
;
statement
: labeled_statement
{$$=$1;}
| compound_statement
{$$=$1;}
| expression_statement
{$$=$1;}
| selection_statement
{$$=$1;}
| iteration_statement
{$$=$1;}
| jump_statement
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -