home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / UNIX / Programming / class-dump-2.1.1-MIS / src / gram.y < prev    next >
Encoding:
Lex Description  |  1997-10-09  |  6.7 KB  |  412 lines

  1. %{
  2.  
  3. //
  4. // $Id: gram.y,v 1.4 1997/10/09 07:51:19 nygard Exp $
  5. //
  6.  
  7. //
  8. //  This file is a part of class-dump v2, a utility for examining the
  9. //  Objective-C segment of Mach-O files.
  10. //  Copyright (C) 1997  Steve Nygard
  11. //
  12. //  This program is free software; you can redistribute it and/or modify
  13. //  it under the terms of the GNU General Public License as published by
  14. //  the Free Software Foundation; either version 2 of the License, or
  15. //  (at your option) any later version.
  16. //
  17. //  This program is distributed in the hope that it will be useful,
  18. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. //  GNU General Public License for more details.
  21. //
  22. //  You should have received a copy of the GNU General Public License
  23. //  along with this program; if not, write to the Free Software
  24. //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. //
  26. //  You may contact the author by:
  27. //     e-mail:  nygard@telusplanet.net
  28. //
  29.  
  30. #include <assert.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35. #include "datatypes.h"
  36.  
  37. extern int ident_state;
  38. extern char yytext[];
  39.  
  40. struct method_type *rtype = NULL;
  41. int parsing_ivar = 0;
  42.  
  43. //----------------------------------------------------------------------
  44.  
  45. char *strdup (const char *str);
  46. int yylex (void);
  47. int yyerror (char *s);
  48.  
  49. //----------------------------------------------------------------------
  50.  
  51. char *strdup (const char *str)
  52. {
  53.     char *ptr = malloc (strlen (str) + 1);
  54.  
  55.     assert (ptr != NULL);
  56.  
  57.     strcpy (ptr, str);
  58.  
  59.     return ptr;
  60. }
  61.  
  62. %}
  63.  
  64. %union
  65. {
  66.     int u_int;
  67.     char *u_str;
  68.     struct my_objc_type *u_type;
  69.     struct method_type *u_meth;
  70. };
  71.  
  72. %type <u_int> start
  73. %type <u_meth> method_type_list method_type
  74.  
  75. %type <u_type> type
  76. %type <u_int> modifier
  77. %type <u_type> unmodified_type
  78. %type <u_int> simple_type
  79. %type <u_type> id_type
  80. %type <u_type> structure_type
  81. %type <u_type> optional_format
  82. %type <u_type> taglist
  83. %type <u_type> tag
  84. %type <u_str> quoted_name
  85. %type <u_int> quoted_name_prefix
  86. %type <u_type> union_type
  87. %type <u_type> union_types
  88. %type <u_type> array_type
  89. %type <u_str> identifier
  90. %type <u_str> number
  91.  
  92.  
  93. %type <u_int> 'c' 'i' 's' 'l' 'q'
  94. %type <u_int> 'C' 'I' 'S' 'L' 'Q'
  95. %type <u_int> 'f' 'd' 'v' '*' '#'
  96. %type <u_int> ':' '%' 'r' 'n' 'N'
  97. %type <u_int> 'o' 'O' 'R' 'V'
  98.  
  99. %type <u_int> '^' 'b'
  100.  
  101. %token <u_str> TK_NUMBER
  102. %token <u_str> TK_IDENTIFIER
  103.  
  104. %token T_NAMED_OBJECT
  105.  
  106. %expect 1
  107.  
  108. %%
  109.  
  110. start:
  111.     type
  112.         {
  113.             rtype = create_method_type ($1, NULL);
  114.             $$ = 0;
  115.         }
  116.     | method_type_list
  117.         {
  118.             rtype = reverse_method_types ($1);
  119.             $$ = 0;
  120.         }
  121.     ;
  122.  
  123. method_type_list:
  124.     method_type
  125.     | method_type_list method_type
  126.         {
  127.             $2->next = $1;
  128.             $$ = $2;
  129.         }
  130.     ;
  131.  
  132. method_type:
  133.     type number
  134.         {
  135.             $$ = create_method_type ($1, $2);
  136.         }
  137.     ;
  138.  
  139. type:    unmodified_type
  140.     | modifier type
  141.         {
  142.             $$ = create_modified_type ($1, $2);
  143.         }
  144.     ;
  145.  
  146. modifier:
  147.     'r' { $$ = 'r'; }
  148.     | 'n' { $$ = 'n'; }
  149.     | 'N' { $$ = 'N'; }
  150.     | 'o' { $$ = 'o'; }
  151.     | 'O' { $$ = 'O'; }
  152.     | 'R' { $$ = 'R'; }
  153.     | 'V' { $$ = 'V'; }
  154.     ;
  155.  
  156. unmodified_type:
  157.     simple_type
  158.         {
  159.             $$ = create_simple_type ($1);
  160.         }
  161.     | id_type
  162.     | '^' type
  163.         {
  164.             $$ = create_pointer_type ($2);
  165.         }
  166.     | 'b' number
  167.         {
  168.             $$ = create_bitfield_type ($2);
  169.         }
  170.     | structure_type
  171.     | union_type
  172.     | array_type
  173.     ;
  174.  
  175. simple_type:
  176.     'c' { $$ = 'c'; }
  177.     | 'i' { $$ = 'i'; }
  178.     | 's' { $$ = 's'; }
  179.     | 'l' { $$ = 'l'; }
  180.     | 'q' { $$ = 'q'; }
  181.     | 'C' { $$ = 'C'; }
  182.     | 'I' { $$ = 'I'; }
  183.     | 'S' { $$ = 'S'; }
  184.     | 'L' { $$ = 'L'; }
  185.     | 'Q' { $$ = 'Q'; }
  186.     | 'f' { $$ = 'f'; }
  187.     | 'd' { $$ = 'd'; }
  188.     | 'v' { $$ = 'v'; }
  189.     | '*' { $$ = '*'; }
  190.     | '#' { $$ = '#'; }
  191.     | ':' { $$ = ':'; }
  192.     | '%' { $$ = '%'; }
  193.     | '?' { $$ = '?'; }
  194.     ;
  195.  
  196. /* This gives the shift/reduce error... */
  197.  
  198. id_type:
  199.     '@'
  200.         {
  201.             $$ = create_id_type (NULL);
  202.         }
  203.     | '@' quoted_name
  204.         {
  205.             $$ = create_id_type ($2);
  206.         }
  207.     ;
  208.  
  209. structure_type:
  210.     '{' { ident_state = 1; } identifier optional_format '}'
  211.         {
  212.             $$ = create_struct_type ($3, $4);
  213.         }
  214.     ;
  215.  
  216. optional_format:
  217.     /* empty */
  218.         {
  219.             $$ = NULL;
  220.         }
  221.     | '=' taglist
  222.         {
  223.             $$ = reverse_types ($2);
  224.         }
  225.     ;
  226.  
  227. taglist:
  228.     /* empty */
  229.         {
  230.             $$ = NULL;
  231.         }
  232.     | taglist tag
  233.         {
  234.             $2->next = $1;
  235.             $$ = $2;
  236.         }
  237.     ;
  238.  
  239. tag:
  240.     quoted_name type
  241.         {
  242.             $2->var_name = $1;
  243.             $$ = $2;
  244.         }
  245.     | type
  246.         {
  247.             $1->var_name = strdup ("___");
  248.             $$ = $1;
  249.         }
  250.     ;
  251.  
  252. quoted_name:
  253.     quoted_name_prefix identifier '"'
  254.         {
  255.             $$ = $2;
  256.         }
  257.     | quoted_name_prefix '"'
  258.         {
  259.             $$ = strdup ("");
  260.         }
  261.     ;
  262.  
  263. quoted_name_prefix:
  264.     '"' { ident_state = 1; }
  265.     ;
  266.  
  267. union_type:
  268.     union_type_prefix union_types ')'
  269.         {
  270.             $$ = create_union_type (reverse_types ($2), NULL);
  271.         }
  272.     | union_type_prefix identifier ')'
  273.         {
  274.             $$ = create_union_type (NULL, $2);
  275.         }
  276.     ;
  277.  
  278. union_type_prefix:
  279.     '('
  280.         {
  281.             /*
  282.              * Great - for a union, an instance variable has a name, and no type,
  283.              *         but a method has the types, and no name!
  284.              */
  285.             if (parsing_ivar == 1)
  286.                 ident_state = 1;
  287.         }
  288.     ;
  289.  
  290. union_types:
  291.     /* empty */
  292.         {
  293.             $$ = NULL;
  294.         }
  295.     | union_types type
  296.         {
  297.             $2->var_name = strdup ("___");
  298.             $2->next = $1;
  299.             $$ = $2;
  300.         }
  301.     ;
  302.  
  303. array_type:
  304.     '[' number type ']'
  305.         {
  306.             $$ = create_array_type ($2, $3);
  307.         }
  308.     ;
  309.  
  310. identifier:
  311.     TK_IDENTIFIER
  312.         {
  313.             $$ = strdup (yytext);
  314.         }
  315.     ;
  316.  
  317. number:
  318.     TK_NUMBER
  319.         {
  320.             $$ = strdup (yytext);
  321.         }
  322.     ;
  323.  
  324. %%
  325.  
  326. extern yy_scan_string();
  327.  
  328. int yyerror (char *s)
  329. {
  330.     fprintf (stderr, "%s\n", s);
  331.     return 0;
  332. }
  333.  
  334. int parse_ivar_type (void)
  335. {
  336.     parsing_ivar = 1;
  337.     return yyparse();
  338. }
  339.  
  340. int parse_method_type (void)
  341. {
  342.     parsing_ivar = 0;
  343.     return yyparse();
  344. }
  345.  
  346. void format_type (const char *type, const char *name, int level)
  347. {
  348.     int parse_flag;
  349.         extern int expand_structures_flag;
  350.  
  351.     rtype = NULL;
  352.     yy_scan_string (type);
  353.     parse_flag = parse_ivar_type();
  354.  
  355.     if (parse_flag == 0)
  356.     {
  357.         if (name != NULL)
  358.             rtype->type->var_name = strdup (name);
  359.                 indent_to_level (level);
  360.         print_type (rtype->type, expand_structures_flag, level);
  361.         printf (";");
  362.  
  363.         rtype = NULL;
  364.     }
  365.     else
  366.         {
  367.         printf ("Error! format_type (%s, %s)\n", type, name);
  368.                 printf ("\n\n");
  369.         }
  370.  
  371.     free_allocated_methods();
  372.     free_allocated_types();
  373. }
  374.  
  375. void format_method (char method_type, const char *name, const char *types)
  376. {
  377.     int parse_flag;
  378.  
  379.     if (name == NULL)
  380.     {
  381.         printf ("%c (method name not found in OBJC segments), args: %s", method_type, types);
  382.         return;
  383.     }
  384.  
  385.         if (*name == '\0' || *types == '\0')
  386.         {
  387.         printf ("Error! format_method (%c, %s, %s\n", method_type, name, types);
  388.         return;
  389.         }
  390.  
  391.     rtype = NULL;
  392.     yy_scan_string (types);
  393.     parse_flag = parse_method_type();
  394.  
  395.     if (parse_flag == 0)
  396.     {
  397.         print_method (method_type, name, rtype);
  398.         rtype = NULL;
  399.     }
  400.     else
  401.         {
  402.         extern const char *scanner_ptr;
  403.  
  404.         printf ("Error! format_method (%c, %s, %s )\n", method_type, name, types);
  405.                 printf ("at %s\n", scanner_ptr);
  406.                 printf ("\n\n");
  407.         }
  408.  
  409.     free_allocated_methods();
  410.     free_allocated_types();
  411. }
  412.