xref: /illumos-gate/usr/src/cmd/localedef/parser.y (revision 2da1cd3a39e2d3da7f9d15071ea9462919c011ac)
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