parser: untabify
[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 "parseutils.h"
30
31 #pragma GCC diagnostic ignored "-Wredundant-decls"
32
33 extern int yylex(union YYSTYPE *val, struct YYLTYPE *loc, void *scanner);
34
35 static void
36 yyerror(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
37 {
38     scanner_error(loc, param->scanner, msg);
39 }
40
41 #define scanner param->scanner
42 %}
43
44 %define         api.pure
45 %locations
46 %lex-param      { void *scanner }
47 %parse-param    { struct parser_param *param }
48
49 %token
50         END_OF_FILE     0
51         ERROR_TOK       255
52         XKB_KEYMAP      1
53         XKB_KEYCODES    2
54         XKB_TYPES       3
55         XKB_SYMBOLS     4
56         XKB_COMPATMAP   5
57         XKB_GEOMETRY    6
58         XKB_SEMANTICS   7
59         XKB_LAYOUT      8
60         INCLUDE         10
61         OVERRIDE        11
62         AUGMENT         12
63         REPLACE         13
64         ALTERNATE       14
65         VIRTUAL_MODS    20
66         TYPE            21
67         INTERPRET       22
68         ACTION_TOK      23
69         KEY             24
70         ALIAS           25
71         GROUP           26
72         MODIFIER_MAP    27
73         INDICATOR       28
74         SHAPE           29
75         KEYS            30
76         ROW             31
77         SECTION         32
78         OVERLAY         33
79         TEXT            34
80         OUTLINE         35
81         SOLID           36
82         LOGO            37
83         VIRTUAL         38
84         EQUALS          40
85         PLUS            41
86         MINUS           42
87         DIVIDE          43
88         TIMES           44
89         OBRACE          45
90         CBRACE          46
91         OPAREN          47
92         CPAREN          48
93         OBRACKET        49
94         CBRACKET        50
95         DOT             51
96         COMMA           52
97         SEMI            53
98         EXCLAM          54
99         INVERT          55
100         STRING          60
101         INTEGER         61
102         FLOAT           62
103         IDENT           63
104         KEYNAME         64
105         PARTIAL         70
106         DEFAULT         71
107         HIDDEN          72
108         ALPHANUMERIC_KEYS       73
109         MODIFIER_KEYS           74
110         KEYPAD_KEYS             75
111         FUNCTION_KEYS           76
112         ALTERNATE_GROUP         77
113
114 %right  EQUALS
115 %left   PLUS MINUS
116 %left   TIMES DIVIDE
117 %left   EXCLAM INVERT
118 %left   OPAREN
119
120 %start  XkbFile
121
122 %union  {
123         int              ival;
124         unsigned         uval;
125         int64_t          num;
126         enum xkb_file_type file_type;
127         char            *str;
128         char            keyName[XkbKeyNameLength];
129         xkb_atom_t      sval;
130         enum merge_mode merge;
131         ParseCommon     *any;
132         ExprDef         *expr;
133         VarDef          *var;
134         VModDef         *vmod;
135         InterpDef       *interp;
136         KeyTypeDef      *keyType;
137         SymbolsDef      *syms;
138         ModMapDef       *modMask;
139         GroupCompatDef  *groupCompat;
140         IndicatorMapDef *ledMap;
141         IndicatorNameDef *ledName;
142         KeycodeDef      *keyCode;
143         KeyAliasDef     *keyAlias;
144         void            *geom;
145         XkbFile         *file;
146 }
147
148 %type <num>     INTEGER FLOAT
149 %type <str>     IDENT STRING
150 %type <keyName> KEYNAME KeyName
151 %type <ival>    Number Integer Float SignedNumber
152 %type <merge>   MergeMode OptMergeMode
153 %type <file_type> XkbCompositeType FileType
154 %type <uval>    DoodadType Flag Flags OptFlags KeyCode
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                         { $$ = CreateXKBFile(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                                 $$ = CreateXKBFile(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                                 $$ = CreateXKBFile(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                 { $$ = XkbLC_Partial; }
260                 |       DEFAULT                 { $$ = XkbLC_Default; }
261                 |       HIDDEN                  { $$ = XkbLC_Hidden; }
262                 |       ALPHANUMERIC_KEYS       { $$ = XkbLC_AlphanumericKeys; }
263                 |       MODIFIER_KEYS           { $$ = XkbLC_ModifierKeys; }
264                 |       KEYPAD_KEYS             { $$ = XkbLC_KeypadKeys; }
265                 |       FUNCTION_KEYS           { $$ = XkbLC_FunctionKeys; }
266                 |       ALTERNATE_GROUP         { $$ = XkbLC_AlternateGroup; }
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                             strncpy(expr->value.keyName, $1, 4);
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 * XkbGeomPtsPerMM; }
729                 ;
730
731 Float           :       FLOAT   { $$ = 0; }
732                 ;
733
734 Integer         :       INTEGER { $$ = $1; }
735                 ;
736
737 KeyCode         :       INTEGER { $$ = $1; }
738                 ;
739
740 KeyName         :       KEYNAME { strncpy($$, $1, XkbKeyNameLength); }
741                 ;
742
743 Ident           :       IDENT   { $$ = xkb_atom_steal(param->ctx, $1); }
744                 |       DEFAULT { $$ = xkb_atom_intern(param->ctx, "default"); }
745                 ;
746
747 String          :       STRING  { $$ = xkb_atom_steal(param->ctx, $1); }
748                 ;
749
750 OptMapName      :       MapName { $$ = $1; }
751                 |               { $$ = NULL; }
752                 ;
753
754 MapName         :       STRING  { $$ = $1; }
755                 ;
756
757 %%
758
759 #undef scanner