parse.y revision 69194
189099Sfjoe%{ 289099Sfjoe/*- 389099Sfjoe * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 489099Sfjoe * at Electronni Visti IA, Kiev, Ukraine. 589099Sfjoe * All rights reserved. 689099Sfjoe * 789099Sfjoe * Redistribution and use in source and binary forms, with or without 889099Sfjoe * modification, are permitted provided that the following conditions 989099Sfjoe * are met: 1089099Sfjoe * 1. Redistributions of source code must retain the above copyright 1189099Sfjoe * notice, this list of conditions and the following disclaimer. 1289099Sfjoe * 2. Redistributions in binary form must reproduce the above copyright 1389099Sfjoe * notice, this list of conditions and the following disclaimer in the 1489099Sfjoe * documentation and/or other materials provided with the distribution. 1589099Sfjoe * 1689099Sfjoe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 1789099Sfjoe * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1889099Sfjoe * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1989099Sfjoe * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 2089099Sfjoe * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2189099Sfjoe * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2289099Sfjoe * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2389099Sfjoe * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2489099Sfjoe * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2589099Sfjoe * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2689099Sfjoe * SUCH DAMAGE. 2789099Sfjoe * 2889099Sfjoe * $FreeBSD: head/usr.bin/colldef/parse.y 69194 2000-11-26 08:14:55Z kris $ 2989099Sfjoe */ 3089099Sfjoe 3189099Sfjoe#include <err.h> 3289099Sfjoe#include <stdarg.h> 3389099Sfjoe#include <stdio.h> 3489099Sfjoe#include <string.h> 3589099Sfjoe#include <stdlib.h> 3689099Sfjoe#include <unistd.h> 3789099Sfjoe#include <sysexits.h> 3889099Sfjoe#include "collate.h" 3989099Sfjoe 4089099Sfjoeextern int line_no; 4189099Sfjoeextern FILE *yyin; 4289099Sfjoevoid yyerror(char *fmt, ...); 43109771Sfjoeint yyparse(void); 4489099Sfjoeint yylex(void); 4589099Sfjoestatic void usage __P((void)); 4689099Sfjoe 4789099Sfjoechar map_name[FILENAME_MAX] = "."; 48129880Sphk 4989099Sfjoechar __collate_version[STR_LEN]; 5089099Sfjoeu_char charmap_table[UCHAR_MAX + 1][STR_LEN]; 5189099Sfjoeu_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 5289099Sfjoestruct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 5389099Sfjoestruct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 5489099Sfjoeint chain_index; 5589099Sfjoeint prim_pri = 1, sec_pri = 1; 5689099Sfjoe#ifdef COLLATE_DEBUG 5789099Sfjoeint debug; 5889099Sfjoe#endif 5989099Sfjoe 6089099Sfjoechar *out_file = "LC_COLLATE"; 6189099Sfjoe%} 6289099Sfjoe%union { 6389099Sfjoe u_char ch; 6489099Sfjoe u_char str[STR_LEN]; 6589099Sfjoe} 6689099Sfjoe%token SUBSTITUTE WITH ORDER RANGE 6789099Sfjoe%token <str> STRING 6889099Sfjoe%token <str> CHAIN 6989099Sfjoe%token <str> DEFN 7089099Sfjoe%token <ch> CHAR 7189099Sfjoe%% 7289099Sfjoecollate : statment_list 7389099Sfjoe; 7489099Sfjoestatment_list : statment 7589099Sfjoe | statment_list '\n' statment 7689099Sfjoe; 7789099Sfjoestatment : 78109771Sfjoe | charmap 79109771Sfjoe | substitute 80109771Sfjoe | order 81109771Sfjoe; 82109771Sfjoecharmap : DEFN CHAR { 8389099Sfjoe strcpy(charmap_table[$2], $1); 8489099Sfjoe} 8589099Sfjoe; 8689099Sfjoesubstitute : SUBSTITUTE CHAR WITH STRING { 8792725Salfred if ($2 == '\0') 88109771Sfjoe yyerror("NUL character can't be substituted"); 89109771Sfjoe if (strchr($4, $2) != NULL) 9089099Sfjoe yyerror("Char 0x%02x substitution is recursive", $2); 9189099Sfjoe strcpy(__collate_substitute_table[$2], $4); 9289099Sfjoe} 93110106Sfjoe; 94110106Sfjoeorder : ORDER order_list { 9589099Sfjoe FILE *fp; 96109771Sfjoe int ch, substed, ordered; 97109771Sfjoe 9889099Sfjoe for (ch = 0; ch < UCHAR_MAX + 1; ch++) { 9989099Sfjoe substed = (__collate_substitute_table[ch][0] != ch); 10089099Sfjoe ordered = !!__collate_char_pri_table[ch].prim; 10189099Sfjoe if (!ordered && !substed) 10289099Sfjoe yyerror("Char 0x%02x not found", ch); 10389099Sfjoe if (substed && ordered) 10489099Sfjoe yyerror("Char 0x%02x can't be ordered since substituted", ch); 10589099Sfjoe } 10689099Sfjoe 10789099Sfjoe fp = fopen(out_file, "w"); 10889099Sfjoe if(!fp) 10989099Sfjoe err(EX_UNAVAILABLE, "can't open destination file %s", 11089099Sfjoe out_file); 11189099Sfjoe 11289099Sfjoe strcpy(__collate_version, COLLATE_VERSION); 11389099Sfjoe fwrite(__collate_version, sizeof(__collate_version), 1, fp); 114109771Sfjoe fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 115110106Sfjoe fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 11689099Sfjoe fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 11789099Sfjoe if (fflush(fp)) 11889099Sfjoe err(EX_UNAVAILABLE, "IO error writting to destination file %s", 11989099Sfjoe out_file); 12089099Sfjoe fclose(fp); 12189099Sfjoe#ifdef COLLATE_DEBUG 12289099Sfjoe if (debug) 12389099Sfjoe collate_print_tables(); 12489099Sfjoe#endif 12589099Sfjoe exit(EX_OK); 12689099Sfjoe} 12789099Sfjoe; 12889099Sfjoeorder_list : item 12989099Sfjoe | order_list ';' item 13089099Sfjoe; 13189099Sfjoeitem : CHAR { 13289099Sfjoe if (__collate_char_pri_table[$1].prim) 133128636Sluigi yyerror("Char 0x%02x duplicated", $1); 134128636Sluigi __collate_char_pri_table[$1].prim = prim_pri++; 135128636Sluigi} 136128636Sluigi | CHAIN { 137128636Sluigi if (chain_index >= TABLE_SIZE - 1) 13889099Sfjoe yyerror("__collate_chain_pri_table overflow"); 13989099Sfjoe strcpy(__collate_chain_pri_table[chain_index].str, $1); 14089099Sfjoe __collate_chain_pri_table[chain_index++].prim = prim_pri++; 14189099Sfjoe} 142127260Smdodd | CHAR RANGE CHAR { 143127260Smdodd u_int i; 144127260Smdodd 145127260Smdodd if ($3 <= $1) 146127260Smdodd yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 147127260Smdodd 148127260Smdodd for (i = $1; i <= $3; i++) { 149127260Smdodd if (__collate_char_pri_table[(u_char)i].prim) 150127260Smdodd yyerror("Char 0x%02x duplicated", (u_char)i); 151127260Smdodd __collate_char_pri_table[(u_char)i].prim = prim_pri++; 152127260Smdodd } 153127275Smdodd} 154127260Smdodd | '{' prim_order_list '}' { 155127260Smdodd prim_pri++; 156127260Smdodd} 157127260Smdodd | '(' sec_order_list ')' { 158127275Smdodd prim_pri++; 159127260Smdodd sec_pri = 1; 160127260Smdodd} 161127260Smdodd; 162127260Smdoddprim_order_list : prim_sub_item 163127290Smdodd | prim_order_list ',' prim_sub_item 164127260Smdodd; 165127290Smdoddsec_order_list : sec_sub_item 166127260Smdodd | sec_order_list ',' sec_sub_item 167127260Smdodd; 168127260Smdoddprim_sub_item : CHAR { 16989099Sfjoe if (__collate_char_pri_table[$1].prim) 17089099Sfjoe yyerror("Char 0x%02x duplicated", $1); 17189099Sfjoe __collate_char_pri_table[$1].prim = prim_pri; 172128636Sluigi} 173128636Sluigi | CHAR RANGE CHAR { 174128636Sluigi u_int i; 17589099Sfjoe 17689099Sfjoe if ($3 <= $1) 17789099Sfjoe yyerror("Illegal range 0x%02x -- 0x%02x", 178109771Sfjoe $1, $3); 179109771Sfjoe 180109771Sfjoe for (i = $1; i <= $3; i++) { 181109771Sfjoe if (__collate_char_pri_table[(u_char)i].prim) 182109771Sfjoe yyerror("Char 0x%02x duplicated", (u_char)i); 183109771Sfjoe __collate_char_pri_table[(u_char)i].prim = prim_pri; 184109771Sfjoe } 185109771Sfjoe} 18689099Sfjoe | CHAIN { 18789099Sfjoe if (chain_index >= TABLE_SIZE - 1) 188109771Sfjoe yyerror("__collate_chain_pri_table overflow"); 18989099Sfjoe strcpy(__collate_chain_pri_table[chain_index].str, $1); 19089099Sfjoe __collate_chain_pri_table[chain_index++].prim = prim_pri; 19189099Sfjoe} 19289099Sfjoe; 19389099Sfjoesec_sub_item : CHAR { 19489099Sfjoe if (__collate_char_pri_table[$1].prim) 19589099Sfjoe yyerror("Char 0x%02x duplicated", $1); 19689099Sfjoe __collate_char_pri_table[$1].prim = prim_pri; 19789099Sfjoe __collate_char_pri_table[$1].sec = sec_pri++; 19889099Sfjoe} 19989099Sfjoe | CHAR RANGE CHAR { 20089099Sfjoe u_int i; 20189099Sfjoe 20289099Sfjoe if ($3 <= $1) 20389099Sfjoe yyerror("Illegal range 0x%02x -- 0x%02x", 20489099Sfjoe $1, $3); 205109771Sfjoe 20689099Sfjoe for (i = $1; i <= $3; i++) { 20789099Sfjoe if (__collate_char_pri_table[(u_char)i].prim) 20889099Sfjoe yyerror("Char 0x%02x duplicated", (u_char)i); 20989099Sfjoe __collate_char_pri_table[(u_char)i].prim = prim_pri; 21089099Sfjoe __collate_char_pri_table[(u_char)i].sec = sec_pri++; 211105598Sbrooks } 21289099Sfjoe} 21389099Sfjoe | CHAIN { 21489099Sfjoe if (chain_index >= TABLE_SIZE - 1) 215110106Sfjoe yyerror("__collate_chain_pri_table overflow"); 216111119Simp strcpy(__collate_chain_pri_table[chain_index].str, $1); 21789099Sfjoe __collate_chain_pri_table[chain_index].prim = prim_pri; 21889099Sfjoe __collate_chain_pri_table[chain_index++].sec = sec_pri++; 21989099Sfjoe} 22089099Sfjoe; 22189099Sfjoe%% 222110106Sfjoeint 223110106Sfjoemain(ac, av) 224110106Sfjoe char **av; 225110106Sfjoe{ 226110106Sfjoe int ch; 22789099Sfjoe 228109771Sfjoe#ifdef COLLATE_DEBUG 229109771Sfjoe while((ch = getopt(ac, av, ":do:I:")) != EOF) { 230109771Sfjoe#else 231109771Sfjoe while((ch = getopt(ac, av, ":o:I:")) != EOF) { 232109771Sfjoe#endif 233109771Sfjoe switch (ch) 234109771Sfjoe { 235109771Sfjoe#ifdef COLLATE_DEBUG 236109771Sfjoe case 'd': 237109771Sfjoe debug++; 238109771Sfjoe break; 239106939Ssam#endif 24089099Sfjoe case 'o': 241130549Smlaier out_file = optarg; 24289099Sfjoe break; 24389099Sfjoe 24489099Sfjoe case 'I': 24589099Sfjoe strcpy(map_name, optarg); 24689099Sfjoe break; 24789099Sfjoe 24889099Sfjoe default: 24989099Sfjoe usage(); 25089099Sfjoe } 25189099Sfjoe } 25289099Sfjoe ac -= optind; 25389099Sfjoe av += optind; 25489099Sfjoe if(ac > 0) { 25589099Sfjoe if((yyin = fopen(*av, "r")) == 0) 25689099Sfjoe err(EX_UNAVAILABLE, "can't open source file %s", *av); 25789099Sfjoe } 25889099Sfjoe for(ch = 0; ch <= UCHAR_MAX; ch++) 25989099Sfjoe __collate_substitute_table[ch][0] = ch; 26089099Sfjoe yyparse(); 26189099Sfjoe return 0; 26289099Sfjoe} 26389099Sfjoe 26489099Sfjoestatic void 26589099Sfjoeusage() 26689099Sfjoe{ 26789099Sfjoe fprintf(stderr, "usage: colldef [-o out_file] [-I map_dir] [filename]\n"); 26889099Sfjoe exit(EX_USAGE); 26989099Sfjoe} 27089099Sfjoe 27189099Sfjoevoid yyerror(char *fmt, ...) 27289099Sfjoe{ 27389099Sfjoe va_list ap; 27489099Sfjoe char msg[128]; 27589099Sfjoe 27689099Sfjoe va_start(ap, fmt); 27789099Sfjoe vsnprintf(msg, sizeof(msg), fmt, ap); 27889099Sfjoe va_end(ap); 27989099Sfjoe errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 28089099Sfjoe} 28189099Sfjoe 28289099Sfjoe#ifdef COLLATE_DEBUG 283109771Sfjoevoid 28489099Sfjoecollate_print_tables() 28589099Sfjoe{ 28689099Sfjoe int i; 28789099Sfjoe struct __collate_st_chain_pri *p2; 28889099Sfjoe 28989099Sfjoe printf("Substitute table:\n"); 29089099Sfjoe for (i = 0; i < UCHAR_MAX + 1; i++) 291110106Sfjoe if (i != *__collate_substitute_table[i]) 29289099Sfjoe printf("\t'%c' --> \"%s\"\n", i, 29389099Sfjoe __collate_substitute_table[i]); 29489099Sfjoe printf("Chain priority table:\n"); 29589099Sfjoe for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 29689099Sfjoe printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 29789099Sfjoe printf("Char priority table:\n"); 298111119Simp for (i = 0; i < UCHAR_MAX + 1; i++) 29989099Sfjoe printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 30093750Sluigi __collate_char_pri_table[i].sec); 30189099Sfjoe} 30289099Sfjoe#endif 30389099Sfjoe