📄 zprof.y
字号:
/*File: zprof.yPurpose: ANSI-C parser. Outputs source with profiling counters added.Last Update Time-stamp: <97/07/31 12:11:22 zdu>Copyright (C) 1995, 1997 Zerksis D. UmrigarSee the file LICENSE for copying and distribution conditions.THERE IS ABSOLUTELY NO WARRANTY FOR THIS PROGRAM.*//* Including as test file as it is more of a "real" test ... checks * inherited attributes, graph coloring and stuff. */%{#include "options.h"#include "out.h"#include "scan.h"#include "area.h"#include "error.h"#include "hashtab.h"#include "ids.h"#include "parseopt.h"#define YY_LEX scanstatic void dclTypedef PROTO((Index id, BooleanX isTypedef));static Boolean isTypedef PROTO((VOID_ARGS));static VOID beginScope PROTO((VOID_ARGS));static VOID endScope PROTO((VOID_ARGS));static Int helpOptFn PROTO((Int id, VOIDP checkP, VOIDP valP, ConstString argP));static Int typedefOptFn PROTO((Int id, VOIDP checkP, VOIDP valP, ConstString argP));static Int versionOptFn PROTO((Int id, VOIDP checkP, VOIDP valP, ConstString argP));static struct { Boolean seenType;} globs;#define G globs#define OUT(t) putOut(&t)enum { TYPEDEF_DCL, /* declaration of a typedef */ ID_DCL, /* declaration of other ID in typedef namespace */ OTHER_DCL, /* declaration of other ID in other namespace */};#if YY_ZYACC_DEBUGstatic YY_VOID tokSemFn PROTO((FILE *out, int tokNum, VOIDP p));#define YY_SEM_FN tokSemFn#endif /* if YY_ZYACC_DEBUG */%}%token <tok>(TokSem $t) AUTO_TOK = 'auto'%token <tok>(TokSem $t) BREAK_TOK = 'break'%token <tok>(TokSem $t) CASE_TOK = 'case'%token <tok>(TokSem $t) CHAR_TOK = 'char'%token <tok>(TokSem $t) CONST_TOK = 'const'%token <tok>(TokSem $t) CONTINUE_TOK = 'continue'%token <tok>(TokSem $t) DEFAULT_TOK = 'default'%token <tok>(TokSem $t) DO_TOK = 'do'%token <tok>(TokSem $t) DOUBLE_TOK = 'double'%token <tok>(TokSem $t) ELSE_TOK = 'else'%token <tok>(TokSem $t) ENUM_TOK = 'enum'%token <tok>(TokSem $t) EXTERN_TOK = 'extern'%token <tok>(TokSem $t) FLOAT_TOK = 'float'%token <tok>(TokSem $t) FOR_TOK = 'for'%token <tok>(TokSem $t) GOTO_TOK = 'goto'%token <tok>(TokSem $t) IF_TOK = 'if'%token <tok>(TokSem $t) INT_TOK = 'int'%token <tok>(TokSem $t) LONG_TOK = 'long'%token <tok>(TokSem $t) REGISTER_TOK = 'register'%token <tok>(TokSem $t) RETURN_TOK = 'return'%token <tok>(TokSem $t) SHORT_TOK = 'short'%token <tok>(TokSem $t) SIGNED_TOK = 'signed'%token <tok>(TokSem $t) SIZEOF_TOK = 'sizeof'%token <tok>(TokSem $t) STATIC_TOK = 'static'%token <tok>(TokSem $t) STRUCT_TOK = 'struct'%token <tok>(TokSem $t) SWITCH_TOK = 'switch'%token <tok>(TokSem $t) TYPEDEF_TOK = 'typedef'%token <tok>(TokSem $t) UNION_TOK = 'union'%token <tok>(TokSem $t) UNSIGNED_TOK = 'unsigned'%token <tok>(TokSem $t) VOID_TOK = 'void'%token <tok>(TokSem $t) VOLATILE_TOK = 'volatile'%token <tok>(TokSem $t) WHILE_TOK = 'while'%token <tok>(TokSem $t) ADD_ASSGN_TOK = '+='%token <tok>(TokSem $t) AND_ASSGN_TOK = '&='%token <tok>(TokSem $t) BOOL_AND_TOK = '&&'%token <tok>(TokSem $t) BOOL_OR_TOK = '||'%token <tok>(TokSem $t) DEC_TOK = '--' %token <tok>(TokSem $t) DEREF_TOK = '->'%token <tok>(TokSem $t) DIV_ASSGN_TOK = '/='%token <tok>(TokSem $t) DOT_DOT_TOK = '...'%token <tok>(TokSem $t) EQ_TOK = '==' %token <tok>(TokSem $t) GE_TOK = '>=' %token <tok>(TokSem $t) INC_TOK = '++'%token <tok>(TokSem $t) LE_TOK = '<=' %token <tok>(TokSem $t) LSH_ASSGN_TOK = '<<='%token <tok>(TokSem $t) LSH_TOK = '<<' %token <tok>(TokSem $t) MOD_ASSGN_TOK = '%='%token <tok>(TokSem $t) MULT_ASSGN_TOK = '*='%token <tok>(TokSem $t) NE_TOK = '!=' %token <tok>(TokSem $t) OR_ASSGN_TOK = '|='%token <tok>(TokSem $t) RSH_ASSGN_TOK = '>>='%token <tok>(TokSem $t) RSH_TOK = '>>' %token <tok>(TokSem $t) SUB_ASSGN_TOK = '-='%token <tok>(TokSem $t) XOR_ASSGN_TOK = '^='%token <tok>(TokSem $t) ';' '{' '}' '[' ']' '(' ')' ',' ':'%token <tok>(TokSem $t) '=' '*' '?' '|' '^' '&' '<' '>'%token <tok>(TokSem $t) '+' '-' '/' '%' '~' '!' '.'%token <tok>(TokSem $t) ID_TOK%token <tok>(TokSem $t) NUM_TOK%token <tok>(TokSem $t) STRING_TOK%start translation_unit%%/*NOTE: Most all-upper-case identifiers are actually nonterminals (tho' only1-level removed from terminals).*//* DECLARATIONS */translation_unit : external_declaration | translation_unit external_declaration ;external_declaration : function_definition | declaration | error ;function_definition : fnDeclarator compound_statement(FN_COUNTER, $counter) | fnDeclarator declaration_list compound_statement(FN_COUNTER, $counter) | declaration_specifiers($dclType) declarator($dclType) compound_statement(FN_COUNTER, $counter) | declaration_specifiers($dclType) declarator($dclType) declaration_list compound_statement(FN_COUNTER, $counter) ;fnDeclarator : declarator(ID_DCL) ;declaration : declaration_specifiers($dclType) SEMI | declaration_specifiers($dclType) init_declarator_list($dclType) SEMI ;declaration_list : declaration | declaration_list declaration ;declaration_specifiers(Index $dclType) : declaration_specifiers_x($dclType) { G.seenType= FALSE; } ;declaration_specifiers_x(Index $dclType) : storage_class_specifier($dclType) | storage_class_specifier($dclType1) declaration_specifiers_x($dclType2) { $dclType= ($dclType1 == TYPEDEF_DCL || $dclType2 == TYPEDEF_DCL) ? TYPEDEF_DCL : ID_DCL; } | type_specifier { $dclType= ID_DCL; } | type_specifier declaration_specifiers_x($dclType) | type_qualifier { $dclType= ID_DCL; } | type_qualifier declaration_specifiers_x($dclType) ;storage_class_specifier(Index $dclType) : TYPEDEF { $dclType= TYPEDEF_DCL; } | EXTERN { $dclType= ID_DCL; } | STATIC { $dclType= ID_DCL; } | AUTO { $dclType= ID_DCL; } | REGISTER { $dclType= ID_DCL; } ;type_specifier : CHAR { G.seenType= TRUE; } | SHORT { G.seenType= TRUE; } | INT { G.seenType= TRUE; } | LONG { G.seenType= TRUE; } | SIGNED { G.seenType= TRUE; } | UNSIGNED { G.seenType= TRUE; } | FLOAT { G.seenType= TRUE; } | DOUBLE { G.seenType= TRUE; } | VOID { G.seenType= TRUE; } | struct_or_union_specifier { G.seenType= TRUE; } | enum_specifier { G.seenType= TRUE; } | typedef_name { G.seenType= TRUE; } ;type_qualifier : CONST | VOLATILE ;struct_or_union_specifier : struct_or_union ID($id) LBRACE struct_declaration_list RBRACE | struct_or_union LBRACE struct_declaration_list RBRACE | struct_or_union ID($id) ;struct_or_union : STRUCT | UNION ;struct_declaration_list : struct_declaration | struct_declaration_list struct_declaration ;init_declarator_list(%in Index $dclType) : init_declarator($dclType) | init_declarator_list($dclType) COMMA init_declarator($dclType) ;init_declarator(%in Index $dclType) : declarator($dclType) | declarator($dclType) EQ initializer ;struct_declaration : specifier_qualifier_list struct_declarator_list SEMI ;specifier_qualifier_list : specifier_qualifier_list_x { G.seenType= FALSE; } ;specifier_qualifier_list_x : type_specifier | type_specifier specifier_qualifier_list_x | type_qualifier | type_qualifier specifier_qualifier_list_x ;struct_declarator_list : struct_declarator | struct_declarator_list COMMA struct_declarator ;struct_declarator : fieldDeclarator | COLON constant_expr | fieldDeclarator COLON constant_expr ;fieldDeclarator : declarator(OTHER_DCL) ;enum_specifier : ENUM LBRACE enumerator_list RBRACE | ENUM ID($id) LBRACE enumerator_list RBRACE | ENUM ID($id) ;enumerator_list : enumerator | enumerator_list COMMA enumerator ;enumerator : ID($id) | ID($id) EQ constant_expr ;declarator(%in Index $dclType) : direct_declarator($dclType) | pointer direct_declarator($dclType) ;direct_declarator(%in Index $dclType) : ID($id) { if ($dclType != OTHER_DCL) dclTypedef($id, $dclType == TYPEDEF_DCL); } | LPAREN declarator($dclType) RPAREN | direct_declarator($dclType) LBRACKET RBRACKET | direct_declarator($dclType) LBRACKET constant_expr RBRACKET | direct_declarator($dclType) LPAREN parameter_type_list RPAREN | direct_declarator($dclType) LPAREN RPAREN | direct_declarator($dclType) LPAREN identifier_list RPAREN ;pointer : STAR | STAR type_qualifier_list | STAR pointer | STAR type_qualifier_list pointer ;type_qualifier_list : type_qualifier | type_qualifier_list type_qualifier ;parameter_type_list : parameter_list | parameter_list COMMA DOT_DOT_DOT ;parameter_list : parameter_declaration | parameter_list COMMA parameter_declaration ;parameter_declaration : declaration_specifiers($dclType) declarator($dclType) | declaration_specifiers($dclType) | declaration_specifiers($dclType) abstract_declarator ;identifier_list : ID($id) | identifier_list COMMA ID($id) ;initializer : assignment_expr | LBRACE initializer_list RBRACE | LBRACE initializer_list COMMA RBRACE ;initializer_list : initializer | initializer_list COMMA initializer ;type_name : specifier_qualifier_list | specifier_qualifier_list abstract_declarator ;abstract_declarator : pointer | direct_abstract_declarator | pointer direct_abstract_declarator ;direct_abstract_declarator : LPAREN abstract_declarator RPAREN | LBRACKET RBRACKET | LBRACKET constant_expr RBRACKET | direct_abstract_declarator LBRACKET RBRACKET | direct_abstract_declarator LBRACKET constant_expr RBRACKET | LPAREN RPAREN | LPAREN parameter_type_list RPAREN | direct_abstract_declarator LPAREN RPAREN | direct_abstract_declarator LPAREN parameter_type_list RPAREN ;typedef_name : %test(!G.seenType && isTypedef()) ID($id) { #if TEST_TYPEDEF printf("*"); #endif } ;/* STATEMENTS */statement(%in CounterType $counter0, %out CounterType $counterZ) : counter_begin($counter0) labeled_statement($counterZ) counter_end($counter0) | counter_begin($counter0) expression_statement counter_end($counter0) { $counterZ= NO_COUNTER; } | compound_statement( $counter0 == STMT_COUNTER ? COMPOUND_COUNTER : $counter0, $counterZ) | counter_begin($counter0) selection_statement($counterX) counter_end($counter0) { $counterZ= STMT_COUNTER; } | counter_begin($counter0) iteration_statement($counterX) counter_end($counter0) { $counterZ= STMT_COUNTER; } | counter_begin($counter0) jump_statement counter_end($counter0) { $counterZ= NO_COUNTER; } ;labeled_statement(%out CounterType $counterZ) : ID($id) COLON statement(STMT_COUNTER, $counterZ) | CASE constant_expr COLON statement(STMT_COUNTER, $counterZ) | DEFAULT COLON statement(STMT_COUNTER, $counterZ) ;expression_statement : SEMI | expr SEMI ;compound_statement(%in CounterType $counter0, %out CounterType $counterZ) : lbrace counter_begin($counter0) rbrace { $counterZ= NO_COUNTER; } | lbrace statement_list($counter0, $counterZ) rbrace | lbrace declaration_list rbrace { $counterZ= NO_COUNTER; } | lbrace declaration_list statement_list($counter0, $counterZ) rbrace ;lbrace : LBRACE { beginScope(); } ;rbrace : RBRACE { endScope(); } ;statement_list(%in CounterType $counter0, %out CounterType $counterZ) : statement($counter0, $counterZ) | statement_list($counter0, $counterX) statement($counterX, $counterZ) ;selection_statement(%out CounterType $counterZ) : IF LPAREN expr RPAREN needs_counter_statement($counterZ) | IF LPAREN expr RPAREN needs_counter_statement($counterT) ELSE statement(STMT_COUNTER, $counterE) { $counterZ= ($counterT == NO_COUNTER) ? $counterE : $counterT; } | SWITCH LPAREN expr RPAREN statement(NO_COUNTER, $counterZ) ;needs_counter_statement(%out CounterType $counterZ) : statement(STMT_COUNTER, $counterZ) ;iteration_statement(%out CounterType $counterZ) : WHILE LPAREN expr RPAREN statement(STMT_COUNTER, $counterZ) | DO statement(STMT_COUNTER, $counterZ) WHILE LPAREN expr RPAREN SEMI | FOR LPAREN SEMI SEMI RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN SEMI SEMI expr RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN SEMI expr SEMI RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN SEMI expr SEMI expr RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN expr SEMI SEMI RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN expr SEMI SEMI expr RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN expr SEMI expr SEMI RPAREN statement(STMT_COUNTER, $counterZ) | FOR LPAREN expr SEMI expr SEMI expr RPAREN statement(STMT_COUNTER, $counterZ) ;jump_statement : GOTO ID($id) SEMI | CONTINUE SEMI | BREAK SEMI | RETURN SEMI | RETURN expr SEMI ;/* EXPRESSIONS */expr : assignment_expr | expr COMMA assignment_expr | error ;assignment_expr : conditional_expr | unary_expr assignment_operator assignment_expr ;assignment_operator : EQ | STAR_EQ | SLASH_EQ | PERCENT_EQ | PLUS_EQ | MINUS_EQ | LT_LT_EQ | GT_GT_EQ | AMPERSAND_EQ | CARAT_EQ | BAR_EQ ;conditional_expr : logical_or_expr | logical_or_expr QUESTION counter_begin(COND_COUNTER) logical_or_expr counter_end(COND_COUNTER) COLON counter_begin(COND_COUNTER) conditional_expr counter_end(COND_COUNTER) ;constant_expr : conditional_expr ;logical_or_expr : logical_and_expr | logical_or_expr BAR_BAR logical_and_expr ;logical_and_expr : inclusive_or_expr | logical_and_expr AMPERSAND_AMPERSAND inclusive_or_expr ;inclusive_or_expr : exclusive_or_expr | inclusive_or_expr BAR exclusive_or_expr ;exclusive_or_expr : and_expr | exclusive_or_expr CARAT and_expr ;and_expr : equality_expr | and_expr AMPERSAND equality_expr ;equality_expr : relational_expr | equality_expr EQ_EQ relational_expr | equality_expr BANG_EQ relational_expr ;relational_expr : shift_expr | relational_expr LT shift_expr | relational_expr GT shift_expr | relational_expr LT_EQ shift_expr | relational_expr GT_EQ shift_expr ;shift_expr : additive_expr | shift_expr LT_LT additive_expr | shift_expr GT_GT additive_expr ;additive_expr : multiplicative_expr | additive_expr PLUS multiplicative_expr | additive_expr MINUS multiplicative_expr ;multiplicative_expr : cast_expr | multiplicative_expr STAR cast_expr | multiplicative_expr SLASH cast_expr | multiplicative_expr PERCENT cast_expr ;cast_expr : unary_expr | LPAREN type_name RPAREN cast_expr ;unary_expr : postfix_expr | PLUS_PLUS unary_expr | MINUS_MINUS unary_expr | unary_operator cast_expr | SIZEOF unary_expr | SIZEOF LPAREN type_name RPAREN ;unary_operator : AMPERSAND | STAR | PLUS | MINUS | TILDE | BANG ;postfix_expr : primary_expr | postfix_expr LBRACKET expr RBRACKET | postfix_expr LPAREN RPAREN | postfix_expr LPAREN argument_expr_list RPAREN | postfix_expr DOT ID($id) | postfix_expr MINUS_GT ID($id) | postfix_expr PLUS_PLUS | postfix_expr MINUS_MINUS ;primary_expr : ID($id) | constant | STRING | LPAREN expr RPAREN ;argument_expr_list : assignment_expr | argument_expr_list COMMA assignment_expr ;constant : NUM ;/* TERMINALS */AMPERSAND : '&'($t) { OUT($t); } ;AMPERSAND_AMPERSAND : '&&'($t) { OUT($t); } ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -