1 %{ 2 /* 3 * This file and its contents are supplied under the terms of the 4 * Common Development and Distribution License ("CDDL"), version 1.0. 5 * You may only use this file in accordance with the terms of version 6 * 1.0 of the CDDL. 7 * 8 * A full copy of the text of the CDDL should have accompanied this 9 * source. A copy of the CDDL is also available via the Internet at 10 * http://www.illumos.org/license/CDDL. 11 */ 12 13 /* 14 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 15 * Copyright 2013 DEY Storage Systems, Inc. 16 */ 17 18 /* 19 * POSIX localedef grammar. 20 */ 21 22 #include <wchar.h> 23 #include <stdio.h> 24 #include <limits.h> 25 #include "localedef.h" 26 27 %} 28 %union { 29 int num; 30 wchar_t wc; 31 char *token; 32 collsym_t *collsym; 33 collelem_t *collelem; 34 } 35 36 %token T_CODE_SET 37 %token T_MB_CUR_MAX 38 %token T_MB_CUR_MIN 39 %token T_COM_CHAR 40 %token T_ESC_CHAR 41 %token T_LT 42 %token T_GT 43 %token T_NL 44 %token T_SEMI 45 %token T_COMMA 46 %token T_ELLIPSIS 47 %token T_RPAREN 48 %token T_LPAREN 49 %token T_QUOTE 50 %token T_NULL 51 %token T_WS 52 %token T_END 53 %token T_COPY 54 %token T_CHARMAP 55 %token T_WIDTH 56 %token T_CTYPE 57 %token T_ISUPPER 58 %token T_ISLOWER 59 %token T_ISALPHA 60 %token T_ISDIGIT 61 %token T_ISPUNCT 62 %token T_ISXDIGIT 63 %token T_ISSPACE 64 %token T_ISPRINT 65 %token T_ISGRAPH 66 %token T_ISBLANK 67 %token T_ISCNTRL 68 %token T_ISALNUM 69 %token T_ISSPECIAL 70 %token T_ISPHONOGRAM 71 %token T_ISIDEOGRAM 72 %token T_ISENGLISH 73 %token T_ISNUMBER 74 %token T_TOUPPER 75 %token T_TOLOWER 76 %token T_COLLATE 77 %token T_COLLATING_SYMBOL 78 %token T_COLLATING_ELEMENT 79 %token T_ORDER_START 80 %token T_ORDER_END 81 %token T_FORWARD 82 %token T_BACKWARD 83 %token T_POSITION 84 %token T_FROM 85 %token T_UNDEFINED 86 %token T_IGNORE 87 %token T_MESSAGES 88 %token T_YESSTR 89 %token T_NOSTR 90 %token T_YESEXPR 91 %token T_NOEXPR 92 %token T_MONETARY 93 %token T_INT_CURR_SYMBOL 94 %token T_CURRENCY_SYMBOL 95 %token T_MON_DECIMAL_POINT 96 %token T_MON_THOUSANDS_SEP 97 %token T_POSITIVE_SIGN 98 %token T_NEGATIVE_SIGN 99 %token T_MON_GROUPING 100 %token T_INT_FRAC_DIGITS 101 %token T_FRAC_DIGITS 102 %token T_P_CS_PRECEDES 103 %token T_P_SEP_BY_SPACE 104 %token T_N_CS_PRECEDES 105 %token T_N_SEP_BY_SPACE 106 %token T_P_SIGN_POSN 107 %token T_N_SIGN_POSN 108 %token T_INT_P_CS_PRECEDES 109 %token T_INT_N_CS_PRECEDES 110 %token T_INT_P_SEP_BY_SPACE 111 %token T_INT_N_SEP_BY_SPACE 112 %token T_INT_P_SIGN_POSN 113 %token T_INT_N_SIGN_POSN 114 %token T_NUMERIC 115 %token T_DECIMAL_POINT 116 %token T_THOUSANDS_SEP 117 %token T_GROUPING 118 %token T_TIME 119 %token T_ABDAY 120 %token T_DAY 121 %token T_ABMON 122 %token T_MON 123 %token T_ERA 124 %token T_ERA_D_FMT 125 %token T_ERA_T_FMT 126 %token T_ERA_D_T_FMT 127 %token T_ALT_DIGITS 128 %token T_D_T_FMT 129 %token T_D_FMT 130 %token T_T_FMT 131 %token T_AM_PM 132 %token T_T_FMT_AMPM 133 %token T_DATE_FMT 134 %token <wc> T_CHAR 135 %token <token> T_NAME 136 %token <num> T_NUMBER 137 %token <token> T_SYMBOL 138 %token <collsym> T_COLLSYM 139 %token <collelem> T_COLLELEM 140 141 %% 142 143 localedef : setting_list categories 144 | categories 145 ; 146 147 string : T_QUOTE charlist T_QUOTE 148 | T_QUOTE T_QUOTE 149 ; 150 151 charlist : charlist T_CHAR 152 { 153 add_wcs($2); 154 } 155 | T_CHAR 156 { 157 add_wcs($1); 158 } 159 ; 160 161 setting_list : setting_list setting 162 | setting 163 ; 164 165 166 setting : T_COM_CHAR T_CHAR T_NL 167 { 168 com_char = $2; 169 } 170 | T_ESC_CHAR T_CHAR T_NL 171 { 172 esc_char = $2; 173 } 174 | T_MB_CUR_MAX T_NUMBER T_NL 175 { 176 mb_cur_max = $2; 177 } 178 | T_MB_CUR_MIN T_NUMBER T_NL 179 { 180 mb_cur_min = $2; 181 } 182 | T_CODE_SET string T_NL 183 { 184 wchar_t *w = get_wcs(); 185 set_wide_encoding(to_mb_string(w)); 186 free(w); 187 } 188 | T_CODE_SET T_NAME T_NL 189 { 190 set_wide_encoding($2); 191 } 192 ; 193 194 copycat : T_COPY T_NAME T_NL 195 { 196 copy_category($2); 197 } 198 | T_COPY string T_NL 199 { 200 wchar_t *w = get_wcs(); 201 copy_category(to_mb_string(w)); 202 free(w); 203 } 204 ; 205 206 categories : categories category 207 | category 208 ; 209 210 211 category : charmap 212 | messages 213 | monetary 214 | ctype 215 | collate 216 | numeric 217 | time 218 ; 219 220 221 charmap : T_CHARMAP T_NL charmap_list T_END T_CHARMAP T_NL 222 | T_WIDTH T_NL width_list T_END T_WIDTH T_NL 223 ; 224 225 226 charmap_list : charmap_list charmap_entry 227 | charmap_entry 228 ; 229 230 231 charmap_entry : T_SYMBOL T_CHAR 232 { 233 add_charmap($1, $2); 234 scan_to_eol(); 235 } 236 | T_SYMBOL T_ELLIPSIS T_SYMBOL T_CHAR 237 { 238 add_charmap_range($1, $3, $4); 239 scan_to_eol(); 240 } 241 | T_NL 242 ; 243 244 width_list : width_list width_entry 245 | width_entry 246 ; 247 248 width_entry : T_CHAR T_NUMBER T_NL 249 { 250 add_width($1, $2); 251 scan_to_eol(); 252 } 253 | T_SYMBOL T_NUMBER T_NL 254 { 255 add_charmap_undefined($1); 256 scan_to_eol(); 257 } 258 | T_CHAR T_ELLIPSIS T_CHAR T_NUMBER T_NL 259 { 260 add_width_range($1, $3, $4); 261 scan_to_eol(); 262 } 263 | T_SYMBOL T_ELLIPSIS T_SYMBOL T_NUMBER T_NL 264 { 265 add_charmap_undefined($1); 266 add_charmap_undefined($3); 267 scan_to_eol(); 268 } 269 | T_CHAR T_ELLIPSIS T_SYMBOL T_NUMBER T_NL 270 { 271 add_width($1, $4); 272 add_charmap_undefined($3); 273 scan_to_eol(); 274 } 275 | T_SYMBOL T_ELLIPSIS T_CHAR T_NUMBER T_NL 276 { 277 add_width($3, $4); 278 add_charmap_undefined($1); 279 scan_to_eol(); 280 } 281 | T_NL 282 ; 283 284 ctype : T_CTYPE T_NL ctype_list T_END T_CTYPE T_NL 285 { 286 dump_ctype(); 287 } 288 | T_CTYPE T_NL copycat T_END T_CTYPE T_NL 289 ; 290 291 ctype_list : ctype_list ctype_kw 292 | ctype_kw 293 ; 294 295 ctype_kw : T_ISUPPER cc_list T_NL 296 | T_ISLOWER cc_list T_NL 297 | T_ISALPHA cc_list T_NL 298 | T_ISDIGIT cc_list T_NL 299 | T_ISPUNCT cc_list T_NL 300 | T_ISXDIGIT cc_list T_NL 301 | T_ISSPACE cc_list T_NL 302 | T_ISPRINT cc_list T_NL 303 | T_ISGRAPH cc_list T_NL 304 | T_ISBLANK cc_list T_NL 305 | T_ISCNTRL cc_list T_NL 306 | T_ISALNUM cc_list T_NL 307 | T_ISSPECIAL cc_list T_NL 308 | T_ISENGLISH cc_list T_NL 309 | T_ISNUMBER cc_list T_NL 310 | T_ISIDEOGRAM cc_list T_NL 311 | T_ISPHONOGRAM cc_list T_NL 312 | T_TOUPPER conv_list T_NL 313 | T_TOLOWER conv_list T_NL 314 ; 315 316 317 cc_list : cc_list T_SEMI T_CHAR 318 { 319 add_ctype($3); 320 } 321 | cc_list T_SEMI T_SYMBOL 322 { 323 add_charmap_undefined($3); 324 } 325 | cc_list T_SEMI T_ELLIPSIS T_SEMI T_CHAR 326 { 327 /* note that the endpoints *must* be characters */ 328 add_ctype_range($5); 329 } 330 | T_CHAR 331 { 332 add_ctype($1); 333 } 334 | T_SYMBOL 335 { 336 add_charmap_undefined($1); 337 } 338 ; 339 340 conv_list : conv_list T_SEMI conv_pair 341 | conv_pair 342 ; 343 344 345 conv_pair : T_LPAREN T_CHAR T_COMMA T_CHAR T_RPAREN 346 { 347 add_caseconv($2, $4); 348 } 349 | T_LPAREN T_SYMBOL T_COMMA T_CHAR T_RPAREN 350 { 351 add_charmap_undefined($2); 352 } 353 | T_LPAREN T_SYMBOL T_COMMA T_SYMBOL T_RPAREN 354 { 355 add_charmap_undefined($2); 356 add_charmap_undefined($4); 357 } 358 | T_LPAREN T_CHAR T_COMMA T_SYMBOL T_RPAREN 359 { 360 add_charmap_undefined($4); 361 } 362 ; 363 364 collate : T_COLLATE T_NL coll_order T_END T_COLLATE T_NL 365 { 366 dump_collate(); 367 } 368 | T_COLLATE T_NL coll_optional coll_order T_END T_COLLATE T_NL 369 { 370 dump_collate(); 371 } 372 | T_COLLATE T_NL copycat T_END T_COLLATE T_NL 373 ; 374 375 376 coll_optional : coll_optional coll_symbols 377 | coll_optional coll_elements 378 | coll_symbols 379 | coll_elements 380 ; 381 382 383 coll_symbols : T_COLLATING_SYMBOL T_SYMBOL T_NL 384 { 385 define_collsym($2); 386 } 387 ; 388 389 390 coll_elements : T_COLLATING_ELEMENT T_SYMBOL T_FROM string T_NL 391 { 392 define_collelem($2, get_wcs()); 393 } 394 ; 395 396 coll_order : T_ORDER_START T_NL order_list T_ORDER_END T_NL 397 { 398 /* If no order list supplied default to one forward */ 399 add_order_bit(T_FORWARD); 400 add_order_directive(); 401 } 402 | T_ORDER_START order_args T_NL order_list T_ORDER_END T_NL 403 ; 404 405 406 order_args : order_args T_SEMI order_arg 407 { 408 add_order_directive(); 409 } 410 | order_arg 411 { 412 add_order_directive(); 413 } 414 ; 415 416 order_arg : order_arg T_COMMA order_dir 417 | order_dir 418 ; 419 420 order_dir : T_FORWARD 421 { 422 add_order_bit(T_FORWARD); 423 } 424 | T_BACKWARD 425 { 426 add_order_bit(T_BACKWARD); 427 } 428 | T_POSITION 429 { 430 add_order_bit(T_POSITION); 431 } 432 ; 433 434 order_list : order_list order_item 435 | order_item 436 ; 437 438 order_item : T_COLLSYM T_NL 439 { 440 end_order_collsym($1); 441 } 442 | order_itemkw T_NL 443 { 444 end_order(); 445 } 446 | order_itemkw order_weights T_NL 447 { 448 end_order(); 449 } 450 ; 451 452 order_itemkw : T_CHAR 453 { 454 start_order_char($1); 455 } 456 | T_ELLIPSIS 457 { 458 start_order_ellipsis(); 459 } 460 | T_COLLELEM 461 { 462 start_order_collelem($1); 463 } 464 | T_UNDEFINED 465 { 466 start_order_undefined(); 467 } 468 | T_SYMBOL 469 { 470 start_order_symbol($1); 471 } 472 ; 473 474 order_weights : order_weights T_SEMI order_weight 475 | order_weights T_SEMI 476 | order_weight 477 ; 478 479 order_weight : T_COLLELEM 480 { 481 add_order_collelem($1); 482 } 483 | T_COLLSYM 484 { 485 add_order_collsym($1); 486 } 487 | T_CHAR 488 { 489 add_order_char($1); 490 } 491 | T_ELLIPSIS 492 { 493 add_order_ellipsis(); 494 } 495 | T_IGNORE 496 { 497 add_order_ignore(); 498 } 499 | T_SYMBOL 500 { 501 add_order_symbol($1); 502 } 503 | T_QUOTE order_str T_QUOTE 504 { 505 add_order_subst(); 506 } 507 ; 508 509 order_str : order_str order_stritem 510 | order_stritem 511 ; 512 513 order_stritem : T_CHAR 514 { 515 add_subst_char($1); 516 } 517 | T_COLLSYM 518 { 519 add_subst_collsym($1); 520 } 521 | T_COLLELEM 522 { 523 add_subst_collelem($1); 524 } 525 | T_SYMBOL 526 { 527 add_subst_symbol($1); 528 } 529 ; 530 531 messages : T_MESSAGES T_NL messages_list T_END T_MESSAGES T_NL 532 { 533 dump_messages(); 534 } 535 | T_MESSAGES T_NL copycat T_END T_MESSAGES T_NL 536 ; 537 538 messages_list : messages_list messages_item 539 | messages_item 540 ; 541 542 messages_kw : T_YESSTR 543 | T_NOSTR 544 | T_YESEXPR 545 | T_NOEXPR 546 ; 547 548 messages_item : messages_kw string T_NL 549 { 550 add_message(get_wcs()); 551 } 552 ; 553 554 monetary : T_MONETARY T_NL monetary_list T_END T_MONETARY T_NL 555 { 556 dump_monetary(); 557 } 558 | T_MONETARY T_NL copycat T_END T_MONETARY T_NL 559 ; 560 561 monetary_list : monetary_list monetary_kw 562 | monetary_kw 563 ; 564 565 monetary_strkw : T_INT_CURR_SYMBOL 566 | T_CURRENCY_SYMBOL 567 | T_MON_DECIMAL_POINT 568 | T_MON_THOUSANDS_SEP 569 | T_POSITIVE_SIGN 570 | T_NEGATIVE_SIGN 571 ; 572 573 monetary_numkw : T_INT_FRAC_DIGITS 574 | T_FRAC_DIGITS 575 | T_P_CS_PRECEDES 576 | T_P_SEP_BY_SPACE 577 | T_N_CS_PRECEDES 578 | T_N_SEP_BY_SPACE 579 | T_P_SIGN_POSN 580 | T_N_SIGN_POSN 581 | T_INT_P_CS_PRECEDES 582 | T_INT_N_CS_PRECEDES 583 | T_INT_P_SEP_BY_SPACE 584 | T_INT_N_SEP_BY_SPACE 585 | T_INT_P_SIGN_POSN 586 | T_INT_N_SIGN_POSN 587 ; 588 589 monetary_kw : monetary_strkw string T_NL 590 { 591 add_monetary_str(get_wcs()); 592 } 593 | monetary_numkw T_NUMBER T_NL 594 { 595 add_monetary_num($2); 596 } 597 | T_MON_GROUPING mon_group_list T_NL 598 ; 599 600 mon_group_list : T_NUMBER 601 { 602 reset_monetary_group(); 603 add_monetary_group($1); 604 } 605 | mon_group_list T_SEMI T_NUMBER 606 { 607 add_monetary_group($3); 608 } 609 ; 610 611 612 numeric : T_NUMERIC T_NL numeric_list T_END T_NUMERIC T_NL 613 { 614 dump_numeric(); 615 } 616 | T_NUMERIC T_NL copycat T_END T_NUMERIC T_NL 617 ; 618 619 620 numeric_list : numeric_list numeric_item 621 | numeric_item 622 ; 623 624 625 numeric_item : numeric_strkw string T_NL 626 { 627 add_numeric_str(get_wcs()); 628 } 629 | T_GROUPING group_list T_NL 630 ; 631 632 numeric_strkw : T_DECIMAL_POINT 633 | T_THOUSANDS_SEP 634 ; 635 636 637 group_list : T_NUMBER 638 { 639 reset_numeric_group(); 640 add_numeric_group($1); 641 } 642 | group_list T_SEMI T_NUMBER 643 { 644 add_numeric_group($3); 645 } 646 ; 647 648 649 time : T_TIME T_NL time_kwlist T_END T_TIME T_NL 650 { 651 dump_time(); 652 } 653 | T_TIME T_NL copycat T_END T_NUMERIC T_NL 654 ; 655 656 time_kwlist : time_kwlist time_kw 657 | time_kw 658 ; 659 660 time_kw : time_strkw string T_NL 661 { 662 add_time_str(get_wcs()); 663 } 664 | time_listkw time_list T_NL 665 { 666 check_time_list(); 667 } 668 ; 669 670 time_listkw : T_ABDAY 671 | T_DAY 672 | T_ABMON 673 | T_MON 674 | T_ERA 675 | T_ALT_DIGITS 676 | T_AM_PM 677 ; 678 679 time_strkw : T_ERA_D_T_FMT 680 | T_ERA_T_FMT 681 | T_ERA_D_FMT 682 | T_D_T_FMT 683 | T_D_FMT 684 | T_T_FMT 685 | T_T_FMT_AMPM 686 | T_DATE_FMT 687 ; 688 689 time_list : time_list T_SEMI string 690 { 691 add_time_list(get_wcs()); 692 } 693 | string 694 { 695 reset_time_list(); 696 add_time_list(get_wcs()); 697 } 698 ; 699