%{ /* Parser for linker scripts Copyright (C) 2001, 2002, 2003, 2004, 2005 Craig Franklin This file is part of gputils. gputils is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gputils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gputils; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdhdr.h" #include "libgputils.h" #include "gplink.h" #include "scan.h" #include "script.h" void yyerror(char *message) { script_error(message, NULL); } int yylex(void); /************************************************************************/ /* Some simple functions for building parse trees */ static struct pnode *mk_pnode(enum pnode_tag tag) { struct pnode *new = malloc(sizeof(*new)); new->tag = tag; return new; } struct pnode *mk_constant(int value) { struct pnode *new = mk_pnode(constant); new->value.constant = value; return new; } static struct pnode *mk_symbol(char *value) { struct pnode *new = mk_pnode(symbol); new->value.symbol = value; return new; } /* static struct pnode *mk_string(char *value) { struct pnode *new = mk_pnode(string); new->value.string = value; return new; } */ struct pnode *mk_list(struct pnode *head, struct pnode *tail) { struct pnode *new = mk_pnode(list); new->value.list.head = head; new->value.list.tail = tail; return new; } static struct pnode *mk_2op(int op, struct pnode *p0, struct pnode *p1) { struct pnode *new = mk_pnode(binop); new->value.binop.op = op; new->value.binop.p0 = p0; new->value.binop.p1 = p1; return new; } /* static struct pnode *mk_1op(int op, struct pnode *p0) { struct pnode *new = mk_pnode(unop); new->value.unop.op = op; new->value.unop.p0 = p0; return new; } */ %} /* Bison declarations */ %union { int i; char *s; struct pnode *p; } %token SYMBOL %token LIBPATH %token LKRPATH %token PATH %token LEXEOF %token NUMBER %type '=' %type e1op %type line %type

e0 %type

e1 %type

parameter_list %type

path_list %% /* Grammar rules */ program: /* can be nothing */ | program { /* do nothing */ } line | program error '\n' { /* do nothing */ } ; line: '\n' { /* do nothing */ } | LEXEOF { YYACCEPT; } | LIBPATH path_list '\n' { add_path($2); } | LIBPATH path_list LEXEOF { add_path($2); YYACCEPT; } | LKRPATH path_list '\n' { add_path($2); } | LKRPATH path_list LEXEOF { add_path($2); YYACCEPT; } | SYMBOL parameter_list '\n' { execute_command($1, $2); } | SYMBOL parameter_list LEXEOF { execute_command($1, $2); YYACCEPT; } ; path_list: SYMBOL { $$ = mk_list(mk_symbol($1), NULL); } | SYMBOL ';' path_list { $$ = mk_list(mk_symbol($1), $3); } ; parameter_list: e1 { $$ = mk_list($1, NULL); } | e1 parameter_list { $$ = mk_list($1, $2); } ; e1: e0 | e1 e1op e0 { $$ = mk_2op($2, $1, $3); } ; e1op: '=' ; e0: SYMBOL { $$ = mk_symbol($1); } | NUMBER { $$ = mk_constant($1); } ; %%