Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/striptool/parser.y
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

1547 lines
37 KiB
Plaintext

%{
#include <stdio.h>
#include <string.h>
typedef enum {
IFDEF_IFDEF,
IFDEF_IFNDEF,
IFDEF_IF,
} IFDEF_TYPE;
typedef enum {
EXPR_SCALAR,
EXPR_FUNC,
EXPR_UNARY,
EXPR_BINARY,
EXPR_TRINARY,
} EXPR_TYPE;
typedef enum {
OP_DEFINED,
OP_PLUS,
OP_MINUS,
OP_MUL,
OP_DIV,
OP_LEFT_SHIFT,
OP_RIGHT_SHIFT,
OP_MOD,
OP_AND,
OP_OR,
OP_NOT,
OP_BIT_AND,
OP_BIT_OR,
OP_BIT_NOT,
OP_INCLUSIVE,
OP_EXCLUSIVE,
OP_LESS,
OP_GREAT,
OP_EQUAL,
OP_LE,
OP_GE,
OP_NOT_EQUAL,
} OP_TYPE;
typedef struct expr
{
EXPR_TYPE type;
OP_TYPE op;
int value;
int defined;
int specified;
struct expr *left;
struct expr *right;
struct expr *tri;
} EXPR;
typedef struct _symbol
{
int defined;
char *name;
char *defined_filename;
int defined_lineno;
EXPR *expr;
struct _symbol *next;
} SYMBOL;
SYMBOL *symbol_define_list = NULL;
SYMBOL *symbol_not_define_list = NULL;
typedef enum
{
STMT_STRING,
STMT_IFDEF,
} StatementType;
typedef struct statement
{
StatementType type;
struct ifdef_statement *ifdef;
char *string;
char *fname;
int lineno;
struct statement *next;
} Statement;
Statement *g_first_stmt = 0;
typedef struct ifdef_statement
{
int specified; // specified in xxx.conf or not
int condition;
IFDEF_TYPE type;
char *ifdef_string;
char *else_string;
char *endif_string;
Statement *true_stmt;
Statement *false_stmt;
char *fname;
int lineno;
} IFDEFstatement;
EXPR *symbol_get_expr(char *name);
EXPR *create_defined_expr(char *name);
void clean_ifdef(IFDEFstatement *ifdef);
void clean(Statement *stmt);
void change_file();
EXPR *create_scalar_expr(int value);
EXPR *create_unary_expr(OP_TYPE op, EXPR *_expr);
EXPR *create_binary_expr(EXPR *expr1, OP_TYPE op, EXPR *expr2);
EXPR *create_trinary_expr(EXPR *expr1, EXPR *expr2, EXPR *expr3);
int evaluate_func(OP_TYPE op, EXPR *expr);
int evaluate_unary(OP_TYPE op, EXPR *expr);
int evaluate_binary(EXPR *left, OP_TYPE op, EXPR *right);
int evaluate_trinary(EXPR *expr1, EXPR *expr2, EXPR *expr3);
int expr_evaluate(EXPR *expr);
Statement *create_statement(char *string, IFDEFstatement *ifdef);
IFDEFstatement *create_ifdef_statement(IFDEF_TYPE type, EXPR *expr, Statement *s1, Statement *s2, int has_else);
Statement *add_statement_list(Statement *list, Statement *s);
void dump_ifdef_all(FILE *fp, IFDEFstatement *ifdef);
void dump(FILE *fp, Statement *s);
void output_file(FILE *fout);
extern char *pop_ifdef_string();
extern char *pop_else_string();
extern char *pop_endif_string();
extern int ifdef_remove;
extern int evaluate_num;
%}
%union
{
char *string;
int num;
double real;
void *ptr;
}
/*
%type <ptr> defined_expression defined_unit
%type <ptr> ifndef_identifier ifdef_identifier
%type <string> macro_name
*/
%type <ptr> expression precompile precompile_list ifdef_statement
%type <ptr> primary_expression
%type <ptr> postfix_expression
%type <ptr> unary_expression
%type <ptr> cast_expression
%type <ptr> multiplicative_expression
%type <ptr> additive_expression
%type <ptr> shift_expression
%type <ptr> relational_expression
%type <ptr> equality_expression
%type <ptr> and_expression
%type <ptr> exclusive_or_expression
%type <ptr> inclusive_or_expression
%type <ptr> logical_and_expression
%type <ptr> logical_or_expression
%type <ptr> conditional_expression
/* %type <ptr> assignment_expression
%type <ptr> constant_expression */
%token <string> IDENTIFIER STRING_LITERAL
/* %token <string> ID_WITH_ARG FILENAME */
%token <string> STRING
%token <num> CONSTANT
%token NL 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 ELLIPSIS
/*
%token TYPEDEF EXTERN STATIC AUTO REGISTER
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
%token STRUCT UNION ENUM
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
*/
%token IFDEF IFNDEF ENDIF DEFINE DEFINED UNDEFINE IF2 ELSE2 INCLUDE OTHER_WORD MACRO_CONCAT
%start start_point
%left OR_OP AND_OP
%%
primary_expression
: IDENTIFIER
{ $$ = symbol_get_expr($1); }
| CONSTANT
{ $$ = create_scalar_expr($1); }
| DEFINED '(' IDENTIFIER ')'
{ $$ = create_defined_expr($3); }
| STRING_LITERAL
{ $$ = 0; }
| '(' ')'
{ $$ = 0; }
| '(' expression ')'
{ $$ = $2; }
;
postfix_expression
: primary_expression
{ $$ = $1; }
| postfix_expression '(' argument_expression_list ')'
{ $$ = $1; }
/*
| postfix_expression '[' expression ']'
{ $$ = 0; }
| postfix_expression '(' ')'
{ $$ = 0; }
| postfix_expression '.' IDENTIFIER
{ $$ = 0; }
| postfix_expression PTR_OP IDENTIFIER
{ $$ = 0; }
| postfix_expression INC_OP
{ $$ = 0; }
| postfix_expression DEC_OP
{ $$ = 0; }
*/
;
argument_expression_list
: conditional_expression
| argument_expression_list ',' conditional_expression
/*
: argument_expression_list ',' assignment_expression
| assignment_expression
*/
;
unary_expression
: postfix_expression
{ $$ = $1; }
| INC_OP unary_expression
{ $$ = 0; }
| DEC_OP unary_expression
{ $$ = 0; }
| '&' cast_expression
{ $$ = 0; }
| '*' cast_expression
{ $$ = 0; }
| '+' cast_expression
{ $$ = create_unary_expr(OP_PLUS, $2); }
| '-' cast_expression
{ $$ = create_unary_expr(OP_MINUS, $2); }
| '~' cast_expression
{ $$ = create_unary_expr(OP_BIT_NOT, $2); }
| '!' cast_expression
{ $$ = create_unary_expr(OP_NOT, $2); }
| SIZEOF unary_expression
{ $$ = 0; }
/*
| SIZEOF '(' type_name ')'
{ $$ = 0; }
*/
;
cast_expression
: unary_expression
{ $$ = $1; }
/*
| '(' type_name ')' cast_expression
{ $$ = 0; }
*/
;
multiplicative_expression
: cast_expression
{ $$ = $1; }
| multiplicative_expression '*' cast_expression
{ $$ = create_binary_expr($1, OP_MUL, $3); }
| multiplicative_expression '/' cast_expression
{ $$ = create_binary_expr($1, OP_DIV, $3); }
| multiplicative_expression '%' cast_expression
{ $$ = create_binary_expr($1, OP_MOD, $3); }
;
additive_expression
: multiplicative_expression
{ $$ = $1; }
| additive_expression '+' multiplicative_expression
{ $$ = create_binary_expr($1, OP_PLUS, $3); }
| additive_expression '-' multiplicative_expression
{ $$ = create_binary_expr($1, OP_MINUS, $3); }
;
shift_expression
: additive_expression
{ $$ = $1; }
| shift_expression LEFT_OP additive_expression
{ $$ = create_binary_expr($1, OP_LEFT_SHIFT, $3); }
| shift_expression RIGHT_OP additive_expression
{ $$ = create_binary_expr($1, OP_RIGHT_SHIFT, $3); }
;
relational_expression
: shift_expression
{ $$ = $1; }
| relational_expression '<' shift_expression
{ $$ = create_binary_expr($1, OP_LESS, $3); }
| relational_expression '>' shift_expression
{ $$ = create_binary_expr($1, OP_GREAT, $3); }
| relational_expression LE_OP shift_expression
{ $$ = create_binary_expr($1, OP_LE, $3); }
| relational_expression GE_OP shift_expression
{ $$ = create_binary_expr($1, OP_GE, $3); }
;
equality_expression
: relational_expression
{ $$ = $1; }
| equality_expression EQ_OP relational_expression
{ $$ = create_binary_expr($1, OP_EQUAL, $3); }
| equality_expression NE_OP relational_expression
{ $$ = create_binary_expr($1, OP_NOT_EQUAL, $3); }
;
and_expression
: equality_expression
{ $$ = $1; }
| and_expression '&' equality_expression
{ $$ = create_binary_expr($1, OP_BIT_AND, $3); }
;
exclusive_or_expression
: and_expression
{ $$ = $1; }
| exclusive_or_expression '^' and_expression
{ $$ = create_binary_expr($1, OP_EXCLUSIVE, $3); }
;
inclusive_or_expression
: exclusive_or_expression
{ $$ = $1; }
| inclusive_or_expression '|' exclusive_or_expression
{ $$ = create_binary_expr($1, OP_INCLUSIVE, $3); }
;
logical_and_expression
: inclusive_or_expression
{ $$ = $1; }
| logical_and_expression AND_OP inclusive_or_expression
{ $$ = create_binary_expr($1, OP_AND, $3); }
;
logical_or_expression
: logical_and_expression
{ $$ = $1; }
| logical_or_expression OR_OP logical_and_expression
{ $$ = create_binary_expr($1, OP_OR, $3); }
;
conditional_expression
: logical_or_expression
{ $$ = $1; }
| logical_or_expression '?' expression ':' conditional_expression
{ $$ = create_trinary_expr($1, $3, $5); }
;
/*
assignment_expression
: conditional_expression
{ $$ = $1; }
| unary_expression assignment_operator assignment_expression
{ $$ = 0; }
;
assignment_operator
: '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;
*/
expression
: conditional_expression
{ $$ = $1; }
/*
: assignment_expression
{ $$ = $1; }
| expression ',' assignment_expression
{ $$ = 0; }
*/
;
/*
constant_expression
: conditional_expression
{ $$ = $1; }
;
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 ',' init_declarator
;
init_declarator
: declarator
| 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
;
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
;
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
: pointer direct_declarator
| direct_declarator
;
direct_declarator
: IDENTIFIER
| '(' 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_type_list
: parameter_list
| parameter_list ',' ELLIPSIS
;
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
| specifier_qualifier_list abstract_declarator
;
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
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
labeled_statement
: IDENTIFIER ':' statement
| CASE constant_expression ':' statement
| DEFAULT ':' statement
;
compound_statement
: '{' '}'
| '{' statement_list '}'
| '{' declaration_list '}'
| '{' declaration_list statement_list '}'
;
declaration_list
: declaration
| declaration_list declaration
;
statement_list
: statement
| statement_list statement
;
expression_statement
: ';'
| expression ';'
;
selection_statement
: IF '(' expression ')' statement
| IF '(' expression ')' statement ELSE statement
| SWITCH '(' expression ')' statement
;
iteration_statement
: WHILE '(' expression ')' statement
| DO statement WHILE '(' expression ')'
| DO statement WHILE '(' expression ')' ';'
| FOR '(' expression_statement expression_statement ')' statement
| FOR '(' expression_statement expression_statement expression ')' statement
;
jump_statement
: GOTO IDENTIFIER ';'
| CONTINUE ';'
| BREAK ';'
| RETURN ';'
| RETURN expression ';'
| RETURN expression
;
translation_unit
: external_declaration
| translation_unit external_declaration
;
*/
precompile
: ifdef_statement
{ $$ = create_statement(0, $1); }
| STRING
{ $$ = create_statement($1, 0); }
/*
: include_statement
| define_statement
*/
;
/*
%type <string> string_list
string_list
: STRING
{ $$ = $1; }
| STRING string_list
{ $$ = merge_string($1, $2); }
;
*/
start_point
:
| precompile_list
{ g_first_stmt = $1; }
;
precompile_list
: precompile
{ $$ = add_statement_list(0, $1); }
| precompile_list precompile
{ $$ = add_statement_list($1, $2); }
;
/*
include_statement
: INCLUDE STRING_LITERAL
{ if (!process_include_file($2)) yyerror($2); }
| INCLUDE '<' FILENAME '>'
{ if (!process_include_file($3)) yyerror($3); }
;
define_statement
: DEFINE macro_name
{ create_symbol($2); }
| DEFINE macro_name declaration_specifiers
{ create_symbol($2); }
| UNDEFINE IDENTIFIER
{ remove_symbol($2); }
| DEFINE macro_name expression
{ assign_symbol($2, $3); }
| DEFINE macro_name statement_list
{ create_symbol($2); }
| DEFINE macro_name declaration
{ create_symbol($2); }
;
macro_name
: IDENTIFIER
{ printf("\nmacro name=%s...\n", $1); $$ = $1;}
| ID_WITH_ARG ')'
{ $$ = 0; }
| ID_WITH_ARG argument_expression_list ')'
{ $$ = 0; }
;
replace_token_list
: replace_token
| replace_token_list replace_token
;
replace_token
: macro_name
| CONSTANT
;
*/
ifdef_statement
: IF2 expression ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, 0, 0, 0); }
| IF2 expression precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, $3, 0, 0); }
| IF2 expression ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, 0, 0, 1); }
| IF2 expression precompile_list ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, $3, 0, 1); }
| IF2 expression ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, 0, $4, 1); }
| IF2 expression precompile_list ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, $3, $5, 1); }
| IFDEF expression ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, 0, 0, 0); }
| IFDEF expression precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, $3, 0, 0); }
| IFDEF expression ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, 0, 0, 1); }
| IFDEF expression precompile_list ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, $3, 0, 1); }
| IFDEF expression ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, 0, $4, 1); }
| IFDEF expression precompile_list ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, $3, $5, 1); }
| IFNDEF expression ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, 0, 0, 0); }
| IFNDEF expression precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, $3, 0, 0); }
| IFNDEF expression ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, 0, 0, 1); }
| IFNDEF expression precompile_list ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, $3, 0, 1); }
| IFNDEF expression ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, 0, $4, 1); }
| IFNDEF expression precompile_list ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, $3, $5, 1); }
;
/*
ifdef_statement
: IF2 defined_expression ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, 0, 0, 0); }
| IF2 defined_expression precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, $3, 0, 0); }
| IF2 defined_expression ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, 0, 0, 1); }
| IF2 defined_expression precompile_list ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, $3, 0, 1); }
| IF2 defined_expression ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, 0, $4, 1); }
| IF2 defined_expression precompile_list ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IF, $2, $3, $5, 1); }
| IFDEF ifdef_identifier ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, 0, 0, 0); }
| IFDEF ifdef_identifier precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, $3, 0, 0); }
| IFDEF ifdef_identifier ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, 0, 0, 1); }
| IFDEF ifdef_identifier precompile_list ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, $3, 0, 1); }
| IFDEF ifdef_identifier ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, 0, $4, 1); }
| IFDEF ifdef_identifier precompile_list ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFDEF, $2, $3, $5, 1); }
| IFNDEF ifndef_identifier ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, 0, 0, 0); }
| IFNDEF ifndef_identifier precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, $3, 0, 0); }
| IFNDEF ifndef_identifier ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, 0, 0, 1); }
| IFNDEF ifndef_identifier precompile_list ELSE2 ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, $3, 0, 1); }
| IFNDEF ifndef_identifier ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, 0, $4, 1); }
| IFNDEF ifndef_identifier precompile_list ELSE2 precompile_list ENDIF
{ $$ = create_ifdef_statement(IFDEF_IFNDEF, $2, $3, $5, 1); }
;
ifdef_identifier
: IDENTIFIER
{ $$ = symbol_evaluate($1); }
;
ifndef_identifier
: IDENTIFIER
{ $$ = symbol_evaluate($1); }
;
defined_expression
: defined_unit
{ $$ = $1; }
| '(' defined_expression ')'
{ $$ = $2; }
| defined_unit AND_OP defined_expression
{ $$ = ($1 && $3) ? 1 : 0; }
| defined_unit OR_OP defined_expression
{ $$ = ($1 || $3) ? 1 : 0; }
;
defined_unit
: DEFINED '(' IDENTIFIER ')'
{ $$ = symbol_defined($3); }
| '!' DEFINED '(' IDENTIFIER ')'
{ $$ = symbol_not_defined($4); }
| expression
{ $$ = 1; }
;
*/
/*
external_declaration
: function_definition
| declaration
: precompile_list
;
code_body
: replace_token_list
;
function_definition
: declaration_specifiers declarator declaration_list compound_statement
| declaration_specifiers declarator compound_statement
| declarator declaration_list compound_statement
| declarator compound_statement
;
*/
%%
#include <stdio.h>
extern char yytext[];
extern FILE *yyin;
extern int column;
extern int lineno;
extern int process_include_file(char *fname);
extern char *current_file_name();
yyerror(s)
char *s;
{
fflush(stderr);
fprintf(stderr, "\n%*s\n%*s\n", column, "^", column, s);
if (!current_file_name())
return;
fprintf(stderr, "==>%s: at line [%d]\n",
current_file_name(), lineno);
}
SYMBOL *symbol_lookup(char *name)
{
SYMBOL *symbol = 0;
//printf("===> symbol_lookup, name=%s, at L(%d)\n", name, lineno);
for (symbol = symbol_define_list; symbol; symbol = symbol->next)
{
if (!strcmp(name, symbol->name))
{
//printf("find symbol:%s, value=%p\n", symbol->name, symbol->expr);
return symbol;
}
}
for (symbol = symbol_not_define_list; symbol; symbol = symbol->next)
{
if (!strcmp(name, symbol->name))
{
//printf("find symbol:%s, value=%p\n", symbol->name, symbol->expr);
return symbol;
}
}
//printf("Symbol(%s) not found\n", name);
return 0;
}
void remove_symbol(char *name)
{
SYMBOL *symbol = NULL, *prev = NULL;
printf("===> remove_lookup\n");
for (symbol = symbol_define_list; symbol; symbol = symbol->next)
{
if (!strcmp(name, symbol->name))
{
if (prev)
prev->next = symbol->next;
else
symbol_define_list = symbol->next;
symbol->next = NULL;
free(symbol->name);
free(symbol);
break;
}
prev = symbol;
}
printf("ERROR! can't undef symbol:%s\n", name);
printf("<=== remove_lookup\n");
}
SYMBOL *create_symbol(char *name, int defined)
{
SYMBOL *symbol;
if (!name) return 0;
symbol = symbol_lookup(name);
if (symbol)
{
printf("ERROR! symbol (%s) redefined at L%d, original at L%d\n",
name, lineno, symbol->defined_lineno);
return NULL;
}
symbol = malloc(sizeof(SYMBOL));
symbol->name = strdup(name);
symbol->defined_lineno = lineno;
symbol->defined_filename = current_file_name();
symbol->expr = 0;
symbol->defined = defined;
if (defined)
{
symbol->next = symbol_define_list;
symbol_define_list = symbol;
}
else
{
symbol->next = symbol_not_define_list;
symbol_not_define_list = symbol;
}
return symbol;
}
void assign_symbol(char *name, EXPR *expr)
{
SYMBOL *symbol = create_symbol(name, 1);
if (!symbol)
{
printf("ERROR! assign null symbol(%s).\n", name);
return;
}
symbol->expr = expr;
}
EXPR default_specified_expr = {
.specified = 1,
.defined = 0,
.type = EXPR_SCALAR,
.op = OP_EQUAL,
.value = 1,
.left = 0,
.right = 0,
.tri = 0,
};
EXPR default_not_specified_expr = {
.specified = 0,
.defined = 1,
.type = EXPR_SCALAR,
.op = OP_EQUAL,
.value = 1,
.left = 0,
.right = 0,
.tri = 0,
};
EXPR *symbol_get_expr(char *name)
{
SYMBOL *symbol = symbol_lookup(name);
EXPR *expr = 0;
//printf("===> symbol_get_expr:%s\n", name);
if (symbol)
{
if (!symbol->expr)
expr = &default_specified_expr;
else
expr = symbol->expr;
expr->defined = symbol->defined;
symbol->expr = expr;
}
else
{
expr = &default_not_specified_expr;
}
return expr;
}
/*
int symbol_evaluate(char *name)
{
SYMBOL *symbol;
symbol = symbol_lookup(name);
if (!symbol)
{
printf("ERROR! symbol %s not defined at L%d.\n", name, lineno);
return 0;
}
if (!symbol->expr)
return 0;
return expr_evaluate(symbol->expr);
}
*/
EXPR *create_defined_expr(char *name)
{
EXPR *expr = malloc(sizeof(EXPR));
memset(expr, 0, sizeof(EXPR));
//printf("create defined expr: %s\n", name);
expr->type = EXPR_FUNC;
expr->op = OP_DEFINED;
expr->left = symbol_get_expr(name);
expr->specified = expr->left->specified;
expr->defined = expr->left->defined;
expr->value = 0;
return expr;
}
EXPR *create_scalar_expr(int value)
{
EXPR *expr = malloc(sizeof(EXPR));
memset(expr, 0, sizeof(EXPR));
expr->type = EXPR_SCALAR;
expr->value = value;
expr->defined = 1;
if (evaluate_num)
expr->specified = 1;
else
expr->specified = 0;
return expr;
}
EXPR *create_unary_expr(OP_TYPE op, EXPR *_expr)
{
EXPR *expr = (EXPR *)malloc(sizeof(EXPR));
memset(expr, 0, sizeof(EXPR));
expr->type = EXPR_UNARY;
expr->op = op;
expr->left = _expr;
expr->specified = expr->left->specified;
expr->defined = expr->left->defined;
return expr;
}
EXPR *create_binary_expr(EXPR *expr1, OP_TYPE op, EXPR *expr2)
{
EXPR *expr = 0;
if (!expr1 && !expr2)
{
printf("ERROR, invalid binary expr, at %s, L(%d)\n",
current_file_name(), lineno);
return 0;
}
expr = malloc(sizeof(EXPR));
memset(expr, 0, sizeof(EXPR));
expr->type = EXPR_BINARY;
expr->op = op;
expr->left = expr1;
expr->right= expr2;
if (!expr1)
{
expr->defined = expr2->defined;
expr->specified = expr2->specified;
}
else if (!expr2)
{
expr->defined = expr1->defined;
expr->specified = expr1->specified;
}
else
{
expr->defined = (expr1->defined) && (expr2->defined);
expr->specified = (expr1->specified) && (expr2->specified);
}
return expr;
}
EXPR *create_trinary_expr(EXPR *expr1, EXPR *expr2, EXPR *expr3)
{
EXPR *expr = 0;
if (!expr1 || (!expr2 && !expr3))
{
printf("ERROR, invalid tri expr, at %s, L(%d)\n",
current_file_name(), lineno);
}
expr = malloc(sizeof(EXPR));
memset(expr, 0, sizeof(EXPR));
expr->type = EXPR_TRINARY;
expr->left = expr1;
expr->right= expr2;
expr->tri = expr3;
if (!expr3)
{
expr->defined = expr2->defined;
expr->specified = expr2->specified;
}
else if (!expr2)
{
expr->defined = expr3->defined;
expr->specified = expr3->specified;
}
else
{
expr->defined = (expr2->defined) && (expr3->defined);
expr->specified = (expr2->specified) && (expr3->specified);
}
return expr;
}
int evaluate_func(OP_TYPE op, EXPR *expr)
{
int value;
if (!expr)
{
printf("Invalid function evaluate (op=%d) at L%d\n", op, lineno);
return 0;
}
value = expr_evaluate(expr);
switch(op)
{
case OP_DEFINED:
return expr->defined;
default:
printf("ERROR! unknown function op:%d, at L%d\n", (int)op, lineno);
}
return 0;
}
int evaluate_unary(OP_TYPE op, EXPR *expr)
{
int value;
if (!expr)
{
printf("Invalid unary evaluate (op=%d) at L%d\n", op, lineno);
return 0;
}
value = expr_evaluate(expr);
switch(op)
{
case OP_PLUS:
return value;
case OP_MINUS:
return -value;
case OP_NOT:
return !value;;
case OP_BIT_NOT:
return ~value;
default:
printf("ERROR! unknown unary op:%d, at L%d\n", (int)op, lineno);
}
}
int evaluate_binary(EXPR *left, OP_TYPE op, EXPR *right)
{
int value, lvalue, rvalue;
if (!left || !right)
{
printf("Invalid binary evaluate (op=%d) at L%d\n", op, lineno);
return 0;
}
switch(op)
{
case OP_PLUS:
return expr_evaluate(left) + expr_evaluate(right);
case OP_MINUS:
return expr_evaluate(left) - expr_evaluate(right);
case OP_MUL:
return expr_evaluate(left) * expr_evaluate(right);
case OP_DIV:
value = expr_evaluate(right);
if (!value)
{
printf("ERROR! divided by zero at L%d\n", lineno);
return 0;
}
return expr_evaluate(left) / value;
case OP_LEFT_SHIFT:
return expr_evaluate(left) << expr_evaluate(right);
case OP_RIGHT_SHIFT:
return expr_evaluate(left) >> expr_evaluate(right);
case OP_MOD:
return expr_evaluate(left) % expr_evaluate(right);
case OP_AND:
return expr_evaluate(left) && expr_evaluate(right);
case OP_OR:
return expr_evaluate(left) || expr_evaluate(right);
case OP_BIT_AND:
return expr_evaluate(left) & expr_evaluate(right);
case OP_BIT_OR:
case OP_INCLUSIVE:
return expr_evaluate(left) | expr_evaluate(right);
case OP_EXCLUSIVE:
return expr_evaluate(left) ^ expr_evaluate(right);
case OP_LESS:
return expr_evaluate(left) < expr_evaluate(right) ? 1 : 0;
case OP_GREAT:
/*
lvalue = expr_evaluate(left);
rvalue = expr_evaluate(right);
printf("OP_GREAT left=%d, right=%d\n", lvalue, rvalue);
*/
return expr_evaluate(left) > expr_evaluate(right) ? 1 : 0;
case OP_EQUAL:
return expr_evaluate(left) == expr_evaluate(right) ? 1 : 0;
case OP_LE:
return expr_evaluate(left) <= expr_evaluate(right) ? 1 : 0;
case OP_GE:
return expr_evaluate(left) >= expr_evaluate(right) ? 1 : 0;
case OP_NOT_EQUAL:
return expr_evaluate(left) != expr_evaluate(right) ? 1 : 0;
default:
printf("ERROR, unknown binary op:%d, at L%d\n", op, lineno);
}
}
int evaluate_trinary(EXPR *expr1, EXPR *expr2, EXPR *expr3)
{
int value;
if (!expr1 || !expr2 || !expr3)
{
printf("Invalid trinary evaluate at L%d\n", lineno);
return 0;
}
value = expr_evaluate(expr1);
if (value != 0)
return expr_evaluate(expr2);
return expr_evaluate(expr3);
}
int expr_evaluate(EXPR *expr)
{
if (!expr)
{
printf("Invalid expr evaluate at L%d\n", lineno);
return 0;
}
switch(expr->type)
{
case EXPR_SCALAR:
return expr->value;
case EXPR_FUNC:
return evaluate_func(expr->op, expr->left);
case EXPR_UNARY:
return evaluate_unary(expr->op, expr->left);
case EXPR_BINARY:
return evaluate_binary(expr->left, expr->op, expr->right);
case EXPR_TRINARY:
return evaluate_trinary(expr->left, expr->right, expr->tri);
default:
printf("ERROR, unknown expr type: %d, at L%d\n",expr->type, lineno);
return 0;
}
return 0;
}
IFDEFstatement *create_ifdef_statement(IFDEF_TYPE type, EXPR *expr, Statement *s1, Statement *s2, int has_else)
{
IFDEFstatement *ifdef = malloc(sizeof(IFDEFstatement));
ifdef->type = type;
ifdef->specified = expr->specified;
switch(type)
{
case IFDEF_IFDEF:
ifdef->condition = expr->defined;
break;
case IFDEF_IFNDEF:
ifdef->condition = !expr->defined;
break;
case IFDEF_IF:
ifdef->condition = expr_evaluate(expr);
break;
}
ifdef->true_stmt = s1;
ifdef->false_stmt = s2;
ifdef->ifdef_string = pop_ifdef_string();
if (has_else)
ifdef->else_string = pop_else_string();
else
ifdef->else_string = 0;
ifdef->endif_string = pop_endif_string();
ifdef->fname = current_file_name();
ifdef->lineno = lineno;
//printf("create ifdef: lineno=%d, endif=%s\n", lineno, ifdef->endif_string);
return ifdef;
}
Statement *create_statement(char *string, IFDEFstatement *ifdef)
{
Statement *stmt = malloc(sizeof(Statement));
if (string)
{
stmt->type = STMT_STRING;
stmt->string = string;
stmt->ifdef = 0;
//printf("create stmt L(%d): %s\n", lineno, stmt->string);
}
else
{
stmt->type = STMT_IFDEF;
stmt->string = 0;
stmt->ifdef = ifdef;
//printf("create stmt L(%d): type=ifdef\n", lineno);
}
stmt->next = 0;
stmt->fname = current_file_name();
stmt->lineno = lineno;
return stmt;
}
#if 0
char *merge_string(char *s1, char *s2)
{
char *buf;
if (!s1) return s2;
if (!s2) return s1;
buf = malloc(strlen(s1) + strlen(s2) + 1);
strcpy(buf, s1);
strcpy((char *)(buf+strlen(s1)), s2);
printf("\nmerged [%s]+[%s]=%s\n", s1, s2, buf);
free(s1);
free(s2);
return buf;
}
#endif
Statement *add_statement_list(Statement *list, Statement *s)
{
Statement *tail = list, *pre = list;
if (!list)
{
#if 0
if (!g_first_stmt)
{
g_first_stmt = s;
printf("first stmt=%s\n", s->string);
}
else
printf("ERROR! no list, but has g_first_stmt\n");
#endif
return s;
}
#if 0
if (list->string)
{
printf("[%s] add ", list->string);
if (s->string)
printf("[%s]\n", s->string);
else
printf("non string stmt\n");
}
#endif
// find the tail of stmts list
while(tail)
{
pre = tail;
tail = tail->next;
}
pre->next = s;
return list;
}
void dump_ifdef_all(FILE *fp, IFDEFstatement *ifdef)
{
if (!ifdef->ifdef_string)
printf("ERROR, no ifdef_string at %s, L(%d)\n", ifdef->fname, ifdef->lineno);
fprintf(fp, "%s", ifdef->ifdef_string);
dump(fp, ifdef->true_stmt);
if (ifdef->else_string)
{
fprintf(fp, "%s", ifdef->else_string);
dump(fp, ifdef->false_stmt);
}
if (!ifdef->endif_string)
printf("ERROR, no endif_string at %s, L(%d)\n", ifdef->fname, ifdef->lineno);
fprintf(fp, "%s", ifdef->endif_string);
}
void dump(FILE *fp, Statement *s)
{
IFDEFstatement *ifdef;
if (!fp) return;
while(s)
{
switch(s->type)
{
case STMT_STRING:
if (!s->string)
printf("ERROR, no statement string at %s, L(%d)\n", s->fname, s->lineno);
fprintf(fp, "%s", s->string);
break;
case STMT_IFDEF:
ifdef = s->ifdef;
if (!ifdef->specified) // not specified in xxx.conf
{
// keep all dumped
dump_ifdef_all(fp, ifdef);
}
else
{
// specified => use condition to judge dump or not
if (ifdef->condition)
{
if (!ifdef->ifdef_string)
printf("ERROR, no ifdef_string at %s, L(%d)\n", ifdef->fname, ifdef->lineno);
if (!ifdef_remove)
fprintf(fp, "%s", ifdef->ifdef_string);
dump(fp, ifdef->true_stmt);
if (!ifdef->endif_string)
printf("ERROR, no endif_string at %s, L(%d)\n", ifdef->fname, ifdef->lineno);
if (!ifdef_remove)
fprintf(fp, "%s", ifdef->endif_string);
}
else
{
//if (ifdef->else_string)
{
if (!ifdef->ifdef_string)
printf("ERROR, no not ifdef_string at %s, L(%d)\n", ifdef->fname, ifdef->lineno);
if (!ifdef_remove)
fprintf(fp, "%s", ifdef->ifdef_string);
if (ifdef->else_string && !ifdef_remove)
{
fprintf(fp, "%s", ifdef->else_string);
}
dump(fp, ifdef->false_stmt);
if (!ifdef->endif_string)
printf("ERROR, no not endif_string at %s, L(%d)\n", ifdef->fname, ifdef->lineno);
if (!ifdef_remove)
fprintf(fp, "%s", ifdef->endif_string);
}
} // of if(condition) else...
} // of speficied
break;
}
s = s->next;
}
}
void clean_ifdef(IFDEFstatement *ifdef)
{
if (!ifdef)
return;
//printf("clean ifdef L(%d)...\n", ifdef->lineno);
clean(ifdef->true_stmt);
clean(ifdef->false_stmt);
if (ifdef->ifdef_string)
free(ifdef->ifdef_string);
if (ifdef->else_string)
free(ifdef->else_string);
if (ifdef->endif_string)
free(ifdef->endif_string);
}
void clean(Statement *stmt)
{
Statement *next;
if (!stmt)
return;
clean_ifdef(stmt->ifdef);
//printf("clean string(%p): L(%d)...\n", stmt->string, stmt->lineno);
if (stmt->string)
{
//printf("free(%d) %s...\n", stmt->lineno, stmt->string);
free(stmt->string);
}
next = stmt->next;
//printf("clean stmt(%p) done...\n", stmt);
free(stmt);
clean(next);
}
void output_file(FILE *fout)
{
//printf("\n======== DUMP ==========\n");
dump(fout, g_first_stmt);
clean(g_first_stmt);
//printf("\n======= CLEAN done ====\n");
g_first_stmt = 0;
}
main()
{
#if 0
if (!process_file("STDIN"))
{
yyerror("STDIN"); // 1st include file
return;
}
#endif
do {
yyparse();
change_file();
} while(yyin);
//} while(!feof(yyin));
}