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