parse.y revision 19163
16527Sache%{ 26527Sache/*- 36527Sache * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 46527Sache * at Electronni Visti IA, Kiev, Ukraine. 56527Sache * All rights reserved. 66527Sache * 76527Sache * Redistribution and use in source and binary forms, with or without 86527Sache * modification, are permitted provided that the following conditions 96527Sache * are met: 106527Sache * 1. Redistributions of source code must retain the above copyright 116527Sache * notice, this list of conditions and the following disclaimer. 126527Sache * 2. Redistributions in binary form must reproduce the above copyright 136527Sache * notice, this list of conditions and the following disclaimer in the 146527Sache * documentation and/or other materials provided with the distribution. 156527Sache * 166527Sache * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 176527Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 186527Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 196527Sache * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 206527Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 216527Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 226527Sache * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 236527Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 246527Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 256527Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 266527Sache * SUCH DAMAGE. 276527Sache * 2819163Sache * $Id: parse.y,v 1.4 1996/10/23 14:59:56 ache Exp $ 296527Sache */ 306527Sache 316527Sache#include <err.h> 3218950Sache#include <stdarg.h> 336527Sache#include <stdio.h> 346527Sache#include <string.h> 356527Sache#include <stdlib.h> 366527Sache#include <sysexits.h> 376527Sache#include "collate.h" 386527Sache 396527Sacheextern int line_no; 406527Sacheextern FILE *yyin; 4118950Sachevoid yyerror(char *fmt, ...); 426527Sache 4318950Sachechar map_name[FILENAME_MAX] = "."; 4418950Sache 4518950Sachechar __collate_version[STR_LEN]; 4618950Sacheu_char charmap_table[UCHAR_MAX + 1][STR_LEN]; 476527Sacheu_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 486527Sachestruct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 496527Sachestruct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 5018950Sacheint chain_index; 516527Sacheint prim_pri = 1, sec_pri = 1; 526527Sache#ifdef COLLATE_DEBUG 536527Sacheint debug; 546527Sache#endif 556527Sache 566527Sachechar *out_file = "LC_COLLATE"; 576527Sache%} 586527Sache%union { 596527Sache u_char ch; 606527Sache u_char str[STR_LEN]; 616527Sache} 626527Sache%token SUBSTITUTE WITH ORDER RANGE 636527Sache%token <str> STRING 646527Sache%token <str> CHAIN 6518950Sache%token <str> DEFN 666527Sache%token <ch> CHAR 676527Sache%% 686527Sachecollate : statment_list 696527Sache; 706527Sachestatment_list : statment 716527Sache | statment_list '\n' statment 726527Sache; 736527Sachestatment : 746527Sache | charmap 756527Sache | substitute 766527Sache | order 776527Sache; 7818950Sachecharmap : DEFN CHAR { 7918950Sache strcpy(charmap_table[$2], $1); 806527Sache} 816527Sache; 826527Sachesubstitute : SUBSTITUTE STRING WITH STRING { 836527Sache strcpy(__collate_substitute_table[$2[0]], $4); 846527Sache} 856527Sache; 866527Sacheorder : ORDER order_list { 8719128Sache FILE *fp; 8819128Sache int ch; 896527Sache 9019128Sache for (ch = 0; ch < UCHAR_MAX + 1; ch++) 9119128Sache if (!__collate_char_pri_table[ch].prim) 9219163Sache yyerror("Char 0x%02x not present", ch); 9319128Sache 9419128Sache fp = fopen(out_file, "w"); 956527Sache if(!fp) 9618950Sache err(EX_UNAVAILABLE, "can't open destination file %s", 976527Sache out_file); 986527Sache 9918950Sache strcpy(__collate_version, COLLATE_VERSION); 10018950Sache fwrite(__collate_version, sizeof(__collate_version), 1, fp); 1016527Sache fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 1026527Sache fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 1036527Sache fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 10418950Sache if (fflush(fp)) 10518950Sache err(EX_UNAVAILABLE, "IO error writting to destination file %s", 10618950Sache out_file); 10718950Sache fclose(fp); 1086527Sache#ifdef COLLATE_DEBUG 1096527Sache if (debug) 11019128Sache collate_print_tables(); 1116527Sache#endif 1126527Sache exit(EX_OK); 1136527Sache} 1146527Sache; 1156527Sacheorder_list : item 1166527Sache | order_list ';' item 1176527Sache; 11819128Sacheitem : CHAR { 11919128Sache if (__collate_char_pri_table[$1].prim) 12019163Sache yyerror("Char 0x%02x duplicated", $1); 12119128Sache __collate_char_pri_table[$1].prim = prim_pri++; 12219128Sache} 1236527Sache | CHAIN { 1246527Sache if (chain_index >= TABLE_SIZE - 1) 1256527Sache yyerror("__collate_chain_pri_table overflow"); 1266527Sache strcpy(__collate_chain_pri_table[chain_index].str, $1); 1276527Sache __collate_chain_pri_table[chain_index++].prim = prim_pri++; 1286527Sache} 1296527Sache | CHAR RANGE CHAR { 1306527Sache u_int i; 1316527Sache 1326527Sache if ($3 <= $1) 13318950Sache yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 1346527Sache 13519128Sache for (i = $1; i <= $3; i++) { 13619128Sache if (__collate_char_pri_table[(u_char)i].prim) 13719163Sache yyerror("Char 0x%02x duplicated", (u_char)i); 1386527Sache __collate_char_pri_table[(u_char)i].prim = prim_pri++; 13919128Sache } 1406527Sache} 1416527Sache | '{' prim_order_list '}' { 1426527Sache prim_pri++; 1436527Sache} 1446527Sache | '(' sec_order_list ')' { 1456527Sache prim_pri++; 1466527Sache sec_pri = 1; 1476527Sache} 1486527Sache; 1496527Sacheprim_order_list : prim_sub_item 1506527Sache | prim_order_list ',' prim_sub_item 1516527Sache; 1526527Sachesec_order_list : sec_sub_item 1536527Sache | sec_order_list ',' sec_sub_item 1546527Sache; 1556527Sacheprim_sub_item : CHAR { 15619128Sache if (__collate_char_pri_table[$1].prim) 15719163Sache yyerror("Char 0x%02x duplicated", $1); 1586527Sache __collate_char_pri_table[$1].prim = prim_pri; 1596527Sache} 1606527Sache | CHAR RANGE CHAR { 1616527Sache u_int i; 1626527Sache 1636527Sache if ($3 <= $1) 16418950Sache yyerror("Illegal range 0x%02x -- 0x%02x", 16518950Sache $1, $3); 1666527Sache 16719128Sache for (i = $1; i <= $3; i++) { 16819128Sache if (__collate_char_pri_table[(u_char)i].prim) 16919163Sache yyerror("Char 0x%02x duplicated", (u_char)i); 1706527Sache __collate_char_pri_table[(u_char)i].prim = prim_pri; 17119128Sache } 1726527Sache} 1736527Sache | CHAIN { 1746527Sache if (chain_index >= TABLE_SIZE - 1) 1756527Sache yyerror("__collate_chain_pri_table overflow"); 1766527Sache strcpy(__collate_chain_pri_table[chain_index].str, $1); 1776527Sache __collate_chain_pri_table[chain_index++].prim = prim_pri; 1786527Sache} 1796527Sache; 1806527Sachesec_sub_item : CHAR { 18119128Sache if (__collate_char_pri_table[$1].prim) 18219163Sache yyerror("Char 0x%02x duplicated", $1); 1836527Sache __collate_char_pri_table[$1].prim = prim_pri; 1846527Sache __collate_char_pri_table[$1].sec = sec_pri++; 1856527Sache} 1866527Sache | CHAR RANGE CHAR { 1876527Sache u_int i; 1886527Sache 1896527Sache if ($3 <= $1) 19018950Sache yyerror("Illegal range 0x%02x -- 0x%02x", 19118950Sache $1, $3); 1926527Sache 1936527Sache for (i = $1; i <= $3; i++) { 19419128Sache if (__collate_char_pri_table[(u_char)i].prim) 19519163Sache yyerror("Char 0x%02x duplicated", (u_char)i); 1966527Sache __collate_char_pri_table[(u_char)i].prim = prim_pri; 1976527Sache __collate_char_pri_table[(u_char)i].sec = sec_pri++; 1986527Sache } 1996527Sache} 2006527Sache | CHAIN { 2016527Sache if (chain_index >= TABLE_SIZE - 1) 2026527Sache yyerror("__collate_chain_pri_table overflow"); 2036527Sache strcpy(__collate_chain_pri_table[chain_index].str, $1); 2046527Sache __collate_chain_pri_table[chain_index].prim = prim_pri; 2056527Sache __collate_chain_pri_table[chain_index++].sec = sec_pri++; 2066527Sache} 2076527Sache; 2086527Sache%% 2096527Sachemain(ac, av) 2106527Sache char **av; 2116527Sache{ 2126527Sache int ch; 2136527Sache 2146527Sache#ifdef COLLATE_DEBUG 21518950Sache while((ch = getopt(ac, av, ":do:I:")) != EOF) { 2166527Sache#else 21718950Sache while((ch = getopt(ac, av, ":o:I:")) != EOF) { 2186527Sache#endif 2196527Sache switch (ch) 2206527Sache { 2216527Sache#ifdef COLLATE_DEBUG 2226527Sache case 'd': 2236527Sache debug++; 2246527Sache break; 2256527Sache#endif 2266527Sache case 'o': 2276527Sache out_file = optarg; 2286527Sache break; 2296527Sache 23018950Sache case 'I': 23118950Sache strcpy(map_name, optarg); 23218950Sache break; 23318950Sache 2346527Sache default: 23518950Sache fprintf(stderr, "Usage: %s [-o out_file] [-I map_dir] [in_file]\n", 2366527Sache av[0]); 2376527Sache exit(EX_OK); 2386527Sache } 2396527Sache } 2406527Sache ac -= optind; 2416527Sache av += optind; 2426527Sache if(ac > 0) { 2436527Sache if((yyin = fopen(*av, "r")) == 0) 2446527Sache err(EX_UNAVAILABLE, "can't open source file %s", *av); 2456527Sache } 2466527Sache for(ch = 0; ch <= UCHAR_MAX; ch++) 2476527Sache __collate_substitute_table[ch][0] = ch; 2486527Sache yyparse(); 2496527Sache return 0; 2506527Sache} 2516527Sache 25218950Sachevoid yyerror(char *fmt, ...) 2536527Sache{ 25418950Sache va_list ap; 25518950Sache char msg[128]; 25618950Sache 25718950Sache va_start(ap, fmt); 25818950Sache vsprintf(msg, fmt, ap); 25918950Sache va_end(ap); 2606527Sache errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 2616527Sache} 26219128Sache 26319128Sache#ifdef COLLATE_DEBUG 26419128Sachecollate_print_tables() 26519128Sache{ 26619128Sache int i; 26719128Sache struct __collate_st_chain_pri *p2; 26819128Sache 26919128Sache printf("Substitute table:\n"); 27019128Sache for (i = 0; i < UCHAR_MAX + 1; i++) 27119128Sache if (i != *__collate_substitute_table[i]) 27219128Sache printf("\t'%c' --> \"%s\"\n", i, 27319128Sache __collate_substitute_table[i]); 27419128Sache printf("Chain priority table:\n"); 27519128Sache for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 27619128Sache printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 27719128Sache printf("Char priority table:\n"); 27819128Sache for (i = 0; i < UCHAR_MAX + 1; i++) 27919128Sache printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 28019128Sache __collate_char_pri_table[i].sec); 28119128Sache} 28219128Sache#endif 283