kbproto unentanglement: XkbLC_*
[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         enum xkb_map_flags mapFlags;
129         ParseCommon     *any;
130         ExprDef         *expr;
131         VarDef          *var;
132         VModDef         *vmod;
133         InterpDef       *interp;
134         KeyTypeDef      *keyType;
135         SymbolsDef      *syms;
136         ModMapDef       *modMask;
137         GroupCompatDef  *groupCompat;
138         IndicatorMapDef *ledMap;
139         IndicatorNameDef *ledName;
140         KeycodeDef      *keyCode;
141         KeyAliasDef     *keyAlias;
142         void            *geom;
143         XkbFile         *file;
144 }
145
146 %type <num>     INTEGER FLOAT
147 %type <str>     IDENT STRING
148 %type <keyName> KEYNAME KeyName
149 %type <ival>    Number Integer Float SignedNumber
150 %type <merge>   MergeMode OptMergeMode
151 %type <file_type> XkbCompositeType FileType
152 %type <uval>    DoodadType
153 %type <mapFlags> Flag Flags OptFlags KeyCode
154 %type <str>     MapName OptMapName KeySym
155 %type <sval>    FieldSpec Ident Element String
156 %type <any>     DeclList Decl
157 %type <expr>    OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms
158 %type <expr>    OptKeySymList KeySymList Action ActionList Coord CoordList
159 %type <var>     VarDecl VarDeclList SymbolsBody SymbolsVarDecl
160 %type <vmod>    VModDecl VModDefList VModDef
161 %type <interp>  InterpretDecl InterpretMatch
162 %type <keyType> KeyTypeDecl
163 %type <syms>    SymbolsDecl
164 %type <modMask> ModMapDecl
165 %type <groupCompat> GroupCompatDecl
166 %type <ledMap>  IndicatorMapDecl
167 %type <ledName> IndicatorNameDecl
168 %type <keyCode> KeyNameDecl
169 %type <keyAlias> KeyAliasDecl
170 %type <geom>    ShapeDecl SectionDecl SectionBody SectionBodyItem RowBody RowBodyItem
171 %type <geom>    Keys Key OverlayDecl OverlayKeyList OverlayKey OutlineList OutlineInList
172 %type <geom>    DoodadDecl
173 %type <file>    XkbFile XkbMapConfigList XkbMapConfig XkbConfig
174 %type <file>    XkbCompositeMap XkbCompMapList
175
176 %%
177
178 XkbFile         :       XkbCompMapList
179                         { $$ = param->rtrn = $1; }
180                 |       XkbMapConfigList
181                         { $$ = param->rtrn = $1; }
182                 |       XkbConfig
183                         { $$ = param->rtrn = $1; }
184                 ;
185
186 XkbCompMapList  :       XkbCompMapList XkbCompositeMap
187                         { $$ = (XkbFile *)AppendStmt(&$1->common, &$2->common); }
188                 |       XkbCompositeMap
189                         { $$ = $1; }
190                 ;
191
192 XkbCompositeMap :       OptFlags XkbCompositeType OptMapName OBRACE
193                             XkbMapConfigList
194                         CBRACE SEMI
195                         { $$ = XkbFileCreate(param->ctx, $2, $3, &$5->common, $1); }
196                 ;
197
198 XkbCompositeType:       XKB_KEYMAP      { $$ = FILE_TYPE_KEYMAP; }
199                 |       XKB_SEMANTICS   { $$ = FILE_TYPE_KEYMAP; }
200                 |       XKB_LAYOUT      { $$ = FILE_TYPE_KEYMAP; }
201                 ;
202
203 XkbMapConfigList :      XkbMapConfigList XkbMapConfig
204                         {
205                             if (!$2)
206                                 $$ = $1;
207                             else
208                                 $$ = (XkbFile *)AppendStmt(&$1->common, &$2->common);
209                         }
210                 |       XkbMapConfig
211                         { $$ = $1; }
212                 ;
213
214 XkbMapConfig    :       OptFlags FileType OptMapName OBRACE
215                             DeclList
216                         CBRACE SEMI
217                         {
218                             if ($2 == FILE_TYPE_GEOMETRY) {
219                                 free($3);
220                                 FreeStmt($5);
221                                 $$ = NULL;
222                             }
223                             else {
224                                 $$ = XkbFileCreate(param->ctx, $2, $3, $5, $1);
225                             }
226                         }
227                 ;
228
229 XkbConfig       :       OptFlags FileType OptMapName DeclList
230                         {
231                             if ($2 == FILE_TYPE_GEOMETRY) {
232                                 free($3);
233                                 FreeStmt($4);
234                                 $$ = NULL;
235                             }
236                             else {
237                                 $$ = XkbFileCreate(param->ctx, $2, $3, $4, $1);
238                             }
239                         }
240                 ;
241
242
243 FileType        :       XKB_KEYCODES            { $$ = FILE_TYPE_KEYCODES; }
244                 |       XKB_TYPES               { $$ = FILE_TYPE_TYPES; }
245                 |       XKB_COMPATMAP           { $$ = FILE_TYPE_COMPAT; }
246                 |       XKB_SYMBOLS             { $$ = FILE_TYPE_SYMBOLS; }
247                 |       XKB_GEOMETRY            { $$ = FILE_TYPE_GEOMETRY; }
248                 ;
249
250 OptFlags        :       Flags                   { $$ = $1; }
251                 |                               { $$ = 0; }
252                 ;
253
254 Flags           :       Flags Flag              { $$ = ($1 | $2); }
255                 |       Flag                    { $$ = $1; }
256                 ;
257
258 Flag            :       PARTIAL                 { $$ = MAP_IS_PARTIAL; }
259                 |       DEFAULT                 { $$ = MAP_IS_DEFAULT; }
260                 |       HIDDEN                  { $$ = MAP_IS_HIDDEN; }
261                 |       ALPHANUMERIC_KEYS       { $$ = MAP_HAS_ALPHANUMERIC; }
262                 |       MODIFIER_KEYS           { $$ = MAP_HAS_MODIFIER; }
263                 |       KEYPAD_KEYS             { $$ = MAP_HAS_KEYPAD; }
264                 |       FUNCTION_KEYS           { $$ = MAP_HAS_FN; }
265                 |       ALTERNATE_GROUP         { $$ = MAP_IS_ALTGR; }
266                 ;
267
268 DeclList        :       DeclList Decl
269                         { $$ = AppendStmt($1, $2); }
270                 |       { $$ = NULL; }
271                 ;
272
273 Decl            :       OptMergeMode VarDecl
274                         {
275                             $2->merge = $1;
276                             $$ = &$2->common;
277                         }
278                 |       OptMergeMode VModDecl
279                         {
280                             $2->merge = $1;
281                             $$ = &$2->common;
282                         }
283                 |       OptMergeMode InterpretDecl
284                         {
285                             $2->merge = $1;
286                             $$ = &$2->common;
287                         }
288                 |       OptMergeMode KeyNameDecl
289                         {
290                             $2->merge = $1;
291                             $$ = &$2->common;
292                         }
293                 |       OptMergeMode KeyAliasDecl
294                         {
295                             $2->merge = $1;
296                             $$ = &$2->common;
297                         }
298                 |       OptMergeMode KeyTypeDecl
299                         {
300                             $2->merge = $1;
301                             $$ = &$2->common;
302                         }
303                 |       OptMergeMode SymbolsDecl
304                         {
305                             $2->merge = $1;
306                             $$ = &$2->common;
307                         }
308                 |       OptMergeMode ModMapDecl
309                         {
310                             $2->merge = $1;
311                             $$ = &$2->common;
312                         }
313                 |       OptMergeMode GroupCompatDecl
314                         {
315                             $2->merge = $1;
316                             $$ = &$2->common;
317                         }
318                 |       OptMergeMode IndicatorMapDecl
319                         {
320                             $2->merge = $1;
321                             $$ = &$2->common;
322                         }
323                 |       OptMergeMode IndicatorNameDecl
324                         {
325                             $2->merge = $1;
326                             $$ = &$2->common;
327                         }
328                 |       OptMergeMode ShapeDecl          { }
329                 |       OptMergeMode SectionDecl        { }
330                 |       OptMergeMode DoodadDecl         { }
331                 |       MergeMode STRING
332                         {
333                             $$ = &IncludeCreate(param->ctx, $2, $1)->common;
334                             free($2);
335                         }
336                 ;
337
338 VarDecl         :       Lhs EQUALS Expr SEMI
339                         { $$ = VarCreate($1, $3); }
340                 |       Ident SEMI
341                         { $$ = BoolVarCreate($1, 1); }
342                 |       EXCLAM Ident SEMI
343                         { $$ = BoolVarCreate($2, 0); }
344                 ;
345
346 KeyNameDecl     :       KeyName EQUALS KeyCode SEMI
347                         { $$ = KeycodeCreate($1, $3); }
348                 ;
349
350 KeyAliasDecl    :       ALIAS KeyName EQUALS KeyName SEMI
351                         { $$ = KeyAliasCreate($2, $4); }
352                 ;
353
354 VModDecl        :       VIRTUAL_MODS VModDefList SEMI
355                         { $$ = $2; }
356                 ;
357
358 VModDefList     :       VModDefList COMMA VModDef
359                         { $$ = (VModDef *)AppendStmt(&$1->common, &$3->common); }
360                 |       VModDef
361                         { $$ = $1; }
362                 ;
363
364 VModDef         :       Ident
365                         { $$ = VModCreate($1, NULL); }
366                 |       Ident EQUALS Expr
367                         { $$ = VModCreate($1, $3); }
368                 ;
369
370 InterpretDecl   :       INTERPRET InterpretMatch OBRACE
371                             VarDeclList
372                         CBRACE SEMI
373                         { $2->def = $4; $$ = $2; }
374                 ;
375
376 InterpretMatch  :       KeySym PLUS Expr
377                         { $$ = InterpCreate($1, $3); }
378                 |       KeySym
379                         { $$ = InterpCreate($1, NULL); }
380                 ;
381
382 VarDeclList     :       VarDeclList VarDecl
383                         { $$ = (VarDef *)AppendStmt(&$1->common, &$2->common); }
384                 |       VarDecl
385                         { $$ = $1; }
386                 ;
387
388 KeyTypeDecl     :       TYPE String OBRACE
389                             VarDeclList
390                         CBRACE SEMI
391                         { $$ = KeyTypeCreate($2, $4); }
392                 ;
393
394 SymbolsDecl     :       KEY KeyName OBRACE
395                             SymbolsBody
396                         CBRACE SEMI
397                         { $$ = SymbolsCreate($2, (ExprDef *)$4); }
398                 ;
399
400 SymbolsBody     :       SymbolsBody COMMA SymbolsVarDecl
401                         { $$ = (VarDef *)AppendStmt(&$1->common, &$3->common); }
402                 |       SymbolsVarDecl
403                         { $$ = $1; }
404                 |       { $$ = NULL; }
405                 ;
406
407 SymbolsVarDecl  :       Lhs EQUALS Expr         { $$ = VarCreate($1, $3); }
408                 |       Lhs EQUALS ArrayInit    { $$ = VarCreate($1, $3); }
409                 |       Ident                   { $$ = BoolVarCreate($1, 1); }
410                 |       EXCLAM Ident            { $$ = BoolVarCreate($2, 0); }
411                 |       ArrayInit               { $$ = VarCreate(NULL, $1); }
412                 ;
413
414 ArrayInit       :       OBRACKET OptKeySymList CBRACKET
415                         { $$ = $2; }
416                 |       OBRACKET ActionList CBRACKET
417                         { $$ = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, $2); }
418                 ;
419
420 GroupCompatDecl :       GROUP Integer EQUALS Expr SEMI
421                         { $$ = GroupCompatCreate($2, $4); }
422                 ;
423
424 ModMapDecl      :       MODIFIER_MAP Ident OBRACE ExprList CBRACE SEMI
425                         { $$ = ModMapCreate($2, $4); }
426                 ;
427
428 IndicatorMapDecl:       INDICATOR String OBRACE VarDeclList CBRACE SEMI
429                         { $$ = IndicatorMapCreate($2, $4); }
430                 ;
431
432 IndicatorNameDecl:      INDICATOR Integer EQUALS Expr SEMI
433                         { $$ = IndicatorNameCreate($2, $4, false); }
434                 |       VIRTUAL INDICATOR Integer EQUALS Expr SEMI
435                         { $$ = IndicatorNameCreate($3, $5, true); }
436                 ;
437
438 ShapeDecl       :       SHAPE String OBRACE OutlineList CBRACE SEMI
439                         { $$ = NULL; }
440                 |       SHAPE String OBRACE CoordList CBRACE SEMI
441                         { $$ = NULL; }
442                 ;
443
444 SectionDecl     :       SECTION String OBRACE SectionBody CBRACE SEMI
445                         { $$ = NULL; }
446                 ;
447
448 SectionBody     :       SectionBody SectionBodyItem     { $$ = NULL;}
449                 |       SectionBodyItem                 { $$ = NULL; }
450                 ;
451
452 SectionBodyItem :       ROW OBRACE RowBody CBRACE SEMI
453                         { $$ = NULL; }
454                 |       VarDecl
455                         { FreeStmt(&$1->common); $$ = NULL; }
456                 |       DoodadDecl
457                         { $$ = NULL; }
458                 |       IndicatorMapDecl
459                         { FreeStmt(&$1->common); $$ = NULL; }
460                 |       OverlayDecl
461                         { $$ = NULL; }
462                 ;
463
464 RowBody         :       RowBody RowBodyItem     { $$ = NULL;}
465                 |       RowBodyItem             { $$ = NULL; }
466                 ;
467
468 RowBodyItem     :       KEYS OBRACE Keys CBRACE SEMI { $$ = NULL; }
469                 |       VarDecl
470                         { FreeStmt(&$1->common); $$ = NULL; }
471                 ;
472
473 Keys            :       Keys COMMA Key          { $$ = NULL; }
474                 |       Key                     { $$ = NULL; }
475                 ;
476
477 Key             :       KeyName
478                         { $$ = NULL; }
479                 |       OBRACE ExprList CBRACE
480                         { FreeStmt(&$2->common); $$ = NULL; }
481                 ;
482
483 OverlayDecl     :       OVERLAY String OBRACE OverlayKeyList CBRACE SEMI
484                         { $$ = NULL; }
485                 ;
486
487 OverlayKeyList  :       OverlayKeyList COMMA OverlayKey { $$ = NULL; }
488                 |       OverlayKey                      { $$ = NULL; }
489                 ;
490
491 OverlayKey      :       KeyName EQUALS KeyName          { $$ = NULL; }
492                 ;
493
494 OutlineList     :       OutlineList COMMA OutlineInList
495                         { $$ = NULL;}
496                 |       OutlineInList
497                         { $$ = NULL; }
498                 ;
499
500 OutlineInList   :       OBRACE CoordList CBRACE
501                         { $$ = NULL; }
502                 |       Ident EQUALS OBRACE CoordList CBRACE
503                         { $$ = NULL; }
504                 |       Ident EQUALS Expr
505                         { FreeStmt(&$3->common); $$ = NULL; }
506                 ;
507
508 CoordList       :       CoordList COMMA Coord
509                         { $$ = NULL; }
510                 |       Coord
511                         { $$ = NULL; }
512                 ;
513
514 Coord           :       OBRACKET SignedNumber COMMA SignedNumber CBRACKET
515                         { $$ = NULL; }
516                 ;
517
518 DoodadDecl      :       DoodadType String OBRACE VarDeclList CBRACE SEMI
519                         { FreeStmt(&$4->common); $$ = NULL; }
520                 ;
521
522 DoodadType      :       TEXT    { $$ = 0; }
523                 |       OUTLINE { $$ = 0; }
524                 |       SOLID   { $$ = 0; }
525                 |       LOGO    { $$ = 0; }
526                 ;
527
528 FieldSpec       :       Ident   { $$ = $1; }
529                 |       Element { $$ = $1; }
530                 ;
531
532 Element         :       ACTION_TOK
533                         { $$ = xkb_atom_intern(param->ctx, "action"); }
534                 |       INTERPRET
535                         { $$ = xkb_atom_intern(param->ctx, "interpret"); }
536                 |       TYPE
537                         { $$ = xkb_atom_intern(param->ctx, "type"); }
538                 |       KEY
539                         { $$ = xkb_atom_intern(param->ctx, "key"); }
540                 |       GROUP
541                         { $$ = xkb_atom_intern(param->ctx, "group"); }
542                 |       MODIFIER_MAP
543                         {$$ = xkb_atom_intern(param->ctx, "modifier_map");}
544                 |       INDICATOR
545                         { $$ = xkb_atom_intern(param->ctx, "indicator"); }
546                 |       SHAPE
547                         { $$ = xkb_atom_intern(param->ctx, "shape"); }
548                 |       ROW
549                         { $$ = XKB_ATOM_NONE; }
550                 |       SECTION
551                         { $$ = XKB_ATOM_NONE; }
552                 |       TEXT
553                         { $$ = XKB_ATOM_NONE; }
554                 ;
555
556 OptMergeMode    :       MergeMode       { $$ = $1; }
557                 |                       { $$ = MERGE_DEFAULT; }
558                 ;
559
560 MergeMode       :       INCLUDE         { $$ = MERGE_DEFAULT; }
561                 |       AUGMENT         { $$ = MERGE_AUGMENT; }
562                 |       OVERRIDE        { $$ = MERGE_OVERRIDE; }
563                 |       REPLACE         { $$ = MERGE_REPLACE; }
564                 |       ALTERNATE
565                 {
566                     /*
567                      * This used to be MERGE_ALT_FORM. This functionality was
568                      * unused and has been removed.
569                      */
570                     $$ = MERGE_DEFAULT;
571                 }
572                 ;
573
574 OptExprList     :       ExprList        { $$ = $1; }
575                 |                       { $$ = NULL; }
576                 ;
577
578 ExprList        :       ExprList COMMA Expr
579                         { $$ = (ExprDef *)AppendStmt(&$1->common, &$3->common); }
580                 |       Expr
581                         { $$ = $1; }
582                 ;
583
584 Expr            :       Expr DIVIDE Expr
585                         { $$ = ExprCreateBinary(EXPR_DIVIDE, $1, $3); }
586                 |       Expr PLUS Expr
587                         { $$ = ExprCreateBinary(EXPR_ADD, $1, $3); }
588                 |       Expr MINUS Expr
589                         { $$ = ExprCreateBinary(EXPR_SUBTRACT, $1, $3); }
590                 |       Expr TIMES Expr
591                         { $$ = ExprCreateBinary(EXPR_MULTIPLY, $1, $3); }
592                 |       Lhs EQUALS Expr
593                         { $$ = ExprCreateBinary(EXPR_ASSIGN, $1, $3); }
594                 |       Term
595                         { $$ = $1; }
596                 ;
597
598 Term            :       MINUS Term
599                         { $$ = ExprCreateUnary(EXPR_NEGATE, $2->value_type, $2); }
600                 |       PLUS Term
601                         { $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->value_type, $2); }
602                 |       EXCLAM Term
603                         { $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); }
604                 |       INVERT Term
605                         { $$ = ExprCreateUnary(EXPR_INVERT, $2->value_type, $2); }
606                 |       Lhs
607                         { $$ = $1;  }
608                 |       FieldSpec OPAREN OptExprList CPAREN %prec OPAREN
609                         { $$ = ActionCreate($1, $3); }
610                 |       Terminal
611                         { $$ = $1;  }
612                 |       OPAREN Expr CPAREN
613                         { $$ = $2;  }
614                 ;
615
616 ActionList      :       ActionList COMMA Action
617                         { $$ = (ExprDef *)AppendStmt(&$1->common, &$3->common); }
618                 |       Action
619                         { $$ = $1; }
620                 ;
621
622 Action          :       FieldSpec OPAREN OptExprList CPAREN
623                         { $$ = ActionCreate($1, $3); }
624                 ;
625
626 Lhs             :       FieldSpec
627                         {
628                             ExprDef *expr;
629                             expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
630                             expr->value.str = $1;
631                             $$ = expr;
632                         }
633                 |       FieldSpec DOT FieldSpec
634                         {
635                             ExprDef *expr;
636                             expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
637                             expr->value.field.element = $1;
638                             expr->value.field.field = $3;
639                             $$ = expr;
640                         }
641                 |       FieldSpec OBRACKET Expr CBRACKET
642                         {
643                             ExprDef *expr;
644                             expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
645                             expr->value.array.element = XKB_ATOM_NONE;
646                             expr->value.array.field = $1;
647                             expr->value.array.entry = $3;
648                             $$ = expr;
649                         }
650                 |       FieldSpec DOT FieldSpec OBRACKET Expr CBRACKET
651                         {
652                             ExprDef *expr;
653                             expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
654                             expr->value.array.element = $1;
655                             expr->value.array.field = $3;
656                             expr->value.array.entry = $5;
657                             $$ = expr;
658                         }
659                 ;
660
661 Terminal        :       String
662                         {
663                             ExprDef *expr;
664                             expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING);
665                             expr->value.str = $1;
666                             $$ = expr;
667                         }
668                 |       Integer
669                         {
670                             ExprDef *expr;
671                             expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT);
672                             expr->value.ival = $1;
673                             $$ = expr;
674                         }
675                 |       Float
676                         {
677                             $$ = NULL;
678                         }
679                 |       KeyName
680                         {
681                             ExprDef *expr;
682                             expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME);
683                             strncpy(expr->value.keyName, $1, XKB_KEY_NAME_LENGTH);
684                             $$ = expr;
685                         }
686                 ;
687
688 OptKeySymList   :       KeySymList      { $$ = $1; }
689                 |                       { $$ = NULL; }
690                 ;
691
692 KeySymList      :       KeySymList COMMA KeySym
693                         { $$ = AppendKeysymList($1, $3); }
694                 |       KeySymList COMMA KeySyms
695                         { $$ = AppendMultiKeysymList($1, $3); }
696                 |       KeySym
697                         { $$ = CreateKeysymList($1); }
698                 |       KeySyms
699                         { $$ = CreateMultiKeysymList($1); }
700                 ;
701
702 KeySyms         :       OBRACE KeySymList CBRACE
703                         { $$ = $2; }
704                 ;
705
706 KeySym          :       IDENT   { $$ = $1; }
707                 |       SECTION { $$ = strdup("section"); }
708                 |       Integer
709                         {
710                             if ($1 < 10) {      /* XK_0 .. XK_9 */
711                                 $$ = malloc(2);
712                                 $$[0] = $1 + '0';
713                                 $$[1] = '\0';
714                             }
715                             else {
716                                 $$ = malloc(17);
717                                 snprintf($$, 17, "0x%x", $1);
718                             }
719                         }
720                 ;
721
722 SignedNumber    :       MINUS Number    { $$ = -$2; }
723                 |       Number          { $$ = $1; }
724                 ;
725
726 Number          :       FLOAT   { $$ = $1; }
727                 |       INTEGER { $$ = $1 * XkbGeomPtsPerMM; }
728                 ;
729
730 Float           :       FLOAT   { $$ = 0; }
731                 ;
732
733 Integer         :       INTEGER { $$ = $1; }
734                 ;
735
736 KeyCode         :       INTEGER { $$ = $1; }
737                 ;
738
739 KeyName         :       KEYNAME { strncpy($$, $1, XKB_KEY_NAME_LENGTH); }
740                 ;
741
742 Ident           :       IDENT   { $$ = xkb_atom_steal(param->ctx, $1); }
743                 |       DEFAULT { $$ = xkb_atom_intern(param->ctx, "default"); }
744                 ;
745
746 String          :       STRING  { $$ = xkb_atom_steal(param->ctx, $1); }
747                 ;
748
749 OptMapName      :       MapName { $$ = $1; }
750                 |               { $$ = NULL; }
751                 ;
752
753 MapName         :       STRING  { $$ = $1; }
754                 ;
755
756 %%
757
758 #undef scanner