parse.y revision 41568
1%{ 2/*- 3 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 4 * at Electronni Visti IA, Kiev, Ukraine. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $Id: parse.y,v 1.10 1997/06/30 11:24:18 charnier Exp $ 29 */ 30 31#include <err.h> 32#include <stdarg.h> 33#include <stdio.h> 34#include <string.h> 35#include <stdlib.h> 36#include <unistd.h> 37#include <sysexits.h> 38#include "collate.h" 39 40extern int line_no; 41extern FILE *yyin; 42void yyerror(char *fmt, ...); 43int yyparse(void); 44int yylex(void); 45static void usage __P((void)); 46 47char map_name[FILENAME_MAX] = "."; 48 49char __collate_version[STR_LEN]; 50u_char charmap_table[UCHAR_MAX + 1][STR_LEN]; 51u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 52struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 53struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 54int chain_index; 55int prim_pri = 1, sec_pri = 1; 56#ifdef COLLATE_DEBUG 57int debug; 58#endif 59 60char *out_file = "LC_COLLATE"; 61%} 62%union { 63 u_char ch; 64 u_char str[STR_LEN]; 65} 66%token SUBSTITUTE WITH ORDER RANGE 67%token <str> STRING 68%token <str> CHAIN 69%token <str> DEFN 70%token <ch> CHAR 71%% 72collate : statment_list 73; 74statment_list : statment 75 | statment_list '\n' statment 76; 77statment : 78 | charmap 79 | substitute 80 | order 81; 82charmap : DEFN CHAR { 83 strcpy(charmap_table[$2], $1); 84} 85; 86substitute : SUBSTITUTE STRING WITH STRING { 87 strcpy(__collate_substitute_table[$2[0]], $4); 88} 89; 90order : ORDER order_list { 91 FILE *fp; 92 int ch; 93 94 for (ch = 0; ch < UCHAR_MAX + 1; ch++) 95 if (!__collate_char_pri_table[ch].prim) 96 yyerror("Char 0x%02x not present", ch); 97 98 fp = fopen(out_file, "w"); 99 if(!fp) 100 err(EX_UNAVAILABLE, "can't open destination file %s", 101 out_file); 102 103 strcpy(__collate_version, COLLATE_VERSION); 104 fwrite(__collate_version, sizeof(__collate_version), 1, fp); 105 fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 106 fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 107 fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 108 if (fflush(fp)) 109 err(EX_UNAVAILABLE, "IO error writting to destination file %s", 110 out_file); 111 fclose(fp); 112#ifdef COLLATE_DEBUG 113 if (debug) 114 collate_print_tables(); 115#endif 116 exit(EX_OK); 117} 118; 119order_list : item 120 | order_list ';' item 121; 122item : CHAR { 123 if (__collate_char_pri_table[$1].prim) 124 yyerror("Char 0x%02x duplicated", $1); 125 __collate_char_pri_table[$1].prim = prim_pri++; 126} 127 | CHAIN { 128 if (chain_index >= TABLE_SIZE - 1) 129 yyerror("__collate_chain_pri_table overflow"); 130 strcpy(__collate_chain_pri_table[chain_index].str, $1); 131 __collate_chain_pri_table[chain_index++].prim = prim_pri++; 132} 133 | CHAR RANGE CHAR { 134 u_int i; 135 136 if ($3 <= $1) 137 yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 138 139 for (i = $1; i <= $3; i++) { 140 if (__collate_char_pri_table[(u_char)i].prim) 141 yyerror("Char 0x%02x duplicated", (u_char)i); 142 __collate_char_pri_table[(u_char)i].prim = prim_pri++; 143 } 144} 145 | '{' prim_order_list '}' { 146 prim_pri++; 147} 148 | '(' sec_order_list ')' { 149 prim_pri++; 150 sec_pri = 1; 151} 152; 153prim_order_list : prim_sub_item 154 | prim_order_list ',' prim_sub_item 155; 156sec_order_list : sec_sub_item 157 | sec_order_list ',' sec_sub_item 158; 159prim_sub_item : CHAR { 160 if (__collate_char_pri_table[$1].prim) 161 yyerror("Char 0x%02x duplicated", $1); 162 __collate_char_pri_table[$1].prim = prim_pri; 163} 164 | CHAR RANGE CHAR { 165 u_int i; 166 167 if ($3 <= $1) 168 yyerror("Illegal range 0x%02x -- 0x%02x", 169 $1, $3); 170 171 for (i = $1; i <= $3; i++) { 172 if (__collate_char_pri_table[(u_char)i].prim) 173 yyerror("Char 0x%02x duplicated", (u_char)i); 174 __collate_char_pri_table[(u_char)i].prim = prim_pri; 175 } 176} 177 | CHAIN { 178 if (chain_index >= TABLE_SIZE - 1) 179 yyerror("__collate_chain_pri_table overflow"); 180 strcpy(__collate_chain_pri_table[chain_index].str, $1); 181 __collate_chain_pri_table[chain_index++].prim = prim_pri; 182} 183; 184sec_sub_item : CHAR { 185 if (__collate_char_pri_table[$1].prim) 186 yyerror("Char 0x%02x duplicated", $1); 187 __collate_char_pri_table[$1].prim = prim_pri; 188 __collate_char_pri_table[$1].sec = sec_pri++; 189} 190 | CHAR RANGE CHAR { 191 u_int i; 192 193 if ($3 <= $1) 194 yyerror("Illegal range 0x%02x -- 0x%02x", 195 $1, $3); 196 197 for (i = $1; i <= $3; i++) { 198 if (__collate_char_pri_table[(u_char)i].prim) 199 yyerror("Char 0x%02x duplicated", (u_char)i); 200 __collate_char_pri_table[(u_char)i].prim = prim_pri; 201 __collate_char_pri_table[(u_char)i].sec = sec_pri++; 202 } 203} 204 | CHAIN { 205 if (chain_index >= TABLE_SIZE - 1) 206 yyerror("__collate_chain_pri_table overflow"); 207 strcpy(__collate_chain_pri_table[chain_index].str, $1); 208 __collate_chain_pri_table[chain_index].prim = prim_pri; 209 __collate_chain_pri_table[chain_index++].sec = sec_pri++; 210} 211; 212%% 213int 214main(ac, av) 215 char **av; 216{ 217 int ch; 218 219#ifdef COLLATE_DEBUG 220 while((ch = getopt(ac, av, ":do:I:")) != EOF) { 221#else 222 while((ch = getopt(ac, av, ":o:I:")) != EOF) { 223#endif 224 switch (ch) 225 { 226#ifdef COLLATE_DEBUG 227 case 'd': 228 debug++; 229 break; 230#endif 231 case 'o': 232 out_file = optarg; 233 break; 234 235 case 'I': 236 strcpy(map_name, optarg); 237 break; 238 239 default: 240 usage(); 241 } 242 } 243 ac -= optind; 244 av += optind; 245 if(ac > 0) { 246 if((yyin = fopen(*av, "r")) == 0) 247 err(EX_UNAVAILABLE, "can't open source file %s", *av); 248 } 249 for(ch = 0; ch <= UCHAR_MAX; ch++) 250 __collate_substitute_table[ch][0] = ch; 251 yyparse(); 252 return 0; 253} 254 255static void 256usage() 257{ 258 fprintf(stderr, "usage: colldef [-o out_file] [-I map_dir] [filename]\n"); 259 exit(EX_USAGE); 260} 261 262void yyerror(char *fmt, ...) 263{ 264 va_list ap; 265 char msg[128]; 266 267 va_start(ap, fmt); 268 vsprintf(msg, fmt, ap); 269 va_end(ap); 270 errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 271} 272 273#ifdef COLLATE_DEBUG 274void 275collate_print_tables() 276{ 277 int i; 278 struct __collate_st_chain_pri *p2; 279 280 printf("Substitute table:\n"); 281 for (i = 0; i < UCHAR_MAX + 1; i++) 282 if (i != *__collate_substitute_table[i]) 283 printf("\t'%c' --> \"%s\"\n", i, 284 __collate_substitute_table[i]); 285 printf("Chain priority table:\n"); 286 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 287 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 288 printf("Char priority table:\n"); 289 for (i = 0; i < UCHAR_MAX + 1; i++) 290 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 291 __collate_char_pri_table[i].sec); 292} 293#endif 294