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