📄 yacc_config.y
字号:
%{/* * yacc_config.y 1.56 2002/05/16 06:07:40 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License * at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and * limitations under the License. * * The initial developer of the original code is David A. Hinds * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License version 2 (the "GPL"), in * which case the provisions of the GPL are applicable instead of the * above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use * your version of this file under the MPL, indicate your decision by * deleting the provisions above and replace them with the notice and * other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file * under either the MPL or the GPL. */ #include <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <string.h>#include <syslog.h>#include <sys/types.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h> #include "cardmgr.h"/* If bison: generate nicer error messages */ #define YYERROR_VERBOSE 1 /* from lex_config, for nice error messages */extern char *current_file;extern int current_lineno;void yyerror(char *msg, ...);static int add_binding(card_info_t *card, char *name, int fn);static int add_module(device_info_t *card, char *name);%}%token DEVICE CARD ANONYMOUS TUPLE MANFID VERSION FUNCTION PCI%token BIND CIS TO NEEDS_MTD MODULE OPTS CLASS%token REGION JEDEC DTYPE DEFAULT MTD%token INCLUDE EXCLUDE RESERVE IRQ_NO PORT MEMORY%token STRING NUMBER SOURCE%union { char *str; u_long num; struct device_info_t *device; struct card_info_t *card; struct mtd_ident_t *mtd; struct adjust_list_t *adjust;}%type <str> STRING%type <num> NUMBER%type <adjust> adjust resource%type <device> device needs_mtd module class%type <card> card anonymous tuple manfid pci version function bind cis%type <mtd> region jedec dtype default mtd%%list: /* nothing */ | list adjust { adjust_list_t **tail = &root_adjust; while (*tail != NULL) tail = &(*tail)->next; *tail = $2; } | list device { $2->next = root_device; root_device = $2; } | list mtd { if ($2->mtd_type == 0) { yyerror("no ID method for '%s'", $2->name); YYERROR; } if ($2->module == NULL) { yyerror("no MTD module for '%s'", $2->name); YYERROR; } $2->next = root_mtd; root_mtd = $2; } | list card { if ($2->ident_type == 0) { yyerror("no ID method for '%s'", $2->name); YYERROR; } if ($2->bindings == 0) { yyerror("no driver bindings for '%s'", $2->name); YYERROR; } if ($2->ident_type == FUNC_IDENT) { $2->next = root_func; root_func = $2; } else { $2->next = root_card; root_card = $2; } } | list opts | list mtd_opts | list SOURCE | list error ;adjust: INCLUDE resource { $2->adj.Action = ADD_MANAGED_RESOURCE; $$ = $2; } | EXCLUDE resource { $2->adj.Action = REMOVE_MANAGED_RESOURCE; $$ = $2; } | RESERVE resource { $2->adj.Action = ADD_MANAGED_RESOURCE; $2->adj.Attributes |= RES_RESERVED; $$ = $2; } | adjust ',' resource { $3->adj.Action = $1->adj.Action; $3->adj.Attributes = $1->adj.Attributes; $3->next = $1; $$ = $3; } ;resource: IRQ_NO NUMBER { $$ = calloc(sizeof(adjust_list_t), 1); $$->adj.Resource = RES_IRQ; $$->adj.resource.irq.IRQ = $2; } | PORT NUMBER '-' NUMBER { if (($4 < $2) || ($4 > 0xffff)) { yyerror("invalid port range 0x%x-0x%x", $2, $4); YYERROR; } $$ = calloc(sizeof(adjust_list_t), 1); $$->adj.Resource = RES_IO_RANGE; $$->adj.resource.io.BasePort = $2; $$->adj.resource.io.NumPorts = $4 - $2 + 1; } | MEMORY NUMBER '-' NUMBER { if ($4 < $2) { yyerror("invalid address range 0x%x-0x%x", $2, $4); YYERROR; } $$ = calloc(sizeof(adjust_list_t), 1); $$->adj.Resource = RES_MEMORY_RANGE; $$->adj.resource.memory.Base = $2; $$->adj.resource.memory.Size = $4 - $2 + 1; } ;device: DEVICE STRING { $$ = calloc(sizeof(device_info_t), 1); $$->refs = 1; strcpy($$->dev_info, $2); free($2); } | needs_mtd | module | class ;card: CARD STRING { $$ = calloc(sizeof(card_info_t), 1); $$->refs = 1; $$->name = $2; } | anonymous | tuple | manfid | pci | version | function | bind | cis ;anonymous: card ANONYMOUS { if ($1->ident_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } if (blank_card) { yyerror("Anonymous card already defined"); YYERROR; } $1->ident_type = BLANK_IDENT; blank_card = $1; } ;tuple: card TUPLE NUMBER ',' NUMBER ',' STRING { if ($1->ident_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->ident_type = TUPLE_IDENT; $1->id.tuple.code = $3; $1->id.tuple.ofs = $5; $1->id.tuple.info = $7; } ;manfid: card MANFID NUMBER ',' NUMBER { if ($1->ident_type & (EXCL_IDENT|MANFID_IDENT)) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->ident_type |= MANFID_IDENT; $1->manfid.manf = $3; $1->manfid.card = $5; }pci: card PCI NUMBER ',' NUMBER { if ($1->ident_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->ident_type = PCI_IDENT; $1->manfid.manf = $3; $1->manfid.card = $5; }version: card VERSION STRING { if ($1->ident_type & (EXCL_IDENT|VERS_1_IDENT)) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->ident_type |= VERS_1_IDENT; $1->id.vers.ns = 1; $1->id.vers.pi[0] = $3; } | version ',' STRING { if ($1->id.vers.ns == 4) { yyerror("too many version strings for '%s'", $1->name); YYERROR; } $1->id.vers.pi[$1->id.vers.ns] = $3; $1->id.vers.ns++; } ;function: card FUNCTION NUMBER { if ($1->ident_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->ident_type = FUNC_IDENT; $1->id.func.funcid = $3; } ;cis: card CIS STRING { $1->cis_file = strdup($3); } ;bind: card BIND STRING { if (add_binding($1, $3, 0) != 0) YYERROR; } | card BIND STRING TO NUMBER { if (add_binding($1, $3, $5) != 0) YYERROR; } | bind ',' STRING { if (add_binding($1, $3, 0) != 0) YYERROR; } | bind ',' STRING TO NUMBER { if (add_binding($1, $3, $5) != 0) YYERROR; } ;needs_mtd: device NEEDS_MTD { $1->needs_mtd = 1; } ;opts: MODULE STRING OPTS STRING { device_info_t *d; int i, found = 0; for (d = root_device; d; d = d->next) { for (i = 0; i < d->modules; i++) if (strcmp($2, d->module[i]) == 0) break; if (i < d->modules) { if (d->opts[i]) free(d->opts[i]); d->opts[i] = strdup($4); found = 1; } } free($2); free($4); if (!found) { yyerror("module name '%s' not found", $2); YYERROR; } } ;module: device MODULE STRING { if (add_module($1, $3) != 0) YYERROR; } | module OPTS STRING { if ($1->opts[$1->modules-1] == NULL) { $1->opts[$1->modules-1] = $3; } else { yyerror("too many module options for '%s'", $1->module[$1->modules-1]); YYERROR; } } | module ',' STRING { if (add_module($1, $3) != 0) YYERROR; } ;class: device CLASS STRING { if ($1->class != NULL) { yyerror("extra class string '%s'", $3); YYERROR; } $1->class = $3; } ;region: REGION STRING { $$ = calloc(sizeof(mtd_ident_t), 1); $$->refs = 1; $$->name = $2; } | dtype | jedec | default ;dtype: region DTYPE NUMBER { if ($1->mtd_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->mtd_type = DTYPE_MTD; $1->dtype = $3; } ;jedec: region JEDEC NUMBER NUMBER { if ($1->mtd_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } $1->mtd_type = JEDEC_MTD; $1->jedec_mfr = $3; $1->jedec_info = $4; } ;default: region DEFAULT { if ($1->mtd_type) { yyerror("ID method already defined for '%s'", $1->name); YYERROR; } if (default_mtd) { yyerror("Default MTD already defined"); YYERROR; } $1->mtd_type = DEFAULT_MTD; default_mtd = $1; } ;mtd: region MTD STRING { if ($1->module != NULL) { yyerror("extra MTD entry for '%s'", $1->name); YYERROR; } $1->module = $3; } | mtd OPTS STRING { if ($1->opts == NULL) { $1->opts = $3; } else { yyerror("too many module options for '%s'", $1->module); YYERROR; } } ;mtd_opts: MTD STRING OPTS STRING { mtd_ident_t *m; int found = 0; for (m = root_mtd; m; m = m->next) if (strcmp($2, m->module) == 0) break; if (m) { if (m->opts) free(m->opts); m->opts = strdup($4); found = 1; } free($2); free($4); if (!found) { yyerror("MTD name '%s' not found", $2); YYERROR; } } ;%%void yyerror(char *msg, ...){ va_list ap; char str[256]; va_start(ap, msg); sprintf(str, "error in file '%s' line %d: ", current_file, current_lineno); vsprintf(str+strlen(str), msg, ap);#if YYDEBUG fprintf(stderr, "%s\n", str);#else syslog(LOG_ERR, "%s", str);#endif va_end(ap);}static int add_binding(card_info_t *card, char *name, int fn){ device_info_t *dev = root_device; if (card->bindings == MAX_BINDINGS) { yyerror("too many bindings\n"); return -1; } for (; dev; dev = dev->next) if (strcmp((char *)dev->dev_info, name) == 0) break; if (dev == NULL) { yyerror("unknown device '%s'", name); return -1; } card->device[card->bindings] = dev; card->dev_fn[card->bindings] = fn; card->bindings++; free(name); return 0;}static int add_module(device_info_t *dev, char *name){ if (dev->modules == MAX_MODULES) { yyerror("too many modules for '%s'", dev->dev_info); return -1; } dev->module[dev->modules] = name; dev->opts[dev->modules] = NULL; dev->modules++; return 0;}#if YYDEBUGadjust_list_t *root_adjust = NULL;device_info_t *root_device = NULL;card_info_t *root_card = NULL, *blank_card = NULL, *root_func = NULL;mtd_ident_t *root_mtd = NULL, *default_mtd = NULL;void main(int argc, char *argv[]){ yydebug = 1; if (argc > 1) parse_configfile(argv[1]);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -