⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fincyacc.y

📁 FinC is Fava in C! A C-like syntax language. It s designed to apply to embededd system.
💻 Y
字号:
%{#include <stdio.h>#include <finctype.h>#include <fincnode.h>#include <finclang.h>#ifndef YYDEBUG#define	YYDEBUG	 1	/* Default to no yydebug support */#endif%}%union {	FinCNode* expr;	FinCTypeType type;	double val_float;	int val_int;	char val_string[100];	char identifier[100];}%token IF ELSE RETURN WHILE FOR CONTINUE BREAK%token V_TRUE V_FALSE V_NULL%token IMPORT OPT_PARAM ADDR_OF CONTENT_OF%token VOID CHAR SHORT INT FLOAT DOUBLE POINTER STRING BOOL%token STRUCT NATIVE STATIC UNSIGNED PACKAGE%token PLUS INC SUB DEC ASSIGN EQ NE LE GE%token<identifier> IDENTIFIER%token<val_int>    V_INT%token<val_float>  V_FLOAT%token<val_string> V_STRING%type<expr> decl%type<expr> decl_global decl_struct decl_local decl_function decl_import%type<expr> decl_variable declarator_list declarator%type<expr> decl_param_list decl_param decl_param_type_list%type<expr> decl_pkg decl_pkg_func_list decl_pkg_func%type<expr> struct_declarator_list struct_declarator decl_field_list decl_field_declarator%type<expr> statement statement_list statement_in_block statement_block statement_node%type<expr> statement_if statement_if_else statement_for statement_return statement_while%type<expr> statement_continue statement_break%type<expr> type identifier literal%type<expr> expr expr_assign expr_logic_or expr_logic_and expr_equality expr_relational expr_additive%type<expr> expr_multiplicative expr_unary expr_postfix expr_primary param_list expr_condition expr_cast%type<type> type_basic type_list;%%/************* * Start */input:  /* Nothing */  | input decl;decl:    decl_struct            { finc_lang_decl_add ($1); }  | decl_global            { finc_lang_decl_add ($1); }  | decl_function          { finc_lang_decl_add ($1); }  | decl_import            { finc_lang_decl_add ($1); }  | decl_pkg               { finc_lang_decl_add ($1); }  | error                  { finc_lang_error ("Expecting a declaration"); };/**************** * Declarations */decl_global:    decl_variable                          { $$ = finc_lang_efunc_create1("global", $1); };decl_local:    decl_variable                          { $$ = finc_lang_efunc_create1("local", $1); };decl_variable:    type declarator_list ';'    { $$ = finc_lang_var_create ($1); }  | type identifier '[' V_INT ']'    {      $1->type->array_type = FinCArrayType_Fixed;      $1->type->array_size = $4;      $$ = finc_lang_array_create($1, $2);    }  | type identifier '[' ']'    {      $1->type->array_type = FinCArrayType_Dynamic;      $1->type->array_size = 0;      $$ = finc_lang_array_create($1, $2);    }  | type error    { $$ = NULL;      finc_lang_error ("Missing identifier in variable declaration.");    }  | type declarator_list error    { $$ = NULL;      finc_lang_error ("Missing a ';' in variable declaration.");    };declarator_list:    declarator_list ',' declarator  | declarator;declarator:    identifier                             { finc_lang_var_list_add($1); }  | identifier ASSIGN expr_assign          { finc_lang_var_list_add_init($1, $3); };decl_struct:    STRUCT identifier     { finc_lang_struct_begin($2); }    '{' decl_field_list '}' ';'    { $$ = finc_lang_struct_end(); }  | STRUCT error    { $$ = NULL;      finc_lang_error ("Missing identifier in struct declaration.");    };decl_field_list:    decl_field_declarator  | decl_field_list decl_field_declarator;decl_field_declarator:    type struct_declarator_list ';'    { finc_lang_struct_field_create($1); }  | type identifier '[' V_INT ']'    {      $1->type->array_type = FinCArrayType_Fixed;      $1->type->array_size = $4;      finc_lang_struct_field_create( finc_lang_array_create($1, $2) );    }  | type identifier '[' ']'    {      $1->type->array_type = FinCArrayType_Dynamic;      $1->type->array_size = 0;      finc_lang_struct_field_create( finc_lang_array_create($1, $2) );    };struct_declarator_list:     struct_declarator_list ',' struct_declarator   | struct_declarator;struct_declarator:     identifier                                     { finc_lang_struct_field_add($1); };decl_function:  type identifier  { finc_lang_func_create ($1, $2);  }  '(' decl_param_type_list ')'  statement_block  { $$ = finc_lang_func_finish ($7); };decl_param_type_list:    decl_param_list  | decl_param_list ',' OPT_PARAM                   { finc_lang_func_opt_param(); };decl_param_list:  /* Nothing */                                     { $$ = NULL; }  | decl_param  | decl_param_list ',' decl_param;decl_param:    type identifier    { finc_lang_func_add_param ($1, $2); }  | type identifier '[' ']'    {      $1->type->array_type = FinCArrayType_Dynamic;      $1->type->array_size = 0;      finc_lang_func_add_param ($1, $2);    }  | type identifier '[' error    { finc_lang_error ("Expecting a ']'\n"); }  | type identifier '[' V_INT ']'    {      $1->type->array_type = FinCArrayType_Fixed;      $1->type->array_size = $4;      finc_lang_func_add_param ($1, $2);    }  | type identifier '[' V_INT error    { finc_lang_error ("Expecting a ']'\n"); };decl_import:    IMPORT V_STRING ';'    { $$ = finc_lang_efunc_create1 ("import", finc_lang_data_string_create ($2)); }  | IMPORT V_STRING error    { $$ = NULL;      finc_lang_error ("Missing a ';' in import");    };decl_pkg:    PACKAGE V_STRING { finc_lang_pkg_begin($2); }    '{'    decl_pkg_func_list    '}' ';'    { $$ = finc_lang_pkg_end(); };decl_pkg_func_list:    decl_pkg_func  | decl_pkg_func_list decl_pkg_func;decl_pkg_func:    type identifier    { finc_lang_func_create($1, $2); }    '(' decl_param_type_list ')' ';'    { $$ = finc_lang_pkg_func_add(); };/***************** * Type */type:    type_list                   { $$ = finc_lang_type_create ($1, FinCArrayType_None, 0); }  | identifier                  { $$ = finc_lang_type_create_name ($1, FinCArrayType_None, 0); };type_list:    type_basic                  { $$ = $1; }  | type_list type_basic        { $$ = $1 || $2; };type_basic:    VOID                        { $$ = FinCType_Void; }  | CHAR                        { $$ = FinCType_Char; }  | SHORT                       { $$ = FinCType_Short; }  | INT                         { $$ = FinCType_Int; }  | STRING                      { $$ = FinCType_String; }  | POINTER                     { $$ = FinCType_Pointer; }  | FLOAT                       { $$ = FinCType_Float; }  | DOUBLE                      { $$ = FinCType_Double; }  | BOOL                        { $$ = FinCType_Bool; }  | STATIC                      { $$ = FinCType_Static; }  | UNSIGNED                    { $$ = FinCType_Unsigned; }  | NATIVE                      { $$ = FinCType_Native; };identifier:  IDENTIFIER                    { $$ =  finc_node_new_name ($1); };literal:    V_STRING                    { $$ = finc_lang_data_string_create ($1);   }  | V_INT                       { $$ = finc_lang_data_integer_create ($1);  }  | V_FLOAT                     { $$ = finc_lang_data_float_create ($1);    }  | V_TRUE                      { $$ = finc_lang_data_bool_create (TRUE);   }  | V_FALSE                     { $$ = finc_lang_data_bool_create (FALSE);  }  | V_NULL                      { $$ = finc_lang_data_pointer_create (NULL); };/******************* * Expressions */expr:    expr_assign                               { $$ = $1; }  | expr ',' expr_assign                      { $$ = finc_lang_efunc_create2 (",", $1, $3);};expr_assign:    expr_condition  | expr_unary ASSIGN expr_assign             { $$ = finc_lang_efunc_create2 ("=", $1, $3); };expr_condition:    expr_logic_or                             { $$ =$1; }  | expr_logic_or '?' expr ':' expr_condition { $$ = finc_lang_efunc_create3("?", $1, $3, $5); };expr_logic_or:    expr_logic_and                            { $$ = $1; }  | expr_logic_or '|' '|' expr_logic_and      { $$ = finc_lang_efunc_create2 ("||", $1, $4); };expr_logic_and:    expr_equality                             { $$ = $1; }  | expr_logic_and '&' '&' expr_equality      { $$ = finc_lang_efunc_create2 ("&&", $1, $4); };expr_equality:    expr_relational                           { $$ = $1; }  | expr_equality EQ expr_relational          { $$ = finc_lang_efunc_create2 ("==", $1, $3); }  | expr_equality NE expr_relational          { $$ = finc_lang_efunc_create2 ("!=", $1, $3); };expr_relational:    expr_additive                             { $$ = $1; }  | expr_relational '<' expr_additive         { $$ = finc_lang_efunc_create2 ("<", $1, $3); }  | expr_relational '>' expr_additive         { $$ = finc_lang_efunc_create2 (">", $1, $3); }  | expr_relational LE expr_additive          { $$ = finc_lang_efunc_create2 ("<=", $1, $3); }  | expr_relational GE expr_additive          { $$ = finc_lang_efunc_create2 (">=", $1, $3); };expr_additive:    expr_multiplicative                       { $$ = $1; }  | expr_additive SUB expr_multiplicative     { $$ = finc_lang_efunc_create2 ("-", $1, $3); }  | expr_additive PLUS expr_multiplicative    { $$ = finc_lang_efunc_create2 ("+", $1, $3); };expr_multiplicative:    expr_cast                                 { $$ = $1; }  | expr_multiplicative '*' expr_cast         { $$ = finc_lang_efunc_create2 ("*", $1, $3); }  | expr_multiplicative '/' expr_cast         { $$ = finc_lang_efunc_create2 ("/", $1, $3); };expr_cast:    expr_unary                                { $$ =$1; }  | '(' type ')' expr_cast                    { $$ = finc_lang_efunc_create2 ("cast", $2, $4); };expr_unary:    expr_postfix                              { $$ = $1; }  | PLUS expr_cast                            { $$ = finc_lang_efunc_create1 ("plus", $2); }  | SUB expr_cast                             { $$ = finc_lang_efunc_create1 ("negative", $2); }  | ADDR_OF '(' expr_unary ')'                { $$ = finc_lang_efunc_create1 ("addr_of", $3); }  | CONTENT_OF '(' expr_unary ')'             { $$ = finc_lang_efunc_create1 ("content_of", $3)}  | ADDR_OF error    { $$ = NULL;      finc_lang_error("Missing '(' in addrof operator");      yyerrok;    }  | ADDR_OF '(' error    { $$ = NULL;      finc_lang_error("addrof is expecting an <expr>");      yyerrok;    }  | ADDR_OF '(' expr_unary error    { $$ = NULL;      finc_lang_error("Missing ')' in addrof operator");      yyerrok;    }  | CONTENT_OF error    { $$ = NULL;      finc_lang_error("Missing '(' in contentof operator");      yyerrok;    }  | CONTENT_OF '(' error    { $$ = NULL;      finc_lang_error("contentof is expecting an <expr>");      yyerrok;    }  | CONTENT_OF '(' expr_unary error    { $$ = NULL;      finc_lang_error("Missing ')' in contentof operator");      yyerrok;    };expr_postfix:    expr_primary                    { $$ = $1; }  | expr_postfix '[' expr ']'       { $$ = finc_lang_efunc_create2 ("[]", $1, $3); }  | expr_postfix INC                { $$ = finc_lang_efunc_create1 ("++", $1);}  | expr_postfix DEC                { $$ = finc_lang_efunc_create1 ("--", $1);}  | expr_postfix '.' identifier     { $$ = finc_lang_efunc_create2 (".", $1, $3); }  | expr_postfix  { finc_lang_call_begin (string_get_str ($1->identifier));    unref ($1);  }  '(' param_list ')'  { $$ = finc_lang_call_end (); };expr_primary:    literal                         { $$ = $1; }  | '(' expr ')'                    { $$ = $2; }  | identifier                      { $$ = $1; };param_list:    /*Nothing*/                     { $$ = NULL; }  | expr_assign                     { finc_lang_call_add ($1); }  | param_list ',' expr_assign      { finc_lang_call_add ($3); };/********************* * Statements (CODE) */statement:    decl_local                      { $$ = $1; }  | statement_block                 { $$ = $1; }  | statement_node                  { $$ = $1; }  | statement_return                { $$ = $1; }  | statement_for                   { $$ = $1; }  | statement_while                 { $$ = $1; }  | statement_if                    { $$ = $1; }  | statement_continue              { $$ = $1; }  | statement_break                 { $$ = $1; };statement_in_block:    decl_local                      { finc_lang_block_add ($1); }  | statement_block                 { finc_lang_block_add ($1); }  | statement_node                  { finc_lang_block_add ($1); }  | statement_return                { finc_lang_block_add ($1); }  | statement_for                   { finc_lang_block_add ($1); }  | statement_while                 { finc_lang_block_add ($1); }  | statement_if                    { finc_lang_block_add ($1); };statement_block:  '{'  { finc_lang_block_begin (); }  statement_list  '}'  { $$ = finc_lang_block_end (); };statement_list:    statement_in_block  | statement_list statement_in_block;statement_node:    ';'               { $$ = NULL; }  | expr ';'          { $$ = $1; }statement_return:    RETURN expr ';'   { $$ = finc_lang_efunc_create1 ("return", $2); }  | RETURN error ';'    { $$ = NULL;      finc_lang_error ("RETURN is expecting an <expr>");      yyerrok;    }  | RETURN expr error    { $$ = NULL;      finc_lang_error ("Missing a ';' in return statement");      yyerrok;    };statement_for:    FOR '(' statement_node statement_node expr ')' statement    { $$ = finc_lang_efunc_create4 ("for", $3, $4, $5, $7); }  | FOR '(' expr ';' error    { $$ = NULL;      finc_lang_error ("FOR is expecting an <expr>");      yyerrok;    }  | FOR error    { $$ = NULL;      finc_lang_error ("Missing a '(' in for statement");      yyerrok;    };statement_while:    WHILE '(' expr ')' statement    { $$ = finc_lang_efunc_create2 ("while", $3, $5); }  | WHILE '(' error    { $$ = NULL;      finc_lang_error ("WHILE is expecting an <expr>");      yyerrok;    }  | WHILE error    { $$ = NULL;      finc_lang_error ("Missing a '(' in while statement");      yyerrok;    };statement_if:    IF '(' expr ')' statement statement_if_else    { if ($5)        $$ = finc_lang_efunc_create2 ("if", $3, $5);      else        $$ = finc_lang_efunc_create1 ("if", $3);      if ($6)	{	  finc_node_add ($$, $6);	  unref ($6);	}    }  | IF '(' error    { $$ = NULL;      finc_lang_error ("IF is expecting an <expr>");      yyerrok;    }  | IF error    { $$ = NULL;      finc_lang_error ("Missing a '(' in if statement");      yyerrok;    };statement_if_else:    /*Nothing*/         { $$ = NULL; }  | ELSE statement      { $$ = $2; };statement_continue:    CONTINUE ';'        { $$ = finc_lang_efunc_create("continue"); }  | CONTINUE error    { $$ = NULL;      finc_lang_error ("Missing a ';' in continue statement");      yyerrok;    };statement_break:    BREAK ';'           { $$ = finc_lang_efunc_create("break"); }  | BREAK error    { $$ = NULL;      finc_lang_error ("Missing a ';' in break statement");      yyerrok;    }%%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -