1 %{ 2 /* $NetBSD: gram.y,v 1.3 2001/03/03 12:51:44 takemura Exp $ */ 3 4 /*- 5 * Copyright (c) 1999 6 * Shin Takemura and PocketBSD Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the PocketBSD project 19 * and its contributors. 20 * 4. Neither the name of the project nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 */ 37 38 #include <stdio.h> 39 #include <strings.h> 40 41 #include "platid_gen.h" 42 43 #define LIST_NEW(l) { \ 44 (l) = new_node(N_LIST, 0, NULL, NULL, NULL); \ 45 } 46 #define LIST_ADD(l, i) { \ 47 if ((l)->ptr1 == NULL) { \ 48 (l)->ptr1 = (i); \ 49 (l)->ptr2 = (i); \ 50 } else { \ 51 ((node_t*)(l)->ptr2)->link = (i); \ 52 (l)->ptr2 = (i); \ 53 } \ 54 (i)->link = NULL; \ 55 (l)->val++; \ 56 } 57 58 %} 59 60 %union { 61 struct node_s *node; 62 const char *str; 63 int val; 64 } 65 66 %token '{' '}' '=' ':' 67 %token <str>FSYM 68 %token <str>SYM 69 %token <str>MOD 70 %token <str>NAME 71 %token <str>DIRECTIVE 72 73 %type <str>sym 74 %type <val>name_prefix 75 %type <node>name_opt 76 %type <node>ent 77 %type <node>sub_list 78 %type <node>sub_item 79 %type <node>list 80 %type <node>item 81 82 %% 83 84 start: list { def_tree = $1; }; 85 86 list: 87 list item { LIST_ADD($1, $2); $$ = $1; } | 88 /* empty */ { LIST_NEW($$); }; 89 90 item: 91 sym ':' { $$ = new_node(N_LABEL, 0, $1, NULL, NULL); } | 92 sym '=' sym { $$ = new_node(N_MODIFIER, 0, $1, $3, NULL); } | 93 ent { $$ = $1; }| 94 '{' sub_list '}' { $$ = $2; } | 95 DIRECTIVE { $$ = new_node(N_DIRECTIVE, 0, $1, NULL, NULL); }; 96 97 sub_list: 98 sub_list sub_item { LIST_ADD($1, $2); $$ = $1; } | 99 /* empty */ { LIST_NEW($$); }; 100 101 sub_item: 102 sym '=' sym { $$ = new_node(N_MODIFIER, 0, $1, $3, NULL); }| 103 ent { $$ = $1; } | 104 '{' sub_list '}' { $$ = $2; } | 105 DIRECTIVE { $$ = new_node(N_DIRECTIVE, 0, $1, NULL, NULL); }; 106 107 ent : sym name_opt { 108 $2->ptr1 = $1; 109 /* 110 if ($2->ptr2 == NULL) { 111 $2->ptr2 = strdup($1); 112 } 113 touppers((char*)$2->ptr1); 114 */ 115 $$ = $2; 116 }; 117 118 name_opt: 119 name_prefix NAME { $$ = new_node(N_ENTRY, $1, NULL, $2, NULL); } | 120 name_prefix { $$ = new_node(N_ENTRY, $1, NULL, NULL, NULL); }; 121 122 name_prefix: 123 name_prefix '-' { $$ = $1 + 1; } | 124 /* empty */ { $$ = 0; } 125 126 sym: 127 FSYM { $$ = $1; } | 128 SYM { $$ = $1; } | 129 MOD { $$ = $1; }; 130 131 %% 132 133 char* 134 touppers(s) 135 char *s; 136 { 137 char *p; 138 139 for (p = s; *p != '\0'; p++) 140 *p = toupper(*p); 141 return (s); 142 } 143 144 void* 145 mem_alloc(size) 146 int size; 147 { 148 void *res; 149 150 if ((res = malloc(size)) == NULL) { 151 fprintf(stderr, "memory allocation failed.\n"); 152 exit(1); 153 } 154 return (res); 155 } 156 157 node_t* 158 new_node(type, val, ptr1, ptr2, link) 159 int type; 160 int val; 161 const void *ptr1, *ptr2; 162 node_t *link; 163 { 164 node_t *res; 165 166 res = mem_alloc(sizeof(node_t)); 167 res->type = type; 168 res->val = val; 169 res->ptr1 = ptr1; 170 res->ptr2 = ptr2; 171 res->link = link; 172 return (res); 173 } 174 175 void 176 dump_node(prefix, n) 177 char *prefix; 178 node_t* n; 179 { 180 char prefix2[1024]; 181 node_t *np; 182 183 sprintf(prefix2, "%s ", prefix); 184 185 switch (n->type) { 186 case N_LABEL: 187 printf("%s%s:\n", prefix, n->ptr1); 188 break; 189 case N_MODIFIER: 190 printf("%s%s=%s\n", prefix, n->ptr1, n->ptr2); 191 break; 192 case N_ENTRY: 193 if (n->val == 0) 194 printf("%s%s(%s)\n", prefix, n->ptr1, n->ptr2); 195 else 196 printf("%s%s(-%d, %s)\n", 197 prefix, n->ptr1, n->val, n->ptr2); 198 break; 199 case N_LIST: 200 printf("%s{\n", prefix); 201 for (np = (node_t*)n->ptr1; np; np = np->link) { 202 dump_node(prefix2, np); 203 } 204 printf("%s}\n", prefix); 205 break; 206 case N_DIRECTIVE: 207 printf("%s", n->ptr1); 208 break; 209 break; 210 default: 211 printf("%s???\n", prefix); 212 break; 213 } 214 } 215 216 void 217 yyerror(s) 218 const char *s; 219 { 220 extern int yyline; 221 222 fprintf(stderr, "%d: %s\n", yyline, s); 223 } 224