diff options
Diffstat (limited to 'src/uscxml/plugins/datamodel/c89/parser/c89.ypp')
-rw-r--r-- | src/uscxml/plugins/datamodel/c89/parser/c89.ypp | 681 |
1 files changed, 681 insertions, 0 deletions
diff --git a/src/uscxml/plugins/datamodel/c89/parser/c89.ypp b/src/uscxml/plugins/datamodel/c89/parser/c89.ypp new file mode 100644 index 0000000..8e113c8 --- /dev/null +++ b/src/uscxml/plugins/datamodel/c89/parser/c89.ypp @@ -0,0 +1,681 @@ +%{ +#include "../C89Parser.h" +#include "c89.tab.hpp" +#include <sys/types.h> +#include <stdarg.h> + +#define YYMAXDEPTH 20000 // default is 10000 +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +extern int c89_lex (C89_STYPE* yylval_param, C89_LTYPE* yylloc_param, void* yyscanner); + +using namespace uscxml; +%} + +%pure-parser +%debug +%locations +%file-prefix "c89" +%parse-param { uscxml::C89Parser* ctx } +%lex-param {void * scanner} +%parse-param {void * scanner} +%define api.prefix {c89_} +%defines + +%union { + uscxml::C89ParserNode* node; + char* value; +} + +%error-verbose + +%type <node> primary_expression expression postfix_expression +%type <node> argument_expression_list assignment_expression +%type <node> unary_expression unary_operator cast_expression +%type <node> type_name assignment_operator +%type <node> multiplicative_expression additive_expression shift_expression +%type <node> relational_expression equality_expression and_expression +%type <node> exclusive_or_expression inclusive_or_expression +%type <node> logical_and_expression logical_or_expression conditional_expression +%type <node> specifier_qualifier_list abstract_declarator +%type <node> type_specifier type_qualifier struct_or_union_specifier +%type <node> enum_specifier pointer direct_abstract_declarator +%type <node> struct_or_union enumerator_list enumerator +%type <node> constant_expression type_qualifier_list +%type <node> parameter_type_list parameter_declaration parameter_list +%type <node> declaration_specifiers declarator storage_class_specifier +%type <node> init_declarator_list init_declarator initializer +%type <node> direct_declarator initializer_list identifier_list +%type <node> statement labeled_statement compound_statement expression_statement +%type <node> selection_statement iteration_statement jump_statement +%type <node> statement_list declaration_list declaration +%type <node> translation_unit external_declaration function_definition +%type <node> struct_declarator struct_declaration +%type <node> struct_declarator_list struct_declaration_list + +%type <node> VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED TYPE_NAME +%type <node> CONST VOLATILE + +%type <value> IDENTIFIER CONSTANT STRING_LITERAL + +%token IDENTIFIER CONSTANT STRING_LITERAL 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 TYPE_NAME + +%token TYPEDEF EXTERN STATIC AUTO REGISTER +%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID +%token STRUCT UNION ENUM ELLIPSIS + +%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN + +%start translation_unit +%% + + +primary_expression + : IDENTIFIER { + $$ = ctx->value(IDENTIFIER, (void*)&(@1), $1); free($1); + } + | CONSTANT { + $$ = ctx->value(CONSTANT, (void*)&(@1), $1); free($1); + } + | STRING_LITERAL { + $$ = ctx->value(STRING_LITERAL, (void*)&(@1), $1); free($1); + } + | '(' expression ')' { + $$ = $2; + } + ; + +postfix_expression + : primary_expression { + $$ = $1; + } + | postfix_expression '[' expression ']' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | postfix_expression '(' ')' { + $$ = ctx->node(__LINE__, 1, $1); + } + | postfix_expression '(' argument_expression_list ')' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | postfix_expression '.' IDENTIFIER { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | postfix_expression PTR_OP IDENTIFIER { + $$ = ctx->node(PTR_OP, 2, $1, $3); + } + | postfix_expression INC_OP { + $$ = ctx->node(INC_OP, 1, $1); + } + | postfix_expression DEC_OP { + $$ = ctx->node(DEC_OP, 1, $1); + } + ; + +argument_expression_list + : assignment_expression { + $$ = $1; + } + | argument_expression_list ',' assignment_expression { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +unary_expression + : postfix_expression { + $$ = $1; + } + | INC_OP unary_expression { + $$ = ctx->node(INC_OP, 1, $2); + } + | DEC_OP unary_expression { + $$ = ctx->node(DEC_OP, 1, $2); + } + | unary_operator cast_expression { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | SIZEOF unary_expression { + $$ = ctx->node(SIZEOF, 1, $2); + } + | SIZEOF '(' type_name ')' { + $$ = ctx->node(SIZEOF, 1, $3); + } + ; + +unary_operator + : '&' { $$ = ctx->node(__LINE__, 0); } + | '*' { $$ = ctx->node(__LINE__, 0); } + | '+' { $$ = ctx->node(__LINE__, 0); } + | '-' { $$ = ctx->node(__LINE__, 0); } + | '~' { $$ = ctx->node(__LINE__, 0); } + | '!' { $$ = ctx->node(__LINE__, 0); } + ; + +cast_expression + : unary_expression { $$ = $1; } + | '(' type_name ')' cast_expression { $$ = ctx->node(__LINE__, 2, $2, $4); } + ; + +multiplicative_expression + : cast_expression { $$ = $1; } + | multiplicative_expression '*' cast_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | multiplicative_expression '/' cast_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | multiplicative_expression '%' cast_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +additive_expression + : multiplicative_expression { $$ = $1; } + | additive_expression '+' multiplicative_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | additive_expression '-' multiplicative_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +shift_expression + : additive_expression { $$ = $1; } + | shift_expression LEFT_OP additive_expression { + $$ = ctx->node(LEFT_OP, 2, $1, $3); + } + | shift_expression RIGHT_OP additive_expression { + $$ = ctx->node(RIGHT_OP, 2, $1, $3); + } + ; + +relational_expression + : shift_expression { $$ = $1; } + | relational_expression '<' shift_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | relational_expression '>' shift_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | relational_expression LE_OP shift_expression { + $$ = ctx->node(LE_OP, 2, $1, $3); + } + | relational_expression GE_OP shift_expression { + $$ = ctx->node(GE_OP, 2, $1, $3); + } + ; + +equality_expression + : relational_expression { $$ = $1; } + | equality_expression EQ_OP relational_expression { + $$ = ctx->node(EQ_OP, 2, $1, $3); + } + | equality_expression NE_OP relational_expression { + $$ = ctx->node(NE_OP, 2, $1, $3); + } + ; + +and_expression + : equality_expression { $$ = $1; } + | and_expression '&' equality_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +exclusive_or_expression + : and_expression { $$ = $1; } + | exclusive_or_expression '^' and_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +inclusive_or_expression + : exclusive_or_expression { $$ = $1; } + | inclusive_or_expression '|' exclusive_or_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +logical_and_expression + : inclusive_or_expression { $$ = $1; } + | logical_and_expression AND_OP inclusive_or_expression { + $$ = ctx->node(AND_OP, 2, $1, $3); + } + ; + +logical_or_expression + : logical_and_expression { $$ = $1; } + | logical_or_expression OR_OP logical_and_expression { + $$ = ctx->node(OR_OP, 2, $1, $3); + } + ; + +conditional_expression + : logical_or_expression { $$ = $1; } + | logical_or_expression '?' expression ':' conditional_expression { + $$ = ctx->node(__LINE__, 3, $1, $3, $5); + } + ; + +assignment_expression + : conditional_expression { $$ = $1; } + | unary_expression assignment_operator assignment_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +assignment_operator + : '=' { $$ = ctx->node('=', 0); } + | MUL_ASSIGN { $$ = ctx->node(MUL_ASSIGN, 0); } + | DIV_ASSIGN { $$ = ctx->node(DIV_ASSIGN, 0); } + | MOD_ASSIGN { $$ = ctx->node(MOD_ASSIGN, 0); } + | ADD_ASSIGN { $$ = ctx->node(ADD_ASSIGN, 0); } + | SUB_ASSIGN { $$ = ctx->node(SUB_ASSIGN, 0); } + | LEFT_ASSIGN { $$ = ctx->node(LEFT_ASSIGN, 0); } + | RIGHT_ASSIGN { $$ = ctx->node(RIGHT_ASSIGN, 0); } + | AND_ASSIGN { $$ = ctx->node(AND_ASSIGN, 0); } + | XOR_ASSIGN { $$ = ctx->node(XOR_ASSIGN, 0); } + | OR_ASSIGN { $$ = ctx->node(OR_ASSIGN, 0); } + ; + +expression + : assignment_expression { $$ = $1; } + | expression ',' assignment_expression { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +constant_expression + : conditional_expression { $$ = $1; } + ; + +declaration + : declaration_specifiers ';' { $$ = $1; } + | declaration_specifiers init_declarator_list ';' { + $$ = ctx->node(',', 2, $1, $2); + } + ; + +declaration_specifiers + : storage_class_specifier { $$ = $1; } + | storage_class_specifier declaration_specifiers { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | type_specifier { $$ = $1; } + | type_specifier declaration_specifiers { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | type_qualifier { $$ = $1; } + | type_qualifier declaration_specifiers { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + ; + +init_declarator_list + : init_declarator { $$ = $1; } + | init_declarator_list ',' init_declarator { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +init_declarator + : declarator { $$ = $1; } + | declarator '=' initializer { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +storage_class_specifier + : TYPEDEF { $$ = ctx->node(TYPEDEF, 0); } + | EXTERN { $$ = ctx->node(EXTERN, 0); } + | STATIC { $$ = ctx->node(STATIC, 0); } + | AUTO { $$ = ctx->node(AUTO, 0); } + | REGISTER { $$ = ctx->node(REGISTER, 0); } + ; + +type_specifier + : VOID { $$ = ctx->node(VOID, 0); } + | CHAR { $$ = ctx->node(CHAR, 0); } + | SHORT { $$ = ctx->node(SHORT, 0); } + | INT { $$ = ctx->node(INT, 0); } + | LONG { $$ = ctx->node(LONG, 0); } + | FLOAT { $$ = ctx->node(FLOAT, 0); } + | DOUBLE { $$ = ctx->node(DOUBLE, 0); } + | SIGNED { $$ = ctx->node(SIGNED, 0); } + | UNSIGNED { $$ = ctx->node(UNSIGNED, 0); } + | struct_or_union_specifier { $$ = $1; } + | enum_specifier { $$ = $1; } + | TYPE_NAME { $$ = ctx->node(TYPE_NAME, 0); } + ; + +struct_or_union_specifier + : struct_or_union IDENTIFIER '{' struct_declaration_list '}' { + $$ = ctx->node(__LINE__, 3, $1, $2, $4); + } + | struct_or_union '{' struct_declaration_list '}' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | struct_or_union IDENTIFIER { + $$ = ctx->node(__LINE__, 1, $1); + } + ; + +struct_or_union + : STRUCT { $$ = ctx->node(STRUCT, 0); } + | UNION { $$ = ctx->node(STRUCT, 1); } + ; + +struct_declaration_list + : struct_declaration { $$ = $1; } + | struct_declaration_list struct_declaration { + $$ = ctx->node(',', 2, $1, $2); + } + ; + +struct_declaration + : specifier_qualifier_list struct_declarator_list ';' { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + ; + +specifier_qualifier_list + : type_specifier specifier_qualifier_list { + $$ = ctx->node(',', 2, $1, $2); + } + | type_specifier { $$ = $1; } + | type_qualifier specifier_qualifier_list { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | type_qualifier { $$ = $1; } + ; + +struct_declarator_list + : struct_declarator { $$ = $1; } + | struct_declarator_list ',' struct_declarator { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +struct_declarator + : declarator { $$ = $1; } + | ':' constant_expression { + $$ = ctx->node(__LINE__, 1, $2); + } + | declarator ':' constant_expression { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +enum_specifier + : ENUM '{' enumerator_list '}' { $$ = ctx->node(ENUM, 1, $3); } + | ENUM IDENTIFIER '{' enumerator_list '}' { $$ = ctx->node(ENUM, 2, $2, $4); } + | ENUM IDENTIFIER { $$ = ctx->node(ENUM, 1, $2); } + ; + +enumerator_list + : enumerator { $$ = $1; } + | enumerator_list ',' enumerator { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +enumerator + : IDENTIFIER { + $$ = ctx->value(IDENTIFIER, (void*)&(@1), $1); free($1); + } + | IDENTIFIER '=' constant_expression { $$ = ctx->node(__LINE__, 2, $1, $3); } + ; + +type_qualifier + : CONST { $$ = $1; } + | VOLATILE { $$ = $1; } + ; + +declarator + : pointer direct_declarator { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | direct_declarator { $$ = $1; } + ; + +direct_declarator + : IDENTIFIER { + $$ = ctx->value(IDENTIFIER, (void*)&(@1), $1); free($1); + } + | '(' declarator ')' { + $$ = ctx->node(__LINE__, 1, $2); + } + | direct_declarator '[' constant_expression ']' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | direct_declarator '[' ']' { + $$ = ctx->node(__LINE__, 1, $1); + } + | direct_declarator '(' parameter_type_list ')' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | direct_declarator '(' identifier_list ')' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | direct_declarator '(' ')' { + $$ = ctx->node(__LINE__, 1, $1); + } + ; + +pointer + : '*' { $$ = ctx->node(__LINE__, 0); } + | '*' type_qualifier_list { $$ = ctx->node(__LINE__, 1, $2); } + | '*' pointer { $$ = ctx->node(__LINE__, 1, $2); } + | '*' type_qualifier_list pointer { $$ = ctx->node(__LINE__, 2, $2, $3); } + ; + +type_qualifier_list + : type_qualifier { $$ = $1; } + | type_qualifier_list type_qualifier { + $$ = ctx->node(',', 2, $1, $2); + } + ; + + +parameter_type_list + : parameter_list { $$ = $1; } + | parameter_list ',' ELLIPSIS { $$ = ctx->node(ELLIPSIS, 1, $1); } + ; + +parameter_list + : parameter_declaration { $$ = $1; } + | parameter_list ',' parameter_declaration { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +parameter_declaration + : declaration_specifiers declarator { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | declaration_specifiers abstract_declarator { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + | declaration_specifiers { $$ = $1; } + ; + +identifier_list + : IDENTIFIER { + $$ = ctx->value(IDENTIFIER, (void*)&(@1), $1); free($1); + } + | identifier_list ',' IDENTIFIER { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +type_name + : specifier_qualifier_list { $$ = $1; } + | specifier_qualifier_list abstract_declarator { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + ; + +abstract_declarator + : pointer { $$ = $1; } + | direct_abstract_declarator { $$ = $1; } + | pointer direct_abstract_declarator { $$ = $1; } + ; + +direct_abstract_declarator + : '(' abstract_declarator ')' { $$ = $2; } + | '[' ']' { $$ = ctx->node(__LINE__, 0); } + | '[' constant_expression ']' { $$ = $2; } + | direct_abstract_declarator '[' ']' { $$ = $1; } + | direct_abstract_declarator '[' constant_expression ']' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + | '(' ')' { $$ = ctx->node(__LINE__, 0); } + | '(' parameter_type_list ')' { $$ = ctx->node(__LINE__, 1, $2); } + | direct_abstract_declarator '(' ')' { $$ = ctx->node(__LINE__, 1, $1); } + | direct_abstract_declarator '(' parameter_type_list ')' { + $$ = ctx->node(__LINE__, 2, $1, $3); + } + ; + +initializer + : assignment_expression { $$ = $1; } + | '{' initializer_list '}' { + $$ = ctx->node(__LINE__, 1, $2); + } + | '{' initializer_list ',' '}' { + $$ = ctx->node(__LINE__, 1, $2); + } + ; + +initializer_list + : initializer { $$ = $1; } + | initializer_list ',' initializer { + $$ = ctx->node(',', 2, $1, $3); + } + ; + +statement + : labeled_statement { $$ = $1; } + | compound_statement { $$ = $1; } + | expression_statement { $$ = $1; } + | selection_statement { $$ = $1; } + | iteration_statement { $$ = $1; } + | jump_statement { $$ = $1; } + ; + +labeled_statement + : IDENTIFIER ':' statement { + $$ = ctx->node(IDENTIFIER, 2, $1, $3); + } + | CASE constant_expression ':' statement { + $$ = ctx->node(CASE, 2, $2, $4); + } + | DEFAULT ':' statement { + $$ = ctx->node(DEFAULT, 1, $3); + } + ; + +compound_statement + : '{' '}' { + $$ = ctx->node(__LINE__, 0); + } + | '{' statement_list '}' { + $$ = ctx->node(__LINE__, 1, $2); + } + | '{' declaration_list '}' { + $$ = ctx->node(__LINE__, 1, $2); + } + | '{' declaration_list statement_list '}' { + $$ = ctx->node(__LINE__, 2, $2, $3); + } + ; + +declaration_list + : declaration { $$ = $1; } + | declaration_list declaration { + $$ = ctx->node(',', 2, $1, $2); + } + ; + +statement_list + : statement { $$ = $1; } + | statement_list statement { + $$ = ctx->node(',', 2, $1, $2); + } + ; + +expression_statement + : ';' { + $$ = ctx->node(__LINE__, 0); + } + | expression ';' { + $$ = $1; + } + ; + +selection_statement + : IF '(' expression ')' statement { + $$ = ctx->node(IF, 2, $3, $5); + } + | IF '(' expression ')' statement ELSE statement { + $$ = ctx->node(IF, 3, $3, $5, $7); + } + | SWITCH '(' expression ')' statement { + $$ = ctx->node(SWITCH, 2, $3, $5); + } + ; + +iteration_statement + : WHILE '(' expression ')' statement { + $$ = ctx->node(WHILE, 2, $3, $5); + } + | DO statement WHILE '(' expression ')' ';' { + $$ = ctx->node(DO, 2, $5, $2); + } + | FOR '(' expression_statement expression_statement ')' statement { + $$ = ctx->node(FOR, 3, $3, $4, $6); + } + | FOR '(' expression_statement expression_statement expression ')' statement { + $$ = ctx->node(FOR, 4, $3, $4, $5, $7); + } + ; + +jump_statement + : GOTO IDENTIFIER ';' { $$ = ctx->node(GOTO, 1, $2); } + | CONTINUE ';' { $$ = ctx->node(CONTINUE, 0); } + | BREAK ';' { $$ = ctx->node(BREAK, 0); } + | RETURN ';' { $$ = ctx->node(RETURN, 0); } + | RETURN expression ';' { $$ = ctx->node(RETURN, 1, $2); } + ; + +translation_unit + : external_declaration { $$ = $1; } + | translation_unit external_declaration { $$ = ctx->node(__LINE__, 2, $1, $2); } + ; + +external_declaration + : function_definition { $$ = $1; } + | declaration { $$ = $1; } + ; + +function_definition + : declaration_specifiers declarator declaration_list compound_statement { + $$ = ctx->node(__LINE__, 4, $1, $2, $3, $4); + } + | declaration_specifiers declarator compound_statement { + $$ = ctx->node(__LINE__, 3, $1, $2, $3); + } + | declarator declaration_list compound_statement { + $$ = ctx->node(__LINE__, 3, $1, $2, $3); + } + | declarator compound_statement { + $$ = ctx->node(__LINE__, 2, $1, $2); + } + ; + +%% |