parse.y revision 87015
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 * $FreeBSD: head/usr.bin/colldef/parse.y 87015 2001-11-27 23:39:14Z ache $ 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#include "common.h" 40 41extern FILE *yyin; 42void yyerror(char *fmt, ...) __printflike(1, 2); 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][CHARMAP_SYMBOL_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 if (strlen($1) + 1 > CHARMAP_SYMBOL_LEN) 84 yyerror("Charmap symbol name '%s' is too long", $1); 85 strcpy(charmap_table[$2], $1); 86} 87; 88substitute : SUBSTITUTE CHAR WITH STRING { 89 if ($2 == '\0') 90 yyerror("NUL character can't be substituted"); 91 if (strchr($4, $2) != NULL) 92 yyerror("Char 0x%02x substitution is recursive", $2); 93 strcpy(__collate_substitute_table[$2], $4); 94} 95; 96order : ORDER order_list { 97 FILE *fp; 98 int ch, substed, ordered; 99 100 for (ch = 0; ch < UCHAR_MAX + 1; ch++) { 101 substed = (__collate_substitute_table[ch][0] != ch); 102 ordered = !!__collate_char_pri_table[ch].prim; 103 if (!ordered && !substed) 104 yyerror("Char 0x%02x not found", ch); 105 if (substed && ordered) 106 yyerror("Char 0x%02x can't be ordered since substituted", ch); 107 } 108 109 fp = fopen(out_file, "w"); 110 if(!fp) 111 err(EX_UNAVAILABLE, "can't open destination file %s", 112 out_file); 113 114 strcpy(__collate_version, COLLATE_VERSION); 115 fwrite(__collate_version, sizeof(__collate_version), 1, fp); 116 fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 117 fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 118 fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 119 if (fflush(fp)) 120 err(EX_UNAVAILABLE, "IO error writting to destination file %s", 121 out_file); 122 fclose(fp); 123#ifdef COLLATE_DEBUG 124 if (debug) 125 collate_print_tables(); 126#endif 127 exit(EX_OK); 128} 129; 130order_list : item 131 | order_list ';' item 132; 133item : CHAR { 134 if (__collate_char_pri_table[$1].prim) 135 yyerror("Char 0x%02x duplicated", $1); 136 __collate_char_pri_table[$1].prim = prim_pri++; 137} 138 | CHAIN { 139 if (chain_index >= TABLE_SIZE - 1) 140 yyerror("__collate_chain_pri_table overflow"); 141 strcpy(__collate_chain_pri_table[chain_index].str, $1); 142 __collate_chain_pri_table[chain_index++].prim = prim_pri++; 143} 144 | CHAR RANGE CHAR { 145 u_int i; 146 147 if ($3 <= $1) 148 yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 149 150 for (i = $1; i <= $3; i++) { 151 if (__collate_char_pri_table[(u_char)i].prim) 152 yyerror("Char 0x%02x duplicated", (u_char)i); 153 __collate_char_pri_table[(u_char)i].prim = prim_pri++; 154 } 155} 156 | '{' prim_order_list '}' { 157 prim_pri++; 158} 159 | '(' sec_order_list ')' { 160 prim_pri++; 161 sec_pri = 1; 162} 163; 164prim_order_list : prim_sub_item 165 | prim_order_list ',' prim_sub_item 166; 167sec_order_list : sec_sub_item 168 | sec_order_list ',' sec_sub_item 169; 170prim_sub_item : CHAR { 171 if (__collate_char_pri_table[$1].prim) 172 yyerror("Char 0x%02x duplicated", $1); 173 __collate_char_pri_table[$1].prim = prim_pri; 174} 175 | CHAR RANGE CHAR { 176 u_int i; 177 178 if ($3 <= $1) 179 yyerror("Illegal range 0x%02x -- 0x%02x", 180 $1, $3); 181 182 for (i = $1; i <= $3; i++) { 183 if (__collate_char_pri_table[(u_char)i].prim) 184 yyerror("Char 0x%02x duplicated", (u_char)i); 185 __collate_char_pri_table[(u_char)i].prim = prim_pri; 186 } 187} 188 | CHAIN { 189 if (chain_index >= TABLE_SIZE - 1) 190 yyerror("__collate_chain_pri_table overflow"); 191 strcpy(__collate_chain_pri_table[chain_index].str, $1); 192 __collate_chain_pri_table[chain_index++].prim = prim_pri; 193} 194; 195sec_sub_item : CHAR { 196 if (__collate_char_pri_table[$1].prim) 197 yyerror("Char 0x%02x duplicated", $1); 198 __collate_char_pri_table[$1].prim = prim_pri; 199 __collate_char_pri_table[$1].sec = sec_pri++; 200} 201 | CHAR RANGE CHAR { 202 u_int i; 203 204 if ($3 <= $1) 205 yyerror("Illegal range 0x%02x -- 0x%02x", 206 $1, $3); 207 208 for (i = $1; i <= $3; i++) { 209 if (__collate_char_pri_table[(u_char)i].prim) 210 yyerror("Char 0x%02x duplicated", (u_char)i); 211 __collate_char_pri_table[(u_char)i].prim = prim_pri; 212 __collate_char_pri_table[(u_char)i].sec = sec_pri++; 213 } 214} 215 | CHAIN { 216 if (chain_index >= TABLE_SIZE - 1) 217 yyerror("__collate_chain_pri_table overflow"); 218 strcpy(__collate_chain_pri_table[chain_index].str, $1); 219 __collate_chain_pri_table[chain_index].prim = prim_pri; 220 __collate_chain_pri_table[chain_index++].sec = sec_pri++; 221} 222; 223%% 224int 225main(ac, av) 226 char **av; 227{ 228 int ch; 229 230#ifdef COLLATE_DEBUG 231 while((ch = getopt(ac, av, ":do:I:")) != EOF) { 232#else 233 while((ch = getopt(ac, av, ":o:I:")) != EOF) { 234#endif 235 switch (ch) 236 { 237#ifdef COLLATE_DEBUG 238 case 'd': 239 debug++; 240 break; 241#endif 242 case 'o': 243 out_file = optarg; 244 break; 245 246 case 'I': 247 strlcpy(map_name, optarg, sizeof(map_name)); 248 break; 249 250 default: 251 usage(); 252 } 253 } 254 ac -= optind; 255 av += optind; 256 if(ac > 0) { 257 if((yyin = fopen(*av, "r")) == 0) 258 err(EX_UNAVAILABLE, "can't open source file %s", *av); 259 } 260 for(ch = 0; ch <= UCHAR_MAX; ch++) 261 __collate_substitute_table[ch][0] = ch; 262 yyparse(); 263 return 0; 264} 265 266static void 267usage() 268{ 269 fprintf(stderr, "usage: colldef [-o out_file] [-I map_dir] [filename]\n"); 270 exit(EX_USAGE); 271} 272 273void yyerror(char *fmt, ...) 274{ 275 va_list ap; 276 char msg[128]; 277 278 va_start(ap, fmt); 279 vsnprintf(msg, sizeof(msg), fmt, ap); 280 va_end(ap); 281 errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 282} 283 284#ifdef COLLATE_DEBUG 285void 286collate_print_tables() 287{ 288 int i; 289 struct __collate_st_chain_pri *p2; 290 291 printf("Substitute table:\n"); 292 for (i = 0; i < UCHAR_MAX + 1; i++) 293 if (i != *__collate_substitute_table[i]) 294 printf("\t'%c' --> \"%s\"\n", i, 295 __collate_substitute_table[i]); 296 printf("Chain priority table:\n"); 297 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 298 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 299 printf("Char priority table:\n"); 300 for (i = 0; i < UCHAR_MAX + 1; i++) 301 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 302 __collate_char_pri_table[i].sec); 303} 304#endif 305