(linenum→info "unix/slp.c:2238")

binutils/2.18/binutils/mcparse.y

    1: %{ /* mcparse.y -- parser for Windows mc files
    2:   Copyright 2007
    3:   Free Software Foundation, Inc.
    4:   
    5:   Parser for Windows mc files
    6:   Written by Kai Tietz, Onevision.
    7:   
    8:   This file is part of GNU Binutils.
    9:   
   10:   This program is free software; you can redistribute it and/or modify
   11:   it under the terms of the GNU General Public License as published by
   12:   the Free Software Foundation; either version 3 of the License, or
   13:   (at your option) any later version.
   14:   
   15:   This program is distributed in the hope that it will be useful,
   16:   but WITHOUT ANY WARRANTY; without even the implied warranty of
   17:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18:   GNU General Public License for more details.
   19:   
   20:   You should have received a copy of the GNU General Public License
   21:   along with this program; if not, write to the Free Software
   22:   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   23:   02110-1301, USA.  */
   24: 
   25: /* This is a parser for Windows rc files.  It is based on the parser
   26:    by Gunther Ebert <gunther.ebert@ixos-leipzig.de>.  */
   27: 
   28: #include "sysdep.h"
   29: #include "bfd.h"
   30: #include "bucomm.h"
   31: #include "libiberty.h"
   32: #include "windmc.h"
   33: #include "safe-ctype.h"
   34: 
   35: static rc_uint_type mc_last_id = 0;
   36: static rc_uint_type mc_sefa_val = 0;
   37: static unichar *mc_last_symbol = NULL;
   38: static const mc_keyword *mc_cur_severity = NULL;
   39: static const mc_keyword *mc_cur_facility = NULL;
   40: static mc_node *cur_node = NULL;
   41: 
   42: %}
   43: 
   44: %union
   45: {
   46:   rc_uint_type ival;
   47:   unichar *ustr;
   48:   const mc_keyword *tok;
   49:   mc_node *nod;
   50: };
   51: 
   52: %start input
   53: 
   54: %token NL
   55: %token<ustr> MCIDENT MCFILENAME MCLINE MCCOMMENT
   56: %token<tok> MCTOKEN
   57: %token MCENDLINE
   58: %token MCLANGUAGENAMES MCFACILITYNAMES MCSEVERITYNAMES MCOUTPUTBASE MCMESSAGEIDTYPEDEF
   59: %token MCLANGUAGE MCMESSAGEID MCSEVERITY MCFACILITY MCSYMBOLICNAME
   60: %token <ival> MCNUMBER
   61: 
   62: %type<ival> id vid sefasy_def
   63: %type<ustr> alias_name token lines comments
   64: %type<tok> lang
   65: 
   66: %%
   67: input:    entities
   68:         ;
   69: 
   70: entities:
   71:           /* empty */
   72:         | entities entity
   73:         ;
   74: entity:   global_section
   75:         | message
   76:         | comments
   77:           {
   78:             cur_node = mc_add_node ();
   79:             cur_node->user_text = $1;
   80:           }
   81:         | error        { mc_fatal ("syntax error"); }
   82: ;
   83: 
   84: global_section:
   85:           MCSEVERITYNAMES '=' '(' severitymaps ')'
   86:         | MCSEVERITYNAMES '=' '(' severitymaps error { mc_fatal ("missing ')' in SeverityNames"); }
   87:         | MCSEVERITYNAMES '=' error { mc_fatal ("missing '(' in SeverityNames"); }
   88:         | MCSEVERITYNAMES error { mc_fatal ("missing '=' for SeverityNames"); }
   89:         | MCLANGUAGENAMES '=' '(' langmaps ')'
   90:         | MCLANGUAGENAMES '=' '(' langmaps error { mc_fatal ("missing ')' in LanguageNames"); }
   91:         | MCLANGUAGENAMES '=' error { mc_fatal ("missing '(' in LanguageNames"); }
   92:         | MCLANGUAGENAMES error { mc_fatal ("missing '=' for LanguageNames"); }
   93:         | MCFACILITYNAMES '=' '(' facilitymaps ')'
   94:         | MCFACILITYNAMES '=' '(' facilitymaps error { mc_fatal ("missing ')' in FacilityNames"); }
   95:         | MCFACILITYNAMES '=' error { mc_fatal ("missing '(' in FacilityNames"); }
   96:         | MCFACILITYNAMES error { mc_fatal ("missing '=' for FacilityNames"); }
   97:         | MCOUTPUTBASE '=' MCNUMBER
   98:           {
   99:             if ($3 != 10 && $3 != 16)
  100:               mc_fatal ("OutputBase allows 10 or 16 as value");
  101:             mcset_out_values_are_decimal = ($3 == 10 ? 1 : 0);
  102:           }
  103:         | MCMESSAGEIDTYPEDEF '=' MCIDENT
  104:           {
  105:             mcset_msg_id_typedef = $3;
  106:           }
  107:         | MCMESSAGEIDTYPEDEF '=' error
  108:           {
  109:             mc_fatal ("MessageIdTypedef expects an identifier");
  110:           }
  111:         | MCMESSAGEIDTYPEDEF error
  112:           {
  113:             mc_fatal ("missing '=' for MessageIdTypedef");
  114:           }
  115: ;
  116: 
  117: severitymaps:
  118:           severitymap
  119:         | severitymaps severitymap
  120:         | error { mc_fatal ("severity ident missing"); }
  121: ;
  122: 
  123: severitymap:
  124:           token '=' MCNUMBER alias_name
  125:           {
  126:             mc_add_keyword ($1, MCTOKEN, "severity", $3, $4);
  127:           }
  128:         | token '=' error { mc_fatal ("severity number missing"); }
  129:         | token error { mc_fatal ("severity missing '='"); }
  130: ;
  131: 
  132: facilitymaps:
  133:           facilitymap
  134:         | facilitymaps facilitymap
  135:         | error { mc_fatal ("missing ident in FacilityNames"); }
  136: ;
  137: 
  138: facilitymap:
  139:           token '=' MCNUMBER alias_name
  140:           {
  141:             mc_add_keyword ($1, MCTOKEN, "facility", $3, $4);
  142:           }
  143:         | token '=' error { mc_fatal ("facility number missing"); }
  144:         | token error { mc_fatal ("facility missing '='"); }
  145: ;
  146: 
  147: langmaps:
  148:           langmap
  149:         | langmaps langmap
  150:         | error { mc_fatal ("missing ident in LanguageNames"); }
  151: ;
  152: 
  153: langmap:
  154:           token '=' MCNUMBER lex_want_filename ':' MCFILENAME
  155:           {
  156:             mc_add_keyword ($1, MCTOKEN, "language", $3, $6);
  157:           }
  158:         | token '=' MCNUMBER lex_want_filename ':' error { mc_fatal ("missing filename in LanguageNames"); }
  159:         | token '=' MCNUMBER error { mc_fatal ("missing ':' in LanguageNames"); }
  160:         | token '=' error { mc_fatal ("missing language code in LanguageNames"); }
  161:         | token error { mc_fatal ("missing '=' for LanguageNames"); }
  162: ;
  163: 
  164: alias_name:
  165:           /* empty */
  166:           {
  167:             $$ = NULL;
  168:           }
  169:         | ':' MCIDENT
  170:           {
  171:             $$ = $2;
  172:           }
  173:         | ':' error { mc_fatal ("illegal token in identifier"); $$ = NULL; }
  174: ;
  175: 
  176: message:
  177:           id sefasy_def
  178:           {
  179:             cur_node = mc_add_node ();
  180:             cur_node->symbol = mc_last_symbol;
  181:             cur_node->facility = mc_cur_facility;
  182:             cur_node->severity = mc_cur_severity;
  183:             cur_node->id = ($1 & 0xffffUL);
  184:             cur_node->vid = ($1 & 0xffffUL) | mc_sefa_val;
  185:             mc_last_id = $1;
  186:           }
  187:           lang_entities
  188: ;
  189: 
  190: id:       MCMESSAGEID '=' vid { $$ = $3; }
  191:         | MCMESSAGEID '=' error { mc_fatal ("missing number in MessageId"); $$ = 0; }
  192:         | MCMESSAGEID error { mc_fatal ("missing '=' for MessageId"); $$ = 0; }
  193: ;
  194: 
  195: vid:      /* empty */
  196:           {
  197:             $$ = ++mc_last_id;
  198:           }
  199:         | MCNUMBER
  200:           {
  201:             $$ = $1;
  202:           }
  203:         | '+' MCNUMBER
  204:           {
  205:             $$ = mc_last_id + $2;
  206:           }
  207:         | '+' error { mc_fatal ("missing number after MessageId '+'"); }
  208: ;
  209: 
  210: sefasy_def:
  211:           /* empty */
  212:           {
  213:             $$ = 0;
  214:             mc_sefa_val = (mcset_custom_bit ? 1 : 0) << 29;
  215:             mc_last_symbol = NULL;
  216:             mc_cur_severity = NULL;
  217:             mc_cur_facility = NULL;
  218:           }
  219:         | sefasy_def severity
  220:           {
  221:             if ($1 & 1)
  222:               mc_warn (_("duplicate definition of Severity"));
  223:             $$ = $1 | 1;
  224:           }
  225:         | sefasy_def facility
  226:           {
  227:             if ($1 & 2)
  228:               mc_warn (_("duplicate definition of Facility"));
  229:             $$ = $1 | 2;
  230:           }
  231:         | sefasy_def symbol
  232:           {
  233:             if ($1 & 4)
  234:               mc_warn (_("duplicate definition of SymbolicName"));
  235:             $$ = $1 | 4;
  236:           }
  237: ;
  238: 
  239: severity: MCSEVERITY '=' MCTOKEN
  240:           {
  241:             mc_sefa_val &= ~ (0x3UL << 30);
  242:             mc_sefa_val |= (($3->nval & 0x3UL) << 30);
  243:             mc_cur_severity = $3;
  244:           }
  245: ;
  246: 
  247: facility: MCFACILITY '=' MCTOKEN
  248:           {
  249:             mc_sefa_val &= ~ (0xfffUL << 16);
  250:             mc_sefa_val |= (($3->nval & 0xfffUL) << 16);
  251:             mc_cur_facility = $3;
  252:           }
  253: ;
  254: 
  255: symbol: MCSYMBOLICNAME '=' MCIDENT
  256:         {
  257:           mc_last_symbol = $3;
  258:         }
  259: ;
  260: 
  261: lang_entities:
  262:           lang_entity
  263:         | lang_entities lang_entity
  264: ;
  265: 
  266: lang_entity:
  267:           lang lex_want_line lines MCENDLINE
  268:           {
  269:             mc_node_lang *h;
  270:             h = mc_add_node_lang (cur_node, $1, cur_node->vid);
  271:             h->message = $3;
  272:             if (mcset_max_message_length != 0 && unichar_len (h->message) > mcset_max_message_length)
  273:               mc_warn ("message length to long");
  274:           }
  275: ;
  276: 
  277: lines:    MCLINE
  278:           {
  279:             $$ = $1;
  280:           }
  281:         | lines MCLINE
  282:           {
  283:             unichar *h;
  284:             rc_uint_type l1,l2;
  285:             l1 = unichar_len ($1);
  286:             l2 = unichar_len ($2);
  287:             h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
  288:             if (l1) memcpy (h, $1, l1 * sizeof (unichar));
  289:             if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar));
  290:             h[l1 + l2] = 0;
  291:             $$ = h;
  292:           }
  293:         | error { mc_fatal ("missing end of message text"); $$ = NULL; }
  294:         | lines error { mc_fatal ("missing end of message text"); $$ = $1; }
  295: ;
  296: 
  297: comments: MCCOMMENT { $$ = $1; }
  298:         | comments MCCOMMENT
  299:           {
  300:             unichar *h;
  301:             rc_uint_type l1,l2;
  302:             l1 = unichar_len ($1);
  303:             l2 = unichar_len ($2);
  304:             h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
  305:             if (l1) memcpy (h, $1, l1 * sizeof (unichar));
  306:             if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar));
  307:             h[l1 + l2] = 0;
  308:             $$ = h;
  309:           }
  310: ;
  311: 
  312: lang:     MCLANGUAGE lex_want_nl '=' MCTOKEN NL
  313:           {
  314:             $$ = $4;
  315:           }
  316:         | MCLANGUAGE lex_want_nl '=' MCIDENT NL
  317:           {
  318:             $$ = NULL;
  319:             mc_fatal (_("undeclared language identifier"));
  320:           }
  321:         | MCLANGUAGE lex_want_nl '=' token error
  322:           {
  323:             $$ = NULL;
  324:             mc_fatal ("missing newline after Language");
  325:           }
  326:         | MCLANGUAGE lex_want_nl '=' error
  327:           {
  328:             $$ = NULL;
  329:             mc_fatal ("missing ident for Language");
  330:           }
  331:         | MCLANGUAGE error
  332:           {
  333:             $$ = NULL;
  334:             mc_fatal ("missing '=' for Language");
  335:           }
  336: ;
  337: 
  338: token:  MCIDENT { $$ = $1; }
  339:         |  MCTOKEN { $$ = $1->usz; }
  340: ;
  341: 
  342: lex_want_nl:
  343:           /* Empty */  { mclex_want_nl = 1; }
  344: ;
  345: 
  346: lex_want_line:
  347:           /* Empty */  { mclex_want_line = 1; }
  348: ;
  349: 
  350: lex_want_filename:
  351:           /* Empty */  { mclex_want_filename = 1; }
  352: ;
  353: 
  354: %%
  355: 
  356: /* Something else.  */
Syntax (Markdown)