📄 parser.y
字号:
%{/* ctrace - C program debugging tool * * C statement parser * */#ifndef lintstatic char *sccsid = "@(#)parser.y 4.1 (ULTRIX) 7/17/90";#endif lint/************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * * Modification History: * * */#include "global.h"#define min(X, Y) (((int) X < (int) Y) ? X : Y)#define max(X, Y) (((int) X > (int) Y) ? X : Y)#define max3(X, Y, Z) max(X, max(Y, Z))#define max4(W,X,Y,Z) max(W, max(X, max(Y, Z)))#define symbol_info(X, FIRST_SYM, LAST_SYM, TYPE) \ /* X.start = FIRST_SYM.start, */ /* default if $1 */ \ X.end = LAST_SYM.end, \ X.type = TYPE#define add_trace(VAR, FIRST_SYM, LAST_SYM, TYPE) \ add_fcn(VAR, FIRST_SYM.start, LAST_SYM.end, TYPE)#define expand_trace(VAR, FIRST_SYM, LAST_SYM) \ expand_fcn(VAR, FIRST_SYM.start, LAST_SYM.end)enum bool fcn_body = no; /* function body indicator */ static int len; /* temporary variable */static int fcn_line; /* function header line number */static char fcn_name[IDMAX + 1]; /* function name */static char fcn_text[SAVEMAX + 1]; /* function header text */static char nf_name[IDMAX + 1]; /* non-function name */static enum bool save_header = yes; /* start of function */static enum bool flow_break = no; /* return, goto, break, & continue */static enum bool executable = no; /* executable statements */%}%union { struct symbol_struct symbol;}/* operator precedence */%left <symbol> ','%right <symbol> '=' ASSIGNOP /* += =+ etc. */%right <symbol> '?' ':'%left <symbol> OROR%left <symbol> ANDAND%left <symbol> '|'%left <symbol> '^'%left <symbol> '&'%left <symbol> EQUOP /* == != */%left <symbol> RELOP /* < > <= >= */%left <symbol> SHIFTOP /* << >> */%left <symbol> '+' '-'%left <symbol> '*' DIVOP /* / % */%right <symbol> NOTCOMPL /* ! ~ */%right <symbol> SIZEOF INCOP /* ++ -- */%left <symbol> '[' '(' DOTARROW%token <symbol> '{' '}' ']' ')' ';'%token <symbol> CLASS CONSTANT IDENT FUNCTION PP_IF PP_ELSE PP_ENDIF TYPE/* the above tokens are used in scanner.l *//* these tokens are used only in lookup.c */%token <symbol> BREAK_CONT CASE DEFAULT DO ELSE ENUM FOR GOTO IF MACRO%token <symbol> RETURN STRUCT_UNION SWITCH TYPEDEF WHILE%token <symbol> STRRES STRCAT STRCMP STRCPY STRLEN STRNCAT STRNCMP%token <symbol> IOBUF JMP_BUF /* used only by lookup() */%type <symbol> name name_args opt_exp exp term strfcn int_strfcn arg cast ident strfcn_name%%/* declarations (copied from the portable compiler) */ext_def_list: ext_def_list external_def | /* empty */ ;external_def: data_def | errordata_def: TYPEDEF oattributes init_dcl_list dcl_semicolon { add_type(nf_name); } | oattributes dcl_semicolon | oattributes init_dcl_list dcl_semicolon | oattributes fdeclarator { /* prevent further function declarations from overwriting this header */ save_header = no; } function_body { save_header = yes; } ;function_body: arg_dcl_list fcn_stmt_body ;arg_dcl_list: arg_dcl_list declaration | /* empty */ ; ;dcl_stat_list : dcl_stat_list attributes dcl_semicolon | dcl_stat_list attributes init_dcl_list dcl_semicolon | /* empty */ ;declaration: attributes declarator_list dcl_semicolon | attributes dcl_semicolon | error dcl_semicolon ;oattributes: attributes | /* VOID */ ;attributes: CLASS type | type CLASS | CLASS | type ;type: TYPE | TYPE TYPE | TYPE TYPE TYPE | struct_dcl | enum_dcl ;enum_dcl: enum_head '{' moe_list optcomma '}' | ENUM ident ;enum_head: ENUM | ENUM ident ;moe_list: moe | moe_list ',' moe ;moe: ident | ident '=' con_e ; /* the optional semicolon was eliminated so the parser doesn't have to look for a '}' or another declaration after a ';', which prevents the scanner from finding a new type on the next declaration */struct_dcl: str_head '{' { /* output this part of the statement so the first struct element declaration looks like a new statement so the typedef scanning works */ if (!executable) { puttext($2.end); } } type_dcl_list '}' | STRUCT_UNION ident ;str_head: STRUCT_UNION | STRUCT_UNION ident ;type_dcl_list: type_declaration | type_dcl_list type_declaration ;type_declaration: type declarator_list dcl_semicolon | type dcl_semicolon ;declarator_list: declarator | declarator_list ',' declarator ;declarator: fdeclarator | nfdeclarator | nfdeclarator ':' con_e %prec ',' | ':' con_e %prec ',' | error ; /* int (a)(); is not a function --- sorry! */nfdeclarator: '*' nfdeclarator | nfdeclarator '(' ')' | nfdeclarator '[' ']' | nfdeclarator '[' con_e ']' | name { /* save the name because it may be a typedef name */ len = min($1.end - $1.start, IDMAX); strncpy(nf_name, yytext + $1.start, len); nf_name[len] = '\0'; } | '(' nfdeclarator ')' ;fdeclarator: '*' fdeclarator | fdeclarator '(' ')' | fdeclarator '[' ']' | fdeclarator '[' con_e ']' | '(' fdeclarator ')' | name_args { /* save the function header */ if (save_header) { fcn_line = yylineno; fcn_text[0] = '\n'; strncpy(fcn_text + 1, yytext + $1.start, SAVEMAX - 1); puttext($1.end); } } ;name_args: name_lp name_list ')' { $$.end = $3.end; } | name_lp ')' { $$.end = $2.end; } ;name_lp: name '(' { /* save the function name */ if (save_header) { len = min($1.end - $1.start, IDMAX); strncpy(fcn_name, yytext + $1.start, len); fcn_name[len] = '\0'; } } ;name : ident | strfcn_name ;name_list: ident | name_list ',' ident ; /* always preceeded by attributes */init_dcl_list: init_declarator %prec ',' | init_dcl_list ',' init_declarator ; /* always preceeded by attributes */xnfdeclarator: nfdeclarator | error ; /* always preceeded by attributes */init_declarator: nfdeclarator | fdeclarator | xnfdeclarator optasgn exp %prec ',' | xnfdeclarator optasgn '{' init_list optcomma '}' ;init_list: initializer %prec ',' | init_list ',' { puttext($2.end); } initializer ;initializer: exp %prec ',' | '{' init_list optcomma '}' ;optcomma : /* VOID */ | ',' ;optasgn : /* VOID */ | '=' ;con_e : exp %prec ',' ; ;dcl_semicolon: ';' { /* could be a struct dcl in a cast */ if (!executable) { puttext($1.end); } } ;/* executable statements */fcn_stmt_body : '{' { puttext(yyleng); fcn_body = yes; } dcl_stat_list { /* see if this function is to be traced */ tr_fcn(fcn_name); /* declare a temporary variable for string function results */ printf("char *_ct;"); /* char pointer may be bigger than int */ /* trace the function header */ tr_stmt(fcn_line, fcn_text, yes); executable = yes; } stmt_list '}' { executable = no; fcn_body = no; if (flow_break) flow_break = no; else tr_stmt(NO_LINENO, "/* return */", yes); puttext(yyleng); } ;compound_stmt : '{' { puttext(yyleng); /* trace the brace after any declarations */ fcn_line = yylineno; strncpy(fcn_text, yytext, SAVEMAX); executable = no; } dcl_stat_list { /* don't trace the '{' after "switch (a)" */ if (flow_break) flow_break = no; else tr_stmt(fcn_line, fcn_text, yes); executable = yes; } stmt_list '}' { if (flow_break) flow_break = no; else tr_stmt(yylineno, yytext, yes); puttext(yyleng); } ;stmt_list : /* no statements */ | stmt_list stmt ;stmt : compound_stmt | pp_if_stmt | flow_control_stmt { /* there could have been embedded break statements */ flow_break = no; } | flow_break_stmt { flow_break = yes; } | label { puttext(yyleng); tr_stmt(yylineno, yytext, yes); } stmt | opt_exp ';' {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -