home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / modutils / genksyms / parse.y < prev    next >
Encoding:
Text File  |  1998-01-06  |  9.8 KB  |  457 lines

  1. /* C global declaration parser for genksyms.
  2.    Copyright 1996, 1997 Linux International.
  3.  
  4.    New implementation contributed by Richard Henderson <rth@tamu.edu>
  5.    Based on original work by Bjorn Eckwall <bj0rn@blox.se>
  6.  
  7.    This file is part of the Linux modutils.
  8.  
  9.    This program is free software; you can redistribute it and/or modify it
  10.    under the terms of the GNU General Public License as published by the
  11.    Free Software Foundation; either version 2 of the License, or (at your
  12.    option) any later version.
  13.  
  14.    This program is distributed in the hope that it will be useful, but
  15.    WITHOUT ANY WARRANTY; without even the implied warranty of
  16.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.    General Public License for more details.
  18.  
  19.    You should have received a copy of the GNU General Public License
  20.    along with this program; if not, write to the Free Software Foundation,
  21.    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  22.  
  23.  
  24. %{
  25. #ident "$Id: parse.y,v 1.1.1.1 1998/01/06 20:51:07 ewt Exp $"
  26.  
  27. #include <assert.h>
  28. #include "genksyms.h"
  29.  
  30. static int is_typedef;
  31. static char *current_name;
  32. static struct string_list *decl_spec;
  33.  
  34. static void yyerror(const char *);
  35.  
  36. static inline void
  37. remove_node(struct string_list **p)
  38. {
  39.   struct string_list *node = *p;
  40.   *p = node->next;
  41.   free_node(node);
  42. }
  43.  
  44. static inline void
  45. remove_list(struct string_list **pb, struct string_list **pe)
  46. {
  47.   struct string_list *b = *pb, *e = *pe;
  48.   *pb = e;
  49.   free_list(b, e);
  50. }
  51.  
  52. %}
  53.  
  54. %token ASM_KEYW
  55. %token ATTRIBUTE_KEYW
  56. %token AUTO_KEYW
  57. %token CHAR_KEYW
  58. %token CONST_KEYW
  59. %token DOUBLE_KEYW
  60. %token ENUM_KEYW
  61. %token EXTERN_KEYW
  62. %token FLOAT_KEYW
  63. %token INLINE_KEYW
  64. %token INT_KEYW
  65. %token LONG_KEYW
  66. %token REGISTER_KEYW
  67. %token SHORT_KEYW
  68. %token SIGNED_KEYW
  69. %token STATIC_KEYW
  70. %token STRUCT_KEYW
  71. %token TYPEDEF_KEYW
  72. %token UNION_KEYW
  73. %token UNSIGNED_KEYW
  74. %token VOID_KEYW
  75. %token VOLATILE_KEYW
  76.  
  77. %token EXPORT_SYMBOL_KEYW
  78.  
  79. %token ASM_PHRASE
  80. %token ATTRIBUTE_PHRASE
  81. %token BRACE_PHRASE
  82. %token BRACKET_PHRASE
  83. %token EXPRESSION_PHRASE
  84.  
  85. %token CHAR
  86. %token DOTS
  87. %token IDENT
  88. %token INT
  89. %token REAL
  90. %token STRING
  91. %token TYPE
  92. %token OTHER
  93. %token FILENAME
  94.  
  95. %%
  96.  
  97. declaration_seq:
  98.     declaration
  99.     | declaration_seq declaration
  100.     ;
  101.  
  102. declaration:
  103.     { is_typedef = 0; current_name = NULL; decl_spec = NULL; }
  104.     declaration1
  105.     { free_list(*$2, NULL); *$2 = NULL; }
  106.     ;
  107.  
  108. declaration1:
  109.     TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
  110.         { $$ = $3; }
  111.     | simple_declaration
  112.     | function_definition
  113.     | asm_definition
  114.     | export_definition
  115.     | error ';'                { $$ = $2; }
  116.     | error '}'                { $$ = $2; }
  117.     ;
  118.  
  119. simple_declaration:
  120.     decl_specifier_seq_opt init_declarator_list_opt ';'
  121.         { if (current_name) {
  122.             struct string_list *decl = (*$3)->next;
  123.             (*$3)->next = NULL;
  124.             add_symbol(current_name,
  125.                    is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
  126.                    decl);
  127.             current_name = NULL;
  128.           }
  129.           $$ = $3;
  130.         }
  131.     ;
  132.  
  133. init_declarator_list_opt:
  134.     /* empty */                { $$ = NULL; }
  135.     | init_declarator_list
  136.     ;
  137.  
  138. init_declarator_list:
  139.     init_declarator
  140.         { struct string_list *decl = *$1;
  141.           *$1 = NULL;
  142.           add_symbol(current_name,
  143.                  is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl);
  144.           current_name = NULL;
  145.           $$ = $1;
  146.         }
  147.     | init_declarator_list ',' init_declarator
  148.         { struct string_list *decl = *$3;
  149.           *$3 = NULL;
  150.           free_list(*$2, NULL);
  151.           *$2 = decl_spec;
  152.           add_symbol(current_name,
  153.                  is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl);
  154.           current_name = NULL;
  155.           $$ = $3;
  156.         }
  157.     ;
  158.  
  159. init_declarator:
  160.     declarator asm_phrase_opt attribute_opt initializer_opt
  161.         { $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
  162.     ;
  163.  
  164. /* Hang on to the specifiers so that we can reuse them.  */
  165. decl_specifier_seq_opt:
  166.     /* empty */                { decl_spec = NULL; }
  167.     | decl_specifier_seq
  168.  
  169. decl_specifier_seq:
  170.     decl_specifier                { decl_spec = *$1; }
  171.     | decl_specifier_seq decl_specifier    { decl_spec = *$2; }
  172.     ;
  173.  
  174. decl_specifier:
  175.     storage_class_specifier
  176.         { /* Version 2 checksumming ignores storage class, as that
  177.              is really irrelevant to the linkage.  */
  178.           if (checksum_version > 1)
  179.             remove_node($1);
  180.           $$ = $1;
  181.         }
  182.     | type_specifier
  183.     ;
  184.  
  185. storage_class_specifier:
  186.     AUTO_KEYW | REGISTER_KEYW | STATIC_KEYW | EXTERN_KEYW | INLINE_KEYW
  187.     ;
  188.  
  189. type_specifier:
  190.     simple_type_specifier
  191.     | cva_qualifier
  192.  
  193.     /* References to s/u/e's defined elsewhere.  Rearrange things
  194.        so that it is easier to expand the definition fully later.  */
  195.     | STRUCT_KEYW IDENT
  196.         { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
  197.     | UNION_KEYW IDENT
  198.         { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
  199.     | ENUM_KEYW IDENT
  200.         { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
  201.  
  202.     /* Full definitions of an s/u/e.  Record it.  */
  203.     | STRUCT_KEYW IDENT class_body
  204.         { struct string_list *s = *$3, *i = *$2, *r;
  205.           r = copy_node(i); r->tag = SYM_STRUCT;
  206.           r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
  207.           add_symbol(i->string, SYM_STRUCT, s);
  208.           $$ = $3;
  209.         }
  210.     | UNION_KEYW IDENT class_body
  211.         { struct string_list *s = *$3, *i = *$2, *r;
  212.           r = copy_node(i); r->tag = SYM_UNION;
  213.           r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
  214.           add_symbol(i->string, SYM_UNION, s);
  215.           $$ = $3;
  216.         }
  217.     | ENUM_KEYW IDENT BRACE_PHRASE
  218.         { struct string_list *s = *$3, *i = *$2, *r;
  219.           r = copy_node(i); r->tag = SYM_ENUM;
  220.           r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
  221.           add_symbol(i->string, SYM_ENUM, s);
  222.           $$ = $3;
  223.         }
  224.  
  225.     /* Anonymous s/u/e definitions.  Nothing needs doing.  */
  226.     | ENUM_KEYW BRACE_PHRASE            { $$ = $2; }
  227.     | STRUCT_KEYW class_body            { $$ = $2; }
  228.     | UNION_KEYW class_body                { $$ = $2; }
  229.     ;
  230.  
  231. simple_type_specifier:
  232.     CHAR_KEYW
  233.     | SHORT_KEYW
  234.     | INT_KEYW
  235.     | LONG_KEYW
  236.     | SIGNED_KEYW
  237.     | UNSIGNED_KEYW
  238.     | FLOAT_KEYW
  239.     | DOUBLE_KEYW
  240.     | VOID_KEYW
  241.     | TYPE            { (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
  242.     ;
  243.  
  244. ptr_operator:
  245.     '*' cva_qualifier_seq_opt
  246.         { $$ = $2 ? $2 : $1; }
  247.     ;
  248.  
  249. cva_qualifier_seq_opt:
  250.     /* empty */                    { $$ = NULL; }
  251.     | cva_qualifier_seq
  252.     ;
  253.  
  254. cva_qualifier_seq:
  255.     cva_qualifier
  256.     | cva_qualifier_seq cva_qualifier        { $$ = $2; }
  257.     ;
  258.  
  259. cva_qualifier:
  260.     CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
  261.     ;
  262.  
  263. declarator:
  264.     ptr_operator declarator            { $$ = $2; }
  265.     | direct_declarator
  266.     ;
  267.  
  268. direct_declarator:
  269.     IDENT
  270.         { if (current_name != NULL) {
  271.             error_with_pos("unexpected second declaration name");
  272.             YYERROR;
  273.           } else {
  274.             current_name = (*$1)->string;
  275.             $$ = $1;
  276.           }
  277.         }
  278.     | direct_declarator '(' parameter_declaration_clause ')'
  279.         { $$ = $4; }
  280.     | direct_declarator '(' error ')'
  281.         { $$ = $4; }
  282.     | direct_declarator BRACKET_PHRASE
  283.         { $$ = $2; }
  284.     | '(' declarator ')'
  285.         { $$ = $3; }
  286.     | '(' error ')'
  287.         { $$ = $3; }
  288.     ;
  289.  
  290. /* Nested declarators differ from regular declarators in that they do
  291.    not record the symbols they find in the global symbol table.  */
  292. nested_declarator:
  293.     ptr_operator nested_declarator        { $$ = $2; }
  294.     | direct_nested_declarator
  295.     ;
  296.  
  297. direct_nested_declarator:
  298.     IDENT
  299.     | TYPE
  300.     | direct_nested_declarator '(' parameter_declaration_clause ')'
  301.         { $$ = $4; }
  302.     | direct_nested_declarator '(' error ')'
  303.         { $$ = $4; }
  304.     | direct_nested_declarator BRACKET_PHRASE
  305.         { $$ = $2; }
  306.     | '(' nested_declarator ')'
  307.         { $$ = $3; }
  308.     | '(' error ')'
  309.         { $$ = $3; }
  310.     ;
  311.  
  312. parameter_declaration_clause:
  313.     parameter_declaration_list_opt DOTS        { $$ = $2; }
  314.     | parameter_declaration_list_opt
  315.     | parameter_declaration_list ',' DOTS        { $$ = $3; }
  316.     ;
  317.  
  318. parameter_declaration_list_opt:
  319.     /* empty */                    { $$ = NULL; }
  320.     | parameter_declaration_list
  321.     ;
  322.  
  323. parameter_declaration_list:
  324.     parameter_declaration
  325.     | parameter_declaration_list ',' parameter_declaration
  326.         { $$ = $3; }
  327.     ;
  328.  
  329. parameter_declaration:
  330.     decl_specifier_seq m_abstract_declarator
  331.         { $$ = $2 ? $2 : $1; }
  332.     ;
  333.  
  334. m_abstract_declarator:
  335.     ptr_operator m_abstract_declarator
  336.         { $$ = $2 ? $2 : $1; }
  337.     | direct_m_abstract_declarator
  338.     ;
  339.  
  340. direct_m_abstract_declarator:
  341.     /* empty */                    { $$ = NULL; }
  342.     | IDENT
  343.         { /* For version 2 checksums, we don't want to remember
  344.              private parameter names.  */
  345.           if (checksum_version > 1)
  346.             remove_node($1);
  347.           $$ = $1;
  348.         }
  349.         /* This wasn't really a typedef name but an identifier that
  350.            shadows one.  */
  351.     | TYPE
  352.         { if (checksum_version > 1)
  353.             remove_node($1);
  354.           $$ = $1;
  355.         }
  356.     | direct_m_abstract_declarator '(' parameter_declaration_clause ')'
  357.         { $$ = $4; }
  358.     | direct_m_abstract_declarator '(' error ')'
  359.         { $$ = $4; }
  360.     | direct_m_abstract_declarator BRACKET_PHRASE
  361.         { $$ = $2; }
  362.     | '(' m_abstract_declarator ')'
  363.         { $$ = $3; }
  364.     | '(' error ')'
  365.         { $$ = $3; }
  366.     ;
  367.  
  368. function_definition:
  369.     decl_specifier_seq_opt declarator BRACE_PHRASE
  370.         { struct string_list *decl = *$2;
  371.           *$2 = NULL;
  372.           add_symbol(current_name, SYM_NORMAL, decl);
  373.           $$ = $3;
  374.         }
  375.     ;
  376.  
  377. initializer_opt:
  378.     /* empty */                    { $$ = NULL; }
  379.     | initializer
  380.     ;
  381.  
  382. /* We never care about the contents of an initializer.  */
  383. initializer:
  384.     '=' EXPRESSION_PHRASE
  385.         { remove_list($2, &(*$1)->next); $$ = $2; }
  386.     ;
  387.  
  388. class_body:
  389.     '{' member_specification_opt '}'        { $$ = $3; }
  390.     | '{' error '}'                    { $$ = $3; }
  391.     ;
  392.  
  393. member_specification_opt:
  394.     /* empty */                    { $$ = NULL; }
  395.     | member_specification
  396.     ;
  397.  
  398. member_specification:
  399.     member_declaration
  400.     | member_specification member_declaration    { $$ = $2; }
  401.     ;
  402.  
  403. member_declaration:
  404.     decl_specifier_seq_opt member_declarator_list_opt ';'
  405.         { $$ = $3; }
  406.     | error ';'
  407.         { $$ = $2; }
  408.     ;
  409.  
  410. member_declarator_list_opt:
  411.     /* empty */                    { $$ = NULL; }
  412.     | member_declarator_list
  413.     ;
  414.  
  415. member_declarator_list:
  416.     member_declarator
  417.     | member_declarator_list ',' member_declarator    { $$ = $3; }
  418.     ;
  419.  
  420. member_declarator:
  421.     nested_declarator attribute_opt            { $$ = $2 ? $2 : $1; }
  422.     | IDENT member_bitfield_declarator        { $$ = $2; }
  423.     | member_bitfield_declarator
  424.     ;
  425.  
  426. member_bitfield_declarator:
  427.     ':' EXPRESSION_PHRASE                { $$ = $2; }
  428.     ;
  429.  
  430. attribute_opt:
  431.     /* empty */                    { $$ = NULL; }
  432.     | ATTRIBUTE_PHRASE
  433.     ;
  434.  
  435. asm_definition:
  436.     ASM_PHRASE ';'                    { $$ = $2; }
  437.     ;
  438.  
  439. asm_phrase_opt:
  440.     /* empty */                    { $$ = NULL; }
  441.     | ASM_PHRASE
  442.     ;
  443.  
  444. export_definition:
  445.     EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
  446.         { export_symbol((*$3)->string); $$ = $5; }
  447.     ;
  448.  
  449.  
  450. %%
  451.  
  452. static void
  453. yyerror(const char *e)
  454. {
  455.   error_with_pos("%s", e);
  456. }
  457.