kbproto untanglement: XkbKeyNameLength
[platform/upstream/libxkbcommon.git] / src / xkbcomp / parser.y
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 %{
28 #include "xkbcomp-priv.h"
29 #include "ast-build.h"
30 #include "parser-priv.h"
31
32 static void
33 yyerror(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
34 {
35     scanner_error(loc, param->scanner, msg);
36 }
37
38 #define scanner param->scanner
39 %}
40
41 %define         api.pure
42 %locations
43 %lex-param      { void *scanner }
44 %parse-param    { struct parser_param *param }
45
46 %token
47         END_OF_FILE     0
48         ERROR_TOK       255
49         XKB_KEYMAP      1
50         XKB_KEYCODES    2
51         XKB_TYPES       3
52         XKB_SYMBOLS     4
53         XKB_COMPATMAP   5
54         XKB_GEOMETRY    6
55         XKB_SEMANTICS   7
56         XKB_LAYOUT      8
57         INCLUDE         10
58         OVERRIDE        11
59         AUGMENT         12
60         REPLACE         13
61         ALTERNATE       14
62         VIRTUAL_MODS    20
63         TYPE            21
64         INTERPRET       22
65         ACTION_TOK      23
66         KEY             24
67         ALIAS           25
68         GROUP           26
69         MODIFIER_MAP    27
70         INDICATOR       28
71         SHAPE           29
72         KEYS            30
73         ROW             31
74         SECTION         32
75         OVERLAY         33
76         TEXT            34
77         OUTLINE         35
78         SOLID           36
79         LOGO            37
80         VIRTUAL         38
81         EQUALS          40
82         PLUS            41
83         MINUS           42
84         DIVIDE          43
85         TIMES           44
86         OBRACE          45
87         CBRACE          46
88         OPAREN          47
89         CPAREN          48
90         OBRACKET        49
91         CBRACKET        50
92         DOT             51
93         COMMA           52
94         SEMI            53
95         EXCLAM          54
96         INVERT          55
97         STRING          60
98         INTEGER         61
99         FLOAT           62
100         IDENT           63
101         KEYNAME         64
102         PARTIAL         70
103         DEFAULT         71
104         HIDDEN          72
105         ALPHANUMERIC_KEYS       73
106         MODIFIER_KEYS           74
107         KEYPAD_KEYS             75
108         FUNCTION_KEYS           76
109         ALTERNATE_GROUP         77
110
111 %right  EQUALS
112 %left   PLUS MINUS
113 %left   TIMES DIVIDE
114 %left   EXCLAM INVERT
115 %left   OPAREN
116
117 %start  XkbFile
118
119 %union  {
120         int              ival;
121         unsigned         uval;
122         int64_t          num;
123         enum xkb_file_type file_type;
124         char            *str;
125         char            keyName[XKB_KEY_NAME_LENGTH];
126         xkb_atom_t      sval;
127         enum merge_mode merge;
128         ParseCommon     *any;
129         ExprDef         *expr;
130         VarDef          *var;
131         VModDef         *vmod;
132         InterpDef       *interp;
133         KeyTypeDef      *keyType;
134         SymbolsDef      *syms;
135         ModMapDef       *modMask;
136         GroupCompatDef  *groupCompat;
137         IndicatorMapDef *ledMap;
138         IndicatorNameDef *ledName;
139         KeycodeDef      *keyCode;
140         KeyAliasDef     *keyAlias;
141         void            *geom;
142         XkbFile         *file;
143 }
144
145 %type <num>     INTEGER FLOAT
146 %type <str>     IDENT STRING
147 %type <keyName> KEYNAME KeyName
148 %type <ival>    Number Integer Float SignedNumber
149 %type <merge>   MergeMode OptMergeMode
150 %type <file_type> XkbCompositeType FileType
151 %type <uval>    DoodadType Flag Flags OptFlags KeyCode
152 %type <str>     MapName OptMapName KeySym
153 %type <sval>    FieldSpec Ident Element String
154 %type <any>     DeclList Decl
155 %type <expr>    OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms
156 %type <expr>    OptKeySymList KeySymList Action ActionList Coord CoordList
157 %type <var>     VarDecl VarDeclList SymbolsBody SymbolsVarDecl
158 %type <vmod>    VModDecl VModDefList VModDef
159 %type <interp>  InterpretDecl InterpretMatch
160 %type <keyType> KeyTypeDecl
161 %type <syms>    SymbolsDecl
162 %type <modMask> ModMapDecl
163 %type <groupCompat> GroupCompatDecl
164 %type <ledMap>  IndicatorMapDecl
165 %type <ledName> IndicatorNameDecl
166 %type <keyCode> KeyNameDecl
167 %type <keyAlias> KeyAliasDecl
168 %type <geom>    ShapeDecl SectionDecl SectionBody SectionBodyItem RowBody RowBodyItem
169 %type <geom>    Keys Key OverlayDecl OverlayKeyList OverlayKey OutlineList OutlineInList
170 %type <geom>    DoodadDecl
171 %type <file>    XkbFile XkbMapConfigList XkbMapConfig XkbConfig
172 %type <file>    XkbCompositeMap XkbCompMapList
173
174 %%
175
176 XkbFile         :       XkbCompMapList
177                         { $$ = param->rtrn = $1; }
178                 |       XkbMapConfigList
179                         { $$ = param->rtrn = $1; }
180                 |       XkbConfig
181                         { $$ = param->rtrn = $1; }
182                 ;
183
184 XkbCompMapList  :       XkbCompMapList XkbCompositeMap
185                         { $$ = (XkbFile *)AppendStmt(&$1->common, &$2->common); }
186                 |       XkbCompositeMap
187                         { $$ = $1; }
188                 ;
189
190 XkbCompositeMap :       OptFlags XkbCompositeType OptMapName OBRACE
191                             XkbMapConfigList
192                         CBRACE SEMI
193                         { $$ = XkbFileCreate(param->ctx, $2, $3, &$5->common, $1); }
194                 ;
195
196 XkbCompositeType:       XKB_KEYMAP      { $$ = FILE_TYPE_KEYMAP; }
197                 |       XKB_SEMANTICS   { $$ = FILE_TYPE_KEYMAP; }
198                 |       XKB_LAYOUT      { $$ = FILE_TYPE_KEYMAP; }
199                 ;
200
201 XkbMapConfigList :      XkbMapConfigList XkbMapConfig
202                         {
203                             if (!$2)
204                                 $$ = $1;
205                             else
206                                 $$ = (XkbFile *)AppendStmt(&$1->common, &$2->common);
207                         }
208                 |       XkbMapConfig
209                         { $$ = $1; }
210                 ;
211
212 XkbMapConfig    :       OptFlags FileType OptMapName OBRACE
213                             DeclList
214                         CBRACE SEMI
215                         {
216                             if ($2 == FILE_TYPE_GEOMETRY) {
217                                 free($3);
218                                 FreeStmt($5);
219                                 $$ = NULL;
220                             }
221                             else {
222                                 $$ = XkbFileCreate(param->ctx, $2, $3, $5, $1);
223                             }
224                         }
225                 ;
226
227 XkbConfig       :       OptFlags FileType OptMapName DeclList
228                         {
229                             if ($2 == FILE_TYPE_GEOMETRY) {
230                                 free($3);
231                                 FreeStmt($4);
232                                 $$ = NULL;
233                             }
234                             else {
235                                 $$ = XkbFileCreate(param->ctx, $2, $3, $4, $1);
236                             }
237                         }
238                 ;
239
240
241 FileType        :       XKB_KEYCODES            { $$ = FILE_TYPE_KEYCODES; }
242                 |       XKB_TYPES               { $$ = FILE_TYPE_TYPES; }
243                 |       XKB_COMPATMAP           { $$ = FILE_TYPE_COMPAT; }
244                 |       XKB_SYMBOLS             { $$ = FILE_TYPE_SYMBOLS; }
245                 |       XKB_GEOMETRY            { $$ = FILE_TYPE_GEOMETRY; }
246                 ;
247
248 OptFlags        :       Flags                   { $$ = $1; }
249                 |                               { $$ = 0; }
250                 ;
251
252 Flags           :       Flags Flag              { $$ = ($1 | $2); }
253                 |       Flag                    { $$ = $1; }
254                 ;
255
256 Flag            :       PARTIAL                 { $$ = XkbLC_Partial; }
257                 |       DEFAULT                 { $$ = XkbLC_Default; }
258                 |       HIDDEN                  { $$ = XkbLC_Hidden; }
259                 |       ALPHANUMERIC_KEYS       { $$ = XkbLC_AlphanumericKeys; }
260                 |       MODIFIER_KEYS           { $$ = XkbLC_ModifierKeys; }
261                 |       KEYPAD_KEYS             { $$ = XkbLC_KeypadKeys; }
262                 |       FUNCTION_KEYS           { $$ = XkbLC_FunctionKeys; }
263                 |       ALTERNATE_GROUP         { $$ = XkbLC_AlternateGroup; }
264                 ;
265
266 DeclList        :       DeclList Decl
267                         { $$ = AppendStmt($1, $2); }
268                 |       { $$ = NULL; }
269                 ;
270
271 Decl            :       OptMergeMode VarDecl
272                         {
273                             $2->merge = $1;
274                             $$ = &$2->common;
275                         }
276                 |       OptMergeMode VModDecl
277                         {
278                             $2->merge = $1;
279                             $$ = &$2->common;
280                         }
281                 |       OptMergeMode InterpretDecl
282                         {
283                             $2->merge = $1;
284                             $$ = &$2->common;
285                         }
286                 |       OptMergeMode KeyNameDecl
287                         {
288                             $2->merge = $1;
289                             $$ = &$2->common;
290                         }
291                 |       OptMergeMode KeyAliasDecl
292                         {
293                             $2->merge = $1;
294                             $$ = &$2->common;
295                         }
296                 |       OptMergeMode KeyTypeDecl
297                         {
298                             $2->merge = $1;
299                             $$ = &$2->common;
300                         }
301                 |       OptMergeMode SymbolsDecl
302                         {
303                             $2->merge = $1;
304                             $$ = &$2->common;
305                         }
306                 |       OptMergeMode ModMapDecl
307                         {
308                             $2->merge = $1;
309                             $$ = &$2->common;
310                         }
311                 |       OptMergeMode GroupCompatDecl
312                         {
313                             $2->merge = $1;
314                             $$ = &$2->common;
315                         }
316                 |       OptMergeMode IndicatorMapDecl
317                         {
318                             $2->merge = $1;
319                             $$ = &$2->common;
320                         }
321                 |       OptMergeMode IndicatorNameDecl
322                         {
323                             $2->merge = $1;
324                             $$ = &$2->common;
325                         }
326                 |       OptMergeMode ShapeDecl          { }
327                 |       OptMergeMode SectionDecl        { }
328                 |       OptMergeMode DoodadDecl         { }
329                 |       MergeMode STRING
330                         {
331                             $$ = &IncludeCreate(param->ctx, $2, $1)->common;
332                             free($2);
333                         }
334                 ;
335
336 VarDecl         :       Lhs EQUALS Expr SEMI
337                         { $$ = VarCreate($1, $3); }
338                 |       Ident SEMI
339                         { $$ = BoolVarCreate($1, 1); }
340                 |       EXCLAM Ident SEMI
341                         { $$ = BoolVarCreate($2, 0); }
342                 ;
343
344 KeyNameDecl     :       KeyName EQUALS KeyCode SEMI
345                         { $$ = KeycodeCreate($1, $3); }
346                 ;
347
348 KeyAliasDecl    :       ALIAS KeyName EQUALS KeyName SEMI
349                         { $$ = KeyAliasCreate($2, $4); }
350                 ;
351
352 VModDecl        :       VIRTUAL_MODS VModDefList SEMI
353                         { $$ = $2; }
354                 ;
355
356 VModDefList     :       VModDefList COMMA VModDef
357                         { $$ = (VModDef *)AppendStmt(&$1->common, &$3->common); }
358                 |       VModDef
359                         { $$ = $1; }
360                 ;
361
362 VModDef         :       Ident
363                         { $$ = VModCreate($1, NULL); }
364                 |       Ident EQUALS Expr
365                         { $$ = VModCreate($1, $3); }
366                 ;
367
368 InterpretDecl   :       INTERPRET InterpretMatch OBRACE
369                             VarDeclList
370                         CBRACE SEMI
371                         { $2->def = $4; $$ = $2; }
372                 ;
373
374 InterpretMatch  :       KeySym PLUS Expr
375                         { $$ = InterpCreate($1, $3); }
376                 |       KeySym
377                         { $$ = InterpCreate($1, NULL); }
378                 ;
379
380 VarDeclList     :       VarDeclList VarDecl
381                         { $$ = (VarDef *)AppendStmt(&$1->common, &$2->common); }
382                 |       VarDecl
383                         { $$ = $1; }
384                 ;
385
386 KeyTypeDecl     :       TYPE String OBRACE
387                             VarDeclList
388                         CBRACE SEMI
389                         { $$ = KeyTypeCreate($2, $4); }
390                 ;
391
392 SymbolsDecl     :       KEY KeyName OBRACE
393                             SymbolsBody
394                         CBRACE SEMI
395                         { $$ = SymbolsCreate($2, (ExprDef *)$4); }
396                 ;
397
398 SymbolsBody     :       SymbolsBody COMMA SymbolsVarDecl
399                         { $$ = (VarDef *)AppendStmt(&$1->common, &$3->common); }
400                 |       SymbolsVarDecl
401                         { $$ = $1; }
402                 |       { $$ = NULL; }
403                 ;
404
405 SymbolsVarDecl  :       Lhs EQUALS Expr         { $$ = VarCreate($1, $3); }
406                 |       Lhs EQUALS ArrayInit    { $$ = VarCreate($1, $3); }
407                 |       Ident                   { $$ = BoolVarCreate($1, 1); }
408                 |       EXCLAM Ident            { $$ = BoolVarCreate($2, 0); }
409                 |       ArrayInit               { $$ = VarCreate(NULL, $1); }
410                 ;
411
412 ArrayInit       :       OBRACKET OptKeySymList CBRACKET
413                         { $$ = $2; }
414                 |       OBRACKET ActionList CBRACKET
415                         { $$ = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, $2); }
416                 ;
417
418 GroupCompatDecl :       GROUP Integer EQUALS Expr SEMI
419                         { $$ = GroupCompatCreate($2, $4); }
420                 ;
421
422 ModMapDecl      :       MODIFIER_MAP Ident OBRACE ExprList CBRACE SEMI
423                         { $$ = ModMapCreate($2, $4); }
424                 ;
425
426 IndicatorMapDecl:       INDICATOR String OBRACE VarDeclList CBRACE SEMI
427                         { $$ = IndicatorMapCreate($2, $4); }
428                 ;
429
430 IndicatorNameDecl:      INDICATOR Integer EQUALS Expr SEMI
431                         { $$ = IndicatorNameCreate($2, $4, false); }
432                 |       VIRTUAL INDICATOR Integer EQUALS Expr SEMI
433                         { $$ = IndicatorNameCreate($3, $5, true); }
434                 ;
435
436 ShapeDecl       :       SHAPE String OBRACE OutlineList CBRACE SEMI
437                         { $$ = NULL; }
438                 |       SHAPE String OBRACE CoordList CBRACE SEMI
439                         { $$ = NULL; }
440                 ;
441
442 SectionDecl     :       SECTION String OBRACE SectionBody CBRACE SEMI
443                         { $$ = NULL; }
444                 ;
445
446 SectionBody     :       SectionBody SectionBodyItem     { $$ = NULL;}
447                 |       SectionBodyItem                 { $$ = NULL; }
448                 ;
449
450 SectionBodyItem :       ROW OBRACE RowBody CBRACE SEMI
451                         { $$ = NULL; }
452                 |       VarDecl
453                         { FreeStmt(&$1->common); $$ = NULL; }
454                 |       DoodadDecl
455                         { $$ = NULL; }
456                 |       IndicatorMapDecl
457                         { FreeStmt(&$1->common); $$ = NULL; }
458                 |       OverlayDecl
459                         { $$ = NULL; }
460                 ;
461
462 RowBody         :       RowBody RowBodyItem     { $$ = NULL;}
463                 |       RowBodyItem             { $$ = NULL; }
464                 ;
465
466 RowBodyItem     :       KEYS OBRACE Keys CBRACE SEMI { $$ = NULL; }
467                 |       VarDecl
468                         { FreeStmt(&$1->common); $$ = NULL; }
469                 ;
470
471 Keys            :       Keys COMMA Key          { $$ = NULL; }
472                 |       Key                     { $$ = NULL; }
473                 ;
474
475 Key             :       KeyName
476                         { $$ = NULL; }
477                 |       OBRACE ExprList CBRACE
478                         { FreeStmt(&$2->common); $$ = NULL; }
479                 ;
480
481 OverlayDecl     :       OVERLAY String OBRACE OverlayKeyList CBRACE SEMI
482                         { $$ = NULL; }
483                 ;
484
485 OverlayKeyList  :       OverlayKeyList COMMA OverlayKey { $$ = NULL; }
486                 |       OverlayKey                      { $$ = NULL; }
487                 ;
488
489 OverlayKey      :       KeyName EQUALS KeyName          { $$ = NULL; }
490                 ;
491
492 OutlineList     :       OutlineList COMMA OutlineInList
493                         { $$ = NULL;}
494                 |       OutlineInList
495                         { $$ = NULL; }
496                 ;
497
498 OutlineInList   :       OBRACE CoordList CBRACE
499                         { $$ = NULL; }
500                 |       Ident EQUALS OBRACE CoordList CBRACE
501                         { $$ = NULL; }
502                 |       Ident EQUALS Expr
503                         { FreeStmt(&$3->common); $$ = NULL; }
504                 ;
505
506 CoordList       :       CoordList COMMA Coord
507                         { $$ = NULL; }
508                 |       Coord
509                         { $$ = NULL; }
510                 ;
511
512 Coord           :       OBRACKET SignedNumber COMMA SignedNumber CBRACKET
513                         { $$ = NULL; }
514                 ;
515
516 DoodadDecl      :       DoodadType String OBRACE VarDeclList CBRACE SEMI
517                         { FreeStmt(&$4->common); $$ = NULL; }
518                 ;
519
520 DoodadType      :       TEXT    { $$ = 0; }
521                 |       OUTLINE { $$ = 0; }
522                 |       SOLID   { $$ = 0; }
523                 |       LOGO    { $$ = 0; }
524                 ;
525
526 FieldSpec       :       Ident   { $$ = $1; }
527                 |       Element { $$ = $1; }
528                 ;
529
530 Element         :       ACTION_TOK
531                         { $$ = xkb_atom_intern(param->ctx, "action"); }
532                 |       INTERPRET
533                         { $$ = xkb_atom_intern(param->ctx, "interpret"); }
534                 |       TYPE
535                         { $$ = xkb_atom_intern(param->ctx, "type"); }
536                 |       KEY
537                         { $$ = xkb_atom_intern(param->ctx, "key"); }
538                 |       GROUP
539                         { $$ = xkb_atom_intern(param->ctx, "group"); }
540                 |       MODIFIER_MAP
541                         {$$ = xkb_atom_intern(param->ctx, "modifier_map");}
542                 |       INDICATOR
543                         { $$ = xkb_atom_intern(param->ctx, "indicator"); }
544                 |       SHAPE
545                         { $$ = xkb_atom_intern(param->ctx, "shape"); }
546                 |       ROW
547                         { $$ = XKB_ATOM_NONE; }
548                 |       SECTION
549                         { $$ = XKB_ATOM_NONE; }
550                 |       TEXT
551                         { $$ = XKB_ATOM_NONE; }
552                 ;
553
554 OptMergeMode    :       MergeMode       { $$ = $1; }
555                 |                       { $$ = MERGE_DEFAULT; }
556                 ;
557
558 MergeMode       :       INCLUDE         { $$ = MERGE_DEFAULT; }
559                 |       AUGMENT         { $$ = MERGE_AUGMENT; }
560                 |       OVERRIDE        { $$ = MERGE_OVERRIDE; }
561                 |       REPLACE         { $$ = MERGE_REPLACE; }
562                 |       ALTERNATE
563                 {
564                     /*
565                      * This used to be MERGE_ALT_FORM. This functionality was
566                      * unused and has been removed.
567                      */
568                     $$ = MERGE_DEFAULT;
569                 }
570                 ;
571
572 OptExprList     :       ExprList        { $$ = $1; }
573                 |                       { $$ = NULL; }
574                 ;
575
576 ExprList        :       ExprList COMMA Expr
577                         { $$ = (ExprDef *)AppendStmt(&$1->common, &$3->common); }
578                 |       Expr
579                         { $$ = $1; }
580                 ;
581
582 Expr            :       Expr DIVIDE Expr
583                         { $$ = ExprCreateBinary(EXPR_DIVIDE, $1, $3); }
584                 |       Expr PLUS Expr
585                         { $$ = ExprCreateBinary(EXPR_ADD, $1, $3); }
586                 |       Expr MINUS Expr
587                         { $$ = ExprCreateBinary(EXPR_SUBTRACT, $1, $3); }
588                 |       Expr TIMES Expr
589                         { $$ = ExprCreateBinary(EXPR_MULTIPLY, $1, $3); }
590                 |       Lhs EQUALS Expr
591                         { $$ = ExprCreateBinary(EXPR_ASSIGN, $1, $3); }
592                 |       Term
593                         { $$ = $1; }
594                 ;
595
596 Term            :       MINUS Term
597                         { $$ = ExprCreateUnary(EXPR_NEGATE, $2->value_type, $2); }
598                 |       PLUS Term
599                         { $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->value_type, $2); }
600                 |       EXCLAM Term
601                         { $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); }
602                 |       INVERT Term
603                         { $$ = ExprCreateUnary(EXPR_INVERT, $2->value_type, $2); }
604                 |       Lhs
605                         { $$ = $1;  }
606                 |       FieldSpec OPAREN OptExprList CPAREN %prec OPAREN
607                         { $$ = ActionCreate($1, $3); }
608                 |       Terminal
609                         { $$ = $1;  }
610                 |       OPAREN Expr CPAREN
611                         { $$ = $2;  }
612                 ;
613
614 ActionList      :       ActionList COMMA Action
615                         { $$ = (ExprDef *)AppendStmt(&$1->common, &$3->common); }
616                 |       Action
617                         { $$ = $1; }
618                 ;
619
620 Action          :       FieldSpec OPAREN OptExprList CPAREN
621                         { $$ = ActionCreate($1, $3); }
622                 ;
623
624 Lhs             :       FieldSpec
625                         {
626                             ExprDef *expr;
627                             expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
628                             expr->value.str = $1;
629                             $$ = expr;
630                         }
631                 |       FieldSpec DOT FieldSpec
632                         {
633                             ExprDef *expr;
634                             expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
635                             expr->value.field.element = $1;
636                             expr->value.field.field = $3;
637                             $$ = expr;
638                         }
639                 |       FieldSpec OBRACKET Expr CBRACKET
640                         {
641                             ExprDef *expr;
642                             expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
643                             expr->value.array.element = XKB_ATOM_NONE;
644                             expr->value.array.field = $1;
645                             expr->value.array.entry = $3;
646                             $$ = expr;
647                         }
648                 |       FieldSpec DOT FieldSpec OBRACKET Expr CBRACKET
649                         {
650                             ExprDef *expr;
651                             expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
652                             expr->value.array.element = $1;
653                             expr->value.array.field = $3;
654                             expr->value.array.entry = $5;
655                             $$ = expr;
656                         }
657                 ;
658
659 Terminal        :       String
660                         {
661                             ExprDef *expr;
662                             expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING);
663                             expr->value.str = $1;
664                             $$ = expr;
665                         }
666                 |       Integer
667                         {
668                             ExprDef *expr;
669                             expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT);
670                             expr->value.ival = $1;
671                             $$ = expr;
672                         }
673                 |       Float
674                         {
675                             $$ = NULL;
676                         }
677                 |       KeyName
678                         {
679                             ExprDef *expr;
680                             expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME);
681                             strncpy(expr->value.keyName, $1, XKB_KEY_NAME_LENGTH);
682                             $$ = expr;
683                         }
684                 ;
685
686 OptKeySymList   :       KeySymList      { $$ = $1; }
687                 |                       { $$ = NULL; }
688                 ;
689
690 KeySymList      :       KeySymList COMMA KeySym
691                         { $$ = AppendKeysymList($1, $3); }
692                 |       KeySymList COMMA KeySyms
693                         { $$ = AppendMultiKeysymList($1, $3); }
694                 |       KeySym
695                         { $$ = CreateKeysymList($1); }
696                 |       KeySyms
697                         { $$ = CreateMultiKeysymList($1); }
698                 ;
699
700 KeySyms         :       OBRACE KeySymList CBRACE
701                         { $$ = $2; }
702                 ;
703
704 KeySym          :       IDENT   { $$ = $1; }
705                 |       SECTION { $$ = strdup("section"); }
706                 |       Integer
707                         {
708                             if ($1 < 10) {      /* XK_0 .. XK_9 */
709                                 $$ = malloc(2);
710                                 $$[0] = $1 + '0';
711                                 $$[1] = '\0';
712                             }
713                             else {
714                                 $$ = malloc(17);
715                                 snprintf($$, 17, "0x%x", $1);
716                             }
717                         }
718                 ;
719
720 SignedNumber    :       MINUS Number    { $$ = -$2; }
721                 |       Number          { $$ = $1; }
722                 ;
723
724 Number          :       FLOAT   { $$ = $1; }
725                 |       INTEGER { $$ = $1 * XkbGeomPtsPerMM; }
726                 ;
727
728 Float           :       FLOAT   { $$ = 0; }
729                 ;
730
731 Integer         :       INTEGER { $$ = $1; }
732                 ;
733
734 KeyCode         :       INTEGER { $$ = $1; }
735                 ;
736
737 KeyName         :       KEYNAME { strncpy($$, $1, XKB_KEY_NAME_LENGTH); }
738                 ;
739
740 Ident           :       IDENT   { $$ = xkb_atom_steal(param->ctx, $1); }
741                 |       DEFAULT { $$ = xkb_atom_intern(param->ctx, "default"); }
742                 ;
743
744 String          :       STRING  { $$ = xkb_atom_steal(param->ctx, $1); }
745                 ;
746
747 OptMapName      :       MapName { $$ = $1; }
748                 |               { $$ = NULL; }
749                 ;
750
751 MapName         :       STRING  { $$ = $1; }
752                 ;
753
754 %%
755
756 #undef scanner