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