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