parse.y revision 23706
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.7 1997/02/22 19:54:31 peter 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, ...); 43 44char map_name[FILENAME_MAX] = "."; 45 46char __collate_version[STR_LEN]; 47u_char charmap_table[UCHAR_MAX + 1][STR_LEN]; 48u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 49struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 50struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 51int chain_index; 52int prim_pri = 1, sec_pri = 1; 53#ifdef COLLATE_DEBUG 54int debug; 55#endif 56 57char *out_file = "LC_COLLATE"; 58%} 59%union { 60 u_char ch; 61 u_char str[STR_LEN]; 62} 63%token SUBSTITUTE WITH ORDER RANGE 64%token <str> STRING 65%token <str> CHAIN 66%token <str> DEFN 67%token <ch> CHAR 68%% 69collate : statment_list 70; 71statment_list : statment 72 | statment_list '\n' statment 73; 74statment : 75 | charmap 76 | substitute 77 | order 78; 79charmap : DEFN CHAR { 80 strcpy(charmap_table[$2], $1); 81} 82; 83substitute : SUBSTITUTE STRING WITH STRING { 84 strcpy(__collate_substitute_table[$2[0]], $4); 85} 86; 87order : ORDER order_list { 88 FILE *fp; 89 int ch; 90 91 for (ch = 0; ch < UCHAR_MAX + 1; ch++) 92 if (!__collate_char_pri_table[ch].prim) 93 yyerror("Char 0x%02x not present", ch); 94 95 fp = fopen(out_file, "w"); 96 if(!fp) 97 err(EX_UNAVAILABLE, "can't open destination file %s", 98 out_file); 99 100 strcpy(__collate_version, COLLATE_VERSION); 101 fwrite(__collate_version, sizeof(__collate_version), 1, fp); 102 fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 103 fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 104 fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 105 if (fflush(fp)) 106 err(EX_UNAVAILABLE, "IO error writting to destination file %s", 107 out_file); 108 fclose(fp); 109#ifdef COLLATE_DEBUG 110 if (debug) 111 collate_print_tables(); 112#endif 113 exit(EX_OK); 114} 115; 116order_list : item 117 | order_list ';' item 118; 119item : CHAR { 120 if (__collate_char_pri_table[$1].prim) 121 yyerror("Char 0x%02x duplicated", $1); 122 __collate_char_pri_table[$1].prim = prim_pri++; 123} 124 | CHAIN { 125 if (chain_index >= TABLE_SIZE - 1) 126 yyerror("__collate_chain_pri_table overflow"); 127 strcpy(__collate_chain_pri_table[chain_index].str, $1); 128 __collate_chain_pri_table[chain_index++].prim = prim_pri++; 129} 130 | CHAR RANGE CHAR { 131 u_int i; 132 133 if ($3 <= $1) 134 yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 135 136 for (i = $1; i <= $3; i++) { 137 if (__collate_char_pri_table[(u_char)i].prim) 138 yyerror("Char 0x%02x duplicated", (u_char)i); 139 __collate_char_pri_table[(u_char)i].prim = prim_pri++; 140 } 141} 142 | '{' prim_order_list '}' { 143 prim_pri++; 144} 145 | '(' sec_order_list ')' { 146 prim_pri++; 147 sec_pri = 1; 148} 149; 150prim_order_list : prim_sub_item 151 | prim_order_list ',' prim_sub_item 152; 153sec_order_list : sec_sub_item 154 | sec_order_list ',' sec_sub_item 155; 156prim_sub_item : CHAR { 157 if (__collate_char_pri_table[$1].prim) 158 yyerror("Char 0x%02x duplicated", $1); 159 __collate_char_pri_table[$1].prim = prim_pri; 160} 161 | CHAR RANGE CHAR { 162 u_int i; 163 164 if ($3 <= $1) 165 yyerror("Illegal range 0x%02x -- 0x%02x", 166 $1, $3); 167 168 for (i = $1; i <= $3; i++) { 169 if (__collate_char_pri_table[(u_char)i].prim) 170 yyerror("Char 0x%02x duplicated", (u_char)i); 171 __collate_char_pri_table[(u_char)i].prim = prim_pri; 172 } 173} 174 | CHAIN { 175 if (chain_index >= TABLE_SIZE - 1) 176 yyerror("__collate_chain_pri_table overflow"); 177 strcpy(__collate_chain_pri_table[chain_index].str, $1); 178 __collate_chain_pri_table[chain_index++].prim = prim_pri; 179} 180; 181sec_sub_item : CHAR { 182 if (__collate_char_pri_table[$1].prim) 183 yyerror("Char 0x%02x duplicated", $1); 184 __collate_char_pri_table[$1].prim = prim_pri; 185 __collate_char_pri_table[$1].sec = sec_pri++; 186} 187 | CHAR RANGE CHAR { 188 u_int i; 189 190 if ($3 <= $1) 191 yyerror("Illegal range 0x%02x -- 0x%02x", 192 $1, $3); 193 194 for (i = $1; i <= $3; i++) { 195 if (__collate_char_pri_table[(u_char)i].prim) 196 yyerror("Char 0x%02x duplicated", (u_char)i); 197 __collate_char_pri_table[(u_char)i].prim = prim_pri; 198 __collate_char_pri_table[(u_char)i].sec = sec_pri++; 199 } 200} 201 | CHAIN { 202 if (chain_index >= TABLE_SIZE - 1) 203 yyerror("__collate_chain_pri_table overflow"); 204 strcpy(__collate_chain_pri_table[chain_index].str, $1); 205 __collate_chain_pri_table[chain_index].prim = prim_pri; 206 __collate_chain_pri_table[chain_index++].sec = sec_pri++; 207} 208; 209%% 210main(ac, av) 211 char **av; 212{ 213 int ch; 214 215#ifdef COLLATE_DEBUG 216 while((ch = getopt(ac, av, ":do:I:")) != EOF) { 217#else 218 while((ch = getopt(ac, av, ":o:I:")) != EOF) { 219#endif 220 switch (ch) 221 { 222#ifdef COLLATE_DEBUG 223 case 'd': 224 debug++; 225 break; 226#endif 227 case 'o': 228 out_file = optarg; 229 break; 230 231 case 'I': 232 strcpy(map_name, optarg); 233 break; 234 235 default: 236 fprintf(stderr, "Usage: %s [-o out_file] [-I map_dir] [in_file]\n", 237 av[0]); 238 exit(EX_OK); 239 } 240 } 241 ac -= optind; 242 av += optind; 243 if(ac > 0) { 244 if((yyin = fopen(*av, "r")) == 0) 245 err(EX_UNAVAILABLE, "can't open source file %s", *av); 246 } 247 for(ch = 0; ch <= UCHAR_MAX; ch++) 248 __collate_substitute_table[ch][0] = ch; 249 yyparse(); 250 return 0; 251} 252 253void yyerror(char *fmt, ...) 254{ 255 va_list ap; 256 char msg[128]; 257 258 va_start(ap, fmt); 259 vsprintf(msg, fmt, ap); 260 va_end(ap); 261 errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 262} 263 264#ifdef COLLATE_DEBUG 265collate_print_tables() 266{ 267 int i; 268 struct __collate_st_chain_pri *p2; 269 270 printf("Substitute table:\n"); 271 for (i = 0; i < UCHAR_MAX + 1; i++) 272 if (i != *__collate_substitute_table[i]) 273 printf("\t'%c' --> \"%s\"\n", i, 274 __collate_substitute_table[i]); 275 printf("Chain priority table:\n"); 276 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 277 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 278 printf("Char priority table:\n"); 279 for (i = 0; i < UCHAR_MAX + 1; i++) 280 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 281 __collate_char_pri_table[i].sec); 282} 283#endif 284