xref: /illumos-gate/usr/src/cmd/localedef/parser.y (revision f83b46baf98d276f5f84fa84c8b461f412ac1f5e)
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 		}
252 		| T_SYMBOL T_NUMBER T_NL
253 		{
254 			add_charmap_undefined($1);
255 		}
256 		| T_CHAR T_ELLIPSIS T_CHAR T_NUMBER T_NL
257 		{
258 			add_width_range($1, $3, $4);
259 		}
260 		| T_SYMBOL T_ELLIPSIS T_SYMBOL T_NUMBER T_NL
261 		{
262 			add_charmap_undefined($1);
263 			add_charmap_undefined($3);
264 		}
265 		| T_CHAR T_ELLIPSIS T_SYMBOL T_NUMBER T_NL
266 		{
267 			add_width($1, $4);
268 			add_charmap_undefined($3);
269 		}
270 		| T_SYMBOL T_ELLIPSIS T_CHAR T_NUMBER T_NL
271 		{
272 			add_width($3, $4);
273 			add_charmap_undefined($1);
274 		}
275 		| T_NL
276 		;
277 
278 ctype		: T_CTYPE T_NL ctype_list T_END T_CTYPE T_NL
279 		{
280 			dump_ctype();
281 		}
282 		| T_CTYPE T_NL copycat  T_END T_CTYPE T_NL
283 		;
284 
285 ctype_list	: ctype_list ctype_kw
286 		| ctype_kw
287 		;
288 
289 ctype_kw	: T_ISUPPER cc_list T_NL
290 		| T_ISLOWER cc_list T_NL
291 		| T_ISALPHA cc_list T_NL
292 		| T_ISDIGIT cc_list T_NL
293 		| T_ISPUNCT cc_list T_NL
294 		| T_ISXDIGIT cc_list T_NL
295 		| T_ISSPACE cc_list T_NL
296 		| T_ISPRINT cc_list T_NL
297 		| T_ISGRAPH cc_list T_NL
298 		| T_ISBLANK cc_list T_NL
299 		| T_ISCNTRL cc_list T_NL
300 		| T_ISALNUM cc_list T_NL
301 		| T_ISSPECIAL cc_list T_NL
302 		| T_ISENGLISH cc_list T_NL
303 		| T_ISNUMBER cc_list T_NL
304 		| T_ISIDEOGRAM cc_list T_NL
305 		| T_ISPHONOGRAM cc_list T_NL
306 		| T_TOUPPER conv_list T_NL
307 		| T_TOLOWER conv_list T_NL
308 		;
309 
310 
311 cc_list		: cc_list T_SEMI T_CHAR
312 		{
313 			add_ctype($3);
314 		}
315 		| cc_list T_SEMI T_SYMBOL
316 		{
317 			add_charmap_undefined($3);
318 		}
319 		| cc_list T_SEMI T_ELLIPSIS T_SEMI T_CHAR
320 		{
321 			/* note that the endpoints *must* be characters */
322 			add_ctype_range($5);
323 		}
324 		| T_CHAR
325 		{
326 			add_ctype($1);
327 		}
328 		| T_SYMBOL
329 		{
330 			add_charmap_undefined($1);
331 		}
332 		;
333 
334 conv_list	: conv_list T_SEMI conv_pair
335 		| conv_pair
336 		;
337 
338 
339 conv_pair	: T_LPAREN T_CHAR T_COMMA T_CHAR T_RPAREN
340 		{
341 			add_caseconv($2, $4);
342 		}
343 		| T_LPAREN T_SYMBOL T_COMMA T_CHAR T_RPAREN
344 		{
345 			add_charmap_undefined($2);
346 		}
347 		| T_LPAREN T_SYMBOL T_COMMA T_SYMBOL T_RPAREN
348 		{
349 			add_charmap_undefined($2);
350 			add_charmap_undefined($4);
351 		}
352 		| T_LPAREN T_CHAR T_COMMA T_SYMBOL T_RPAREN
353 		{
354 			add_charmap_undefined($4);
355 		}
356 		;
357 
358 collate		: T_COLLATE T_NL coll_order T_END T_COLLATE T_NL
359 		{
360 			dump_collate();
361 		}
362 		| T_COLLATE T_NL coll_optional coll_order T_END T_COLLATE T_NL
363 		{
364 			dump_collate();
365 		}
366 		| T_COLLATE T_NL copycat T_END T_COLLATE T_NL
367 		;
368 
369 
370 coll_optional	: coll_optional coll_symbols
371 		| coll_optional coll_elements
372 		| coll_symbols
373 		| coll_elements
374 		;
375 
376 
377 coll_symbols	: T_COLLATING_SYMBOL T_SYMBOL T_NL
378 		{
379 			define_collsym($2);
380 		}
381 		;
382 
383 
384 coll_elements	: T_COLLATING_ELEMENT T_SYMBOL T_FROM string T_NL
385 		{
386 			define_collelem($2, get_wcs());
387 		}
388 		;
389 
390 coll_order	: T_ORDER_START T_NL order_list T_ORDER_END T_NL
391 		{
392 			/* If no order list supplied default to one forward */
393 			add_order_bit(T_FORWARD);
394 			add_order_directive();
395 		}
396 		| T_ORDER_START order_args T_NL order_list T_ORDER_END T_NL
397 		;
398 
399 
400 order_args	: order_args T_SEMI order_arg
401 		{
402 			add_order_directive();
403 		}
404 		| order_arg
405 		{
406 			add_order_directive();
407 		}
408 		;
409 
410 order_arg	: order_arg T_COMMA order_dir
411 		| order_dir
412 		;
413 
414 order_dir	: T_FORWARD
415 		{
416 			add_order_bit(T_FORWARD);
417 		}
418 		| T_BACKWARD
419 		{
420 			add_order_bit(T_BACKWARD);
421 		}
422 		| T_POSITION
423 		{
424 			add_order_bit(T_POSITION);
425 		}
426 		;
427 
428 order_list	: order_list order_item
429 		| order_item
430 		;
431 
432 order_item	: T_COLLSYM T_NL
433 		{
434 			end_order_collsym($1);
435 		}
436 		| order_itemkw T_NL
437 		{
438 			end_order();
439 		}
440 		| order_itemkw order_weights T_NL
441 		{
442 			end_order();
443 		}
444 		;
445 
446 order_itemkw	: T_CHAR
447 		{
448 			start_order_char($1);
449 		}
450 		| T_ELLIPSIS
451 		{
452 			start_order_ellipsis();
453 		}
454 		| T_COLLELEM
455 		{
456 			start_order_collelem($1);
457 		}
458 		| T_UNDEFINED
459 		{
460 			start_order_undefined();
461 		}
462 		| T_SYMBOL
463 		{
464 			start_order_symbol($1);
465 		}
466 		;
467 
468 order_weights	: order_weights T_SEMI order_weight
469 		| order_weights T_SEMI
470 		| order_weight
471 		;
472 
473 order_weight	: T_COLLELEM
474 		{
475 			add_order_collelem($1);
476 		}
477 		| T_COLLSYM
478 		{
479 			add_order_collsym($1);
480 		}
481 		| T_CHAR
482 		{
483 			add_order_char($1);
484 		}
485 		| T_ELLIPSIS
486 		{
487 			add_order_ellipsis();
488 		}
489 		| T_IGNORE
490 		{
491 			add_order_ignore();
492 		}
493 		| T_SYMBOL
494 		{
495 			add_order_symbol($1);
496 		}
497 		| T_QUOTE order_str T_QUOTE
498 		{
499 			add_order_subst();
500 		}
501 		;
502 
503 order_str	: order_str order_stritem
504 		| order_stritem
505 		;
506 
507 order_stritem	: T_CHAR
508 		{
509 			add_subst_char($1);
510 		}
511 		| T_COLLSYM
512 		{
513 			add_subst_collsym($1);
514 		}
515 		| T_COLLELEM
516 		{
517 			add_subst_collelem($1);
518 		}
519 		| T_SYMBOL
520 		{
521 			add_subst_symbol($1);
522 		}
523 		;
524 
525 messages	: T_MESSAGES T_NL messages_list T_END T_MESSAGES T_NL
526 		{
527 			dump_messages();
528 		}
529 		| T_MESSAGES T_NL copycat T_END T_MESSAGES T_NL
530 		;
531 
532 messages_list	: messages_list messages_item
533 		| messages_item
534 		;
535 
536 messages_kw	: T_YESSTR
537 		| T_NOSTR
538 		| T_YESEXPR
539 		| T_NOEXPR
540 		;
541 
542 messages_item	: messages_kw string T_NL
543 		{
544 			add_message(get_wcs());
545 		}
546 		;
547 
548 monetary	: T_MONETARY T_NL monetary_list T_END T_MONETARY T_NL
549 		{
550 			dump_monetary();
551 		}
552 		| T_MONETARY T_NL copycat T_END T_MONETARY T_NL
553 		;
554 
555 monetary_list	: monetary_list monetary_kw
556 		| monetary_kw
557 		;
558 
559 monetary_strkw	: T_INT_CURR_SYMBOL
560 		| T_CURRENCY_SYMBOL
561 		| T_MON_DECIMAL_POINT
562 		| T_MON_THOUSANDS_SEP
563 		| T_POSITIVE_SIGN
564 		| T_NEGATIVE_SIGN
565 		;
566 
567 monetary_numkw	: T_INT_FRAC_DIGITS
568 		| T_FRAC_DIGITS
569 		| T_P_CS_PRECEDES
570 		| T_P_SEP_BY_SPACE
571 		| T_N_CS_PRECEDES
572 		| T_N_SEP_BY_SPACE
573 		| T_P_SIGN_POSN
574 		| T_N_SIGN_POSN
575 		| T_INT_P_CS_PRECEDES
576 		| T_INT_N_CS_PRECEDES
577 		| T_INT_P_SEP_BY_SPACE
578 		| T_INT_N_SEP_BY_SPACE
579 		| T_INT_P_SIGN_POSN
580 		| T_INT_N_SIGN_POSN
581 		;
582 
583 monetary_kw	: monetary_strkw string T_NL
584 		{
585 			add_monetary_str(get_wcs());
586 		}
587 		| monetary_numkw T_NUMBER T_NL
588 		{
589 			add_monetary_num($2);
590 		}
591 		| T_MON_GROUPING mon_group_list T_NL
592 		;
593 
594 mon_group_list	: T_NUMBER
595 		{
596 			reset_monetary_group();
597 			add_monetary_group($1);
598 		}
599 		| mon_group_list T_SEMI T_NUMBER
600 		{
601 			add_monetary_group($3);
602 		}
603 		;
604 
605 
606 numeric		: T_NUMERIC T_NL numeric_list T_END T_NUMERIC T_NL
607 		{
608 			dump_numeric();
609 		}
610 		| T_NUMERIC T_NL copycat T_END T_NUMERIC T_NL
611 		;
612 
613 
614 numeric_list	: numeric_list numeric_item
615 		| numeric_item
616 		;
617 
618 
619 numeric_item	: numeric_strkw string T_NL
620 		{
621 			add_numeric_str(get_wcs());
622 		}
623 		| T_GROUPING group_list T_NL
624 		;
625 
626 numeric_strkw	: T_DECIMAL_POINT
627 		| T_THOUSANDS_SEP
628 		;
629 
630 
631 group_list	: T_NUMBER
632 		{
633 			reset_numeric_group();
634 			add_numeric_group($1);
635 		}
636 		| group_list T_SEMI T_NUMBER
637 		{
638 			add_numeric_group($3);
639 		}
640 		;
641 
642 
643 time		: T_TIME T_NL time_kwlist T_END T_TIME T_NL
644 		{
645 			dump_time();
646 		}
647 		| T_TIME T_NL copycat T_END T_NUMERIC T_NL
648 		;
649 
650 time_kwlist	: time_kwlist time_kw
651 		| time_kw
652 		;
653 
654 time_kw		: time_strkw string T_NL
655 		{
656 			add_time_str(get_wcs());
657 		}
658 		| time_listkw time_list T_NL
659 		{
660 			check_time_list();
661 		}
662 		;
663 
664 time_listkw	: T_ABDAY
665 		| T_DAY
666 		| T_ABMON
667 		| T_MON
668 		| T_ERA
669 		| T_ALT_DIGITS
670 		| T_AM_PM
671 		;
672 
673 time_strkw	: T_ERA_D_T_FMT
674 		| T_ERA_T_FMT
675 		| T_ERA_D_FMT
676 		| T_D_T_FMT
677 		| T_D_FMT
678 		| T_T_FMT
679 		| T_T_FMT_AMPM
680 		| T_DATE_FMT
681 		;
682 
683 time_list	: time_list T_SEMI string
684 		{
685 			add_time_list(get_wcs());
686 		}
687 		| string
688 		{
689 			reset_time_list();
690 			add_time_list(get_wcs());
691 		}
692 		;
693