| %option nounput noyywrap | 
 |  | 
 | %{ | 
 |  | 
 | /* Copyright (C) 1991-2025 Free Software Foundation, Inc. | 
 |    Written by Steve Chamberlain of Cygnus Support. | 
 |  | 
 |    This file is part of the GNU Binutils. | 
 |  | 
 |    This program 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 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program 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 this program; if not, write to the Free Software | 
 |    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 
 |    MA 02110-1301, USA.  */ | 
 |  | 
 | #include "bfd.h" | 
 | #include "safe-ctype.h" | 
 | #include "bfdlink.h" | 
 | #include "ctf-api.h" | 
 | #include "ld.h" | 
 | #include "ldmisc.h" | 
 | #include "ldexp.h" | 
 | #include "ldlang.h" | 
 | #include <ldgram.h> | 
 | #include "ldfile.h" | 
 | #include "ldlex.h" | 
 | #include "ldmain.h" | 
 | #include "libiberty.h" | 
 |  | 
 | /* The type of top-level parser input. | 
 |    yylex and yyparse (indirectly) both check this.  */ | 
 | input_type parser_input; | 
 |  | 
 | /* Line number in the current input file.  */ | 
 | unsigned int lineno; | 
 |  | 
 | /* The string we are currently lexing, or NULL if we are reading a | 
 |    file.  */ | 
 | const char *lex_string = NULL; | 
 |  | 
 | /* Support for flex reading from more than one input file (stream). | 
 |    `include_stack' is flex's input state for each open file; | 
 |    `file_name_stack' is the file names.  `lineno_stack' is the current | 
 |    line numbers. | 
 |  | 
 |    If `include_stack_ptr' is 0, we haven't started reading anything yet. | 
 |    Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid.  */ | 
 |  | 
 | #undef YY_INPUT | 
 | #define YY_INPUT(buf,result,max_size) result = yy_input (buf, max_size) | 
 |  | 
 | #ifndef YY_NO_UNPUT | 
 | #define YY_NO_UNPUT | 
 | #endif | 
 |  | 
 | #define MAX_INCLUDE_DEPTH 10 | 
 | static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; | 
 | static const char *file_name_stack[MAX_INCLUDE_DEPTH]; | 
 | static unsigned int lineno_stack[MAX_INCLUDE_DEPTH]; | 
 | static unsigned int sysrooted_stack[MAX_INCLUDE_DEPTH]; | 
 | static unsigned int include_stack_ptr = 0; | 
 | static int vers_node_nesting = 0; | 
 |  | 
 | static int yy_input (char *, int); | 
 | static void comment (void); | 
 | static void lex_warn_invalid (char *where, char *what); | 
 |  | 
 | /* STATES | 
 | 	EXPRESSION	in an expression | 
 | 	SCRIPT		in a script | 
 | 	INPUTLIST	in a script, a filename-list | 
 | 	MRI		in an MRI script | 
 | 	WILD		inside the braces of an output section or overlay, | 
 | 			for input section wildcards | 
 | 	VERS_START	starting a Sun style mapfile | 
 | 	VERS_SCRIPT	a Sun style mapfile | 
 | 	VERS_NODE	a node within a Sun style mapfile | 
 | */ | 
 | #define RTOKEN(x)  {  yylval.token = x; return x; } | 
 |  | 
 | %} | 
 |  | 
 | %a 4000 | 
 | %o 5000 | 
 |  | 
 | WILDCHAR	[_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=\?\*\^\!] | 
 | FILENAMECHAR	[_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=] | 
 | NOCFILENAMECHAR	[_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]] | 
 | SYMBOLNAMECHAR  [_a-zA-Z0-9\/\.\\\$\~] | 
 | FILENAMECHAR1	[_a-zA-Z\/\.\\\$\~] | 
 | SYMBOLNAMECHAR1	[_a-zA-Z\.\\\$] | 
 | WHITE		[ \t\n\r]+ | 
 |  | 
 | V_TAG [.$_a-zA-Z][._a-zA-Z0-9]* | 
 | V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* | 
 |  | 
 | %s SCRIPT | 
 | %s INPUTLIST | 
 | %s EXPRESSION | 
 | %s MRI | 
 | %s WILD | 
 | %s VERS_START | 
 | %s VERS_SCRIPT | 
 | %s VERS_NODE | 
 | %% | 
 |  | 
 |   if (parser_input != input_selected) | 
 |     { | 
 |       /* The first token of the input determines the initial parser state.  */ | 
 |       input_type t = parser_input; | 
 |       parser_input = input_selected; | 
 |       switch (t) | 
 | 	{ | 
 | 	case input_script: return INPUT_SCRIPT; | 
 | 	case input_mri_script: return INPUT_MRI_SCRIPT; | 
 | 	case input_version_script: return INPUT_VERSION_SCRIPT; | 
 | 	case input_section_ordering_script: return INPUT_SECTION_ORDERING_SCRIPT; | 
 | 	case input_dynamic_list: return INPUT_DYNAMIC_LIST; | 
 | 	case input_defsym: return INPUT_DEFSYM; | 
 | 	default: abort (); | 
 | 	} | 
 |     } | 
 |  | 
 | <SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"/*" { | 
 | 				comment (); } | 
 |  | 
 | <MRI,EXPRESSION>"$"([0-9A-Fa-f])+ { | 
 | 				yylval.integer = strtoull (yytext + 1, 0, 16); | 
 | 				yylval.bigint.str = NULL; | 
 | 				return INT; | 
 | 			} | 
 |  | 
 | <MRI,EXPRESSION>((([0-9A-Fa-f])+(H|h|X|x))|(([0-1])+(B|b))|(([0-7])+(O|o))|(([0-9])+(D|d))) { | 
 | 				   int ibase ; | 
 | 				   switch (yytext[yyleng - 1]) { | 
 | 				    case 'X': | 
 | 				    case 'x': | 
 | 				    case 'H': | 
 | 				    case 'h': | 
 | 				     ibase = 16; | 
 | 				     break; | 
 | 				    case 'O': | 
 | 				    case 'o': | 
 | 				     ibase = 8; | 
 | 				     break; | 
 | 				    case 'B': | 
 | 				    case 'b': | 
 | 				     ibase = 2; | 
 | 				     break; | 
 | 				    default: | 
 | 				     ibase = 10; | 
 | 				   } | 
 | 				   yylval.integer = strtoull (yytext, 0, ibase); | 
 | 				   yylval.bigint.str = NULL; | 
 | 				   return INT; | 
 | 				 } | 
 | <SCRIPT,MRI,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? { | 
 | 				  char *s = yytext; | 
 | 				  int ibase = 0; | 
 |  | 
 | 				  if (*s == '$') | 
 | 				    { | 
 | 				      ++s; | 
 | 				      ibase = 16; | 
 | 				    } | 
 | 				  yylval.integer = strtoull (s, 0, ibase); | 
 | 				  yylval.bigint.str = NULL; | 
 | 				  if (yytext[yyleng - 1] == 'M' | 
 | 				      || yytext[yyleng - 1] == 'm') | 
 | 				    { | 
 | 				      yylval.integer *= 1024 * 1024; | 
 | 				    } | 
 | 				  else if (yytext[yyleng - 1] == 'K' | 
 | 				      || yytext[yyleng - 1]=='k') | 
 | 				    { | 
 | 				      yylval.integer *= 1024; | 
 | 				    } | 
 | 				  else if (yytext[0] == '0' | 
 | 					   && (yytext[1] == 'x' | 
 | 					       || yytext[1] == 'X')) | 
 | 				    { | 
 | 				      yylval.bigint.str | 
 | 					= stat_strdup (yytext + 2); | 
 | 				    } | 
 | 				  return INT; | 
 | 				} | 
 |  | 
 |   /* Some tokens that only appear in expressions must be enabled for | 
 |      states other than EXPRESSION, since parser lookahead means they | 
 |      must be recognised before the parser switches the lexer out of | 
 |      SCRIPT or WILD state into EXPRESSION state. | 
 |  | 
 |      This sort of thing happens for example with NAME in ldgram.y | 
 |      "section" rule, which is immediately followed by ldlex_expression. | 
 |      However, if you follow the grammar from "sec_or_group_p1" you see | 
 |      "assignment" appearing in "statement_anywhere".  Now, | 
 |      "assignment" also has NAME as its first token, just like | 
 |      "section".  So the parser can't know whether it is in the | 
 |      "section" or the "assignment" rule until it has scanned the next | 
 |      token to find an assignment operator.  Thus the next token after | 
 |      NAME in the "section" rule may be lexed before the lexer is | 
 |      switched to EXPRESSION state, and there are quite a number of | 
 |      optional components.  The first token in all those components | 
 |      must be able to be lexed in SCRIPT state, as well as the | 
 |      assignment operators.  In fact, due to "opt_exp_with_type", | 
 |      anything that can appear on the left hand side of "exp" might | 
 |      need to be lexed in SCRIPT state. | 
 |  | 
 |      MRI mode tends to cover everything in MRI scripts. | 
 |   */ | 
 | <MRI,WILD>"]"				{ RTOKEN(']'); } | 
 | <MRI,WILD>"["				{ RTOKEN('['); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"<<="	{ RTOKEN(LSHIFTEQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>">>="	{ RTOKEN(RSHIFTEQ); } | 
 | <EXPRESSION,MRI>"||"			{ RTOKEN(OROR); } | 
 | <EXPRESSION,MRI>"=="			{ RTOKEN(EQ); } | 
 | <EXPRESSION,MRI>"!="			{ RTOKEN(NE); } | 
 | <EXPRESSION,MRI>">="			{ RTOKEN(GE); } | 
 | <EXPRESSION,MRI>"<="			{ RTOKEN(LE); } | 
 | <EXPRESSION,MRI>"<<"			{ RTOKEN(LSHIFT); } | 
 | <EXPRESSION,MRI>">>"			{ RTOKEN(RSHIFT); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"+="	{ RTOKEN(PLUSEQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"-="	{ RTOKEN(MINUSEQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"*="	{ RTOKEN(MULTEQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"/="	{ RTOKEN(DIVEQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"&="	{ RTOKEN(ANDEQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"|="	{ RTOKEN(OREQ); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"^="	{ RTOKEN(XOREQ); } | 
 | <EXPRESSION,MRI>"&&"			{ RTOKEN(ANDAND); } | 
 | <SCRIPT,EXPRESSION,MRI>">"		{ RTOKEN('>'); } | 
 | <SCRIPT,EXPRESSION,MRI,INPUTLIST>","	{ RTOKEN(','); } | 
 | <EXPRESSION,MRI,WILD>"&"		{ RTOKEN('&'); } | 
 | <EXPRESSION,MRI>"|"			{ RTOKEN('|'); } | 
 | <SCRIPT,EXPRESSION,MRI>"~"		{ RTOKEN('~'); } | 
 | <SCRIPT,EXPRESSION,MRI>"!"		{ RTOKEN('!'); } | 
 | <EXPRESSION,MRI>"?"			{ RTOKEN('?'); } | 
 | <EXPRESSION,MRI>"*"			{ RTOKEN('*'); } | 
 | <SCRIPT,EXPRESSION,MRI>"+"		{ RTOKEN('+'); } | 
 | <SCRIPT,EXPRESSION,MRI>"-"		{ RTOKEN('-'); } | 
 | <EXPRESSION,MRI>"/"			{ RTOKEN('/'); } | 
 | <EXPRESSION,MRI>"%"			{ RTOKEN('%'); } | 
 | <EXPRESSION,MRI>"<"			{ RTOKEN('<'); } | 
 | <EXPRESSION,MRI>"^"			{ RTOKEN('^'); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"="		{ RTOKEN('='); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"}"		{ RTOKEN('}'); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>"{"		{ RTOKEN('{'); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>")" { RTOKEN(')'); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>"(" { RTOKEN('('); } | 
 | <SCRIPT,EXPRESSION,MRI>":"		{ RTOKEN(':'); } | 
 | <SCRIPT,EXPRESSION,MRI,WILD>";"		{ RTOKEN(';'); } | 
 | <SCRIPT>"MEMORY"			{ RTOKEN(MEMORY); } | 
 | <SCRIPT>"REGION_ALIAS"			{ RTOKEN(REGION_ALIAS); } | 
 | <SCRIPT>"LD_FEATURE"			{ RTOKEN(LD_FEATURE); } | 
 | <SCRIPT,EXPRESSION>"ORIGIN"		{ RTOKEN(ORIGIN); } | 
 | <SCRIPT>"VERSION"			{ RTOKEN(VERSIONK); } | 
 | <SCRIPT,EXPRESSION>"BLOCK"		{ RTOKEN(BLOCK); } | 
 | <SCRIPT,EXPRESSION>"BIND"		{ RTOKEN(BIND); } | 
 | <SCRIPT,EXPRESSION>"LENGTH"		{ RTOKEN(LENGTH); } | 
 | <SCRIPT,EXPRESSION>"ALIGN"		{ RTOKEN(ALIGN_K); } | 
 | <SCRIPT,EXPRESSION>"DATA_SEGMENT_ALIGN"	{ RTOKEN(DATA_SEGMENT_ALIGN); } | 
 | <SCRIPT,EXPRESSION>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END); } | 
 | <SCRIPT,EXPRESSION>"DATA_SEGMENT_END"	{ RTOKEN(DATA_SEGMENT_END); } | 
 | <SCRIPT,EXPRESSION>"ADDR"		{ RTOKEN(ADDR); } | 
 | <SCRIPT,EXPRESSION>"LOADADDR"		{ RTOKEN(LOADADDR); } | 
 | <SCRIPT,EXPRESSION>"ALIGNOF"		{ RTOKEN(ALIGNOF); } | 
 | <SCRIPT,EXPRESSION>"ABSOLUTE"		{ RTOKEN(ABSOLUTE); } | 
 | <SCRIPT,EXPRESSION>"MAX"		{ RTOKEN(MAX_K); } | 
 | <SCRIPT,EXPRESSION>"MIN"		{ RTOKEN(MIN_K); } | 
 | <SCRIPT,EXPRESSION>"LOG2CEIL"		{ RTOKEN(LOG2CEIL); } | 
 | <SCRIPT,EXPRESSION,WILD>"ASSERT"	{ RTOKEN(ASSERT_K); } | 
 | <SCRIPT>"ENTRY"				{ RTOKEN(ENTRY); } | 
 | <SCRIPT,MRI>"EXTERN"			{ RTOKEN(EXTERN); } | 
 | <SCRIPT,EXPRESSION>"NEXT"		{ RTOKEN(NEXT); } | 
 | <SCRIPT,EXPRESSION>"SIZEOF_HEADERS"	{ RTOKEN(SIZEOF_HEADERS); } | 
 | <SCRIPT,EXPRESSION>"SEGMENT_START"	{ RTOKEN(SEGMENT_START); } | 
 | <SCRIPT>"MAP"				{ RTOKEN(MAP); } | 
 | <SCRIPT,EXPRESSION>"SIZEOF"		{ RTOKEN(SIZEOF); } | 
 | <SCRIPT>"TARGET"			{ RTOKEN(TARGET_K); } | 
 | <SCRIPT>"SEARCH_DIR"			{ RTOKEN(SEARCH_DIR); } | 
 | <SCRIPT>"OUTPUT"			{ RTOKEN(OUTPUT); } | 
 | <SCRIPT>"INPUT"				{ RTOKEN(INPUT); } | 
 | <SCRIPT>"GROUP"				{ RTOKEN(GROUP); } | 
 | <INPUTLIST>"AS_NEEDED"			{ RTOKEN(AS_NEEDED); } | 
 | <SCRIPT,EXPRESSION>"DEFINED"		{ RTOKEN(DEFINED); } | 
 | <WILD>"CREATE_OBJECT_SYMBOLS"		{ RTOKEN(CREATE_OBJECT_SYMBOLS); } | 
 | <WILD>"CONSTRUCTORS"			{ RTOKEN(CONSTRUCTORS); } | 
 | <SCRIPT>"FORCE_COMMON_ALLOCATION"	{ RTOKEN(FORCE_COMMON_ALLOCATION); } | 
 | <SCRIPT>"FORCE_GROUP_ALLOCATION"	{ RTOKEN(FORCE_GROUP_ALLOCATION); } | 
 | <SCRIPT>"INHIBIT_COMMON_ALLOCATION"	{ RTOKEN(INHIBIT_COMMON_ALLOCATION); } | 
 | <SCRIPT>"SECTIONS"			{ RTOKEN(SECTIONS); } | 
 | <SCRIPT>"INSERT"			{ RTOKEN(INSERT_K); } | 
 | <SCRIPT>"AFTER"				{ RTOKEN(AFTER); } | 
 | <SCRIPT>"BEFORE"			{ RTOKEN(BEFORE); } | 
 | <WILD>"FILL"				{ RTOKEN(FILL); } | 
 | <SCRIPT>"STARTUP"			{ RTOKEN(STARTUP); } | 
 | <SCRIPT>"OUTPUT_FORMAT"			{ RTOKEN(OUTPUT_FORMAT); } | 
 | <SCRIPT>"OUTPUT_ARCH"			{ RTOKEN(OUTPUT_ARCH); } | 
 | <SCRIPT>"HLL"				{ RTOKEN(HLL); } | 
 | <SCRIPT>"SYSLIB"			{ RTOKEN(SYSLIB); } | 
 | <SCRIPT>"FLOAT"				{ RTOKEN(FLOAT); } | 
 | <WILD>"QUAD"				{ RTOKEN(QUAD); } | 
 | <WILD>"SQUAD"				{ RTOKEN(SQUAD); } | 
 | <WILD>"LONG"				{ RTOKEN(LONG); } | 
 | <WILD>"SHORT"				{ RTOKEN(SHORT); } | 
 | <WILD>"BYTE"				{ RTOKEN(BYTE); } | 
 | <WILD>"ASCIZ"				{ RTOKEN(ASCIZ); } | 
 | <WILD>"LINKER_VERSION"			{ RTOKEN(LINKER_VERSION); } | 
 | <SCRIPT>"NOFLOAT"			{ RTOKEN(NOFLOAT); } | 
 | <SCRIPT,EXPRESSION>"NOCROSSREFS"	{ RTOKEN(NOCROSSREFS); } | 
 | <SCRIPT,EXPRESSION>"NOCROSSREFS_TO"	{ RTOKEN(NOCROSSREFS_TO); } | 
 | <SCRIPT,EXPRESSION>"OVERLAY"		{ RTOKEN(OVERLAY); } | 
 | <WILD>"SORT_BY_NAME"			{ RTOKEN(SORT_BY_NAME); } | 
 | <WILD>"SORT_BY_ALIGNMENT"		{ RTOKEN(SORT_BY_ALIGNMENT); } | 
 | <WILD>"SORT"				{ RTOKEN(SORT_BY_NAME); } | 
 | <WILD>"SORT_BY_INIT_PRIORITY"		{ RTOKEN(SORT_BY_INIT_PRIORITY); } | 
 | <WILD>"SORT_NONE"			{ RTOKEN(SORT_NONE); } | 
 | <WILD>"REVERSE"				{ RTOKEN(REVERSE); } | 
 | <EXPRESSION>"NOLOAD"			{ RTOKEN(NOLOAD); } | 
 | <EXPRESSION>"READONLY"			{ RTOKEN(READONLY); } | 
 | <EXPRESSION>"DSECT"			{ RTOKEN(DSECT); } | 
 | <EXPRESSION>"COPY"			{ RTOKEN(COPY); } | 
 | <EXPRESSION>"INFO"			{ RTOKEN(INFO); } | 
 | <EXPRESSION>"TYPE"			{ RTOKEN(TYPE); } | 
 | <SCRIPT,EXPRESSION>"ONLY_IF_RO"		{ RTOKEN(ONLY_IF_RO); } | 
 | <SCRIPT,EXPRESSION>"ONLY_IF_RW"		{ RTOKEN(ONLY_IF_RW); } | 
 | <SCRIPT,EXPRESSION>"SPECIAL"		{ RTOKEN(SPECIAL); } | 
 | <SCRIPT>"o"				{ RTOKEN(ORIGIN); } | 
 | <SCRIPT>"org"				{ RTOKEN(ORIGIN); } | 
 | <SCRIPT>"l"				{ RTOKEN(LENGTH); } | 
 | <SCRIPT>"len"				{ RTOKEN(LENGTH); } | 
 | <WILD>"INPUT_SECTION_FLAGS"		{ RTOKEN(INPUT_SECTION_FLAGS); } | 
 | <SCRIPT,EXPRESSION,WILD,MRI>"INCLUDE"	{ RTOKEN(INCLUDE);} | 
 | <SCRIPT>"PHDRS"				{ RTOKEN(PHDRS); } | 
 | <SCRIPT,EXPRESSION,WILD>"AT"		{ RTOKEN(AT);} | 
 | <SCRIPT,EXPRESSION>"ALIGN_WITH_INPUT"	{ RTOKEN(ALIGN_WITH_INPUT);} | 
 | <SCRIPT,EXPRESSION>"SUBALIGN"		{ RTOKEN(SUBALIGN);} | 
 | <SCRIPT,EXPRESSION,WILD>"HIDDEN"	{ RTOKEN(HIDDEN); } | 
 | <SCRIPT,EXPRESSION,WILD>"PROVIDE"	{ RTOKEN(PROVIDE); } | 
 | <SCRIPT,EXPRESSION,WILD>"PROVIDE_HIDDEN" { RTOKEN(PROVIDE_HIDDEN); } | 
 | <WILD>"KEEP"				{ RTOKEN(KEEP); } | 
 | <WILD>"EXCLUDE_FILE"			{ RTOKEN(EXCLUDE_FILE); } | 
 | <SCRIPT,EXPRESSION>"CONSTANT"		{ RTOKEN(CONSTANT);} | 
 |  | 
 | <MRI>"#".*\n?			{ ++ lineno; } | 
 | <MRI>"\n"			{ ++ lineno;  RTOKEN(NEWLINE); } | 
 | <MRI>"*".*			{ /* Mri comment line */ } | 
 | <MRI>";".*			{ /* Mri comment line */ } | 
 | <MRI>"END"			{ RTOKEN(ENDWORD); } | 
 | <MRI>"ABSOLUTE"			{ RTOKEN(ABSOLUTE); } | 
 | <MRI>"ALIGNMOD"			{ RTOKEN(ALIGNMOD);} | 
 | <MRI>"ALIGN"			{ RTOKEN(ALIGN_K);} | 
 | <MRI>"CHIP"			{ RTOKEN(CHIP); } | 
 | <MRI>"BASE"			{ RTOKEN(BASE); } | 
 | <MRI>"ALIAS"			{ RTOKEN(ALIAS); } | 
 | <MRI>"TRUNCATE"			{ RTOKEN(TRUNCATE); } | 
 | <MRI>"LOAD"			{ RTOKEN(LOAD); } | 
 | <MRI>"PUBLIC"			{ RTOKEN(PUBLIC); } | 
 | <MRI>"ORDER"			{ RTOKEN(ORDER); } | 
 | <MRI>"NAME"			{ RTOKEN(NAMEWORD); } | 
 | <MRI>"FORMAT"			{ RTOKEN(FORMAT); } | 
 | <MRI>"CASE"			{ RTOKEN(CASE); } | 
 | <MRI>"START"			{ RTOKEN(START); } | 
 | <MRI>"LIST".*			{ RTOKEN(LIST); /* LIST and ignore to end of line */ } | 
 | <MRI>"SECT"			{ RTOKEN(SECT); } | 
 | <MRI>"end"			{ RTOKEN(ENDWORD); } | 
 | <MRI>"absolute"			{ RTOKEN(ABSOLUTE); } | 
 | <MRI>"alignmod"			{ RTOKEN(ALIGNMOD);} | 
 | <MRI>"align"			{ RTOKEN(ALIGN_K);} | 
 | <MRI>"chip"			{ RTOKEN(CHIP); } | 
 | <MRI>"base"			{ RTOKEN(BASE); } | 
 | <MRI>"alias"			{ RTOKEN(ALIAS); } | 
 | <MRI>"truncate"			{ RTOKEN(TRUNCATE); } | 
 | <MRI>"load"			{ RTOKEN(LOAD); } | 
 | <MRI>"public"			{ RTOKEN(PUBLIC); } | 
 | <MRI>"order"			{ RTOKEN(ORDER); } | 
 | <MRI>"name"			{ RTOKEN(NAMEWORD); } | 
 | <MRI>"format"			{ RTOKEN(FORMAT); } | 
 | <MRI>"case"			{ RTOKEN(CASE); } | 
 | <MRI>"extern"			{ RTOKEN(EXTERN); } | 
 | <MRI>"start"			{ RTOKEN(START); } | 
 | <MRI>"list".*			{ RTOKEN(LIST); /* LIST and ignore to end of line */ } | 
 | <MRI>"sect"			{ RTOKEN(SECT); } | 
 |  | 
 | <MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}*	{ | 
 | /* Filename without commas, needed to parse mri stuff */ | 
 | 				  yylval.name = stat_strdup (yytext); | 
 | 				  return NAME; | 
 | 				} | 
 |  | 
 |  | 
 | <SCRIPT,INPUTLIST>{FILENAMECHAR1}{FILENAMECHAR}*	{ | 
 | 				  yylval.name = stat_strdup (yytext); | 
 | 				  return NAME; | 
 | 				} | 
 | <INPUTLIST>"="{FILENAMECHAR1}{FILENAMECHAR}*	{ | 
 | /* Filename to be prefixed by --sysroot or when non-sysrooted, nothing.  */ | 
 | 				  yylval.name = stat_strdup (yytext); | 
 | 				  return NAME; | 
 | 				} | 
 | <INPUTLIST>"-l"{FILENAMECHAR}+ { | 
 | 				  yylval.name = stat_strdup (yytext + 2); | 
 | 				  return LNAME; | 
 | 				} | 
 | <EXPRESSION>{SYMBOLNAMECHAR1}{SYMBOLNAMECHAR}* { | 
 | 				  yylval.name = stat_strdup (yytext); | 
 | 				  return NAME; | 
 | 				} | 
 |   /* The following rule is to prevent a fill expression on the output | 
 |      section before /DISCARD/ interpreting the '/' as a divide.  */ | 
 | <EXPRESSION>"/DISCARD/"		{ | 
 | 				  yylval.name = stat_strdup (yytext); | 
 | 				  return NAME; | 
 | 				} | 
 | <WILD>{WILDCHAR}* { | 
 | 		/* Annoyingly, this pattern can match comments, and we have | 
 | 		   longest match issues to consider.  So if the first two | 
 | 		   characters are a comment opening, put the input back and | 
 | 		   try again.  */ | 
 | 		if (yytext[0] == '/' && yytext[1] == '*') | 
 | 		  { | 
 | 		    yyless (2); | 
 | 		    comment (); | 
 | 		  } | 
 | 		else | 
 | 		  { | 
 | 		    yylval.name = stat_strdup (yytext); | 
 | 		    return NAME; | 
 | 		  } | 
 | 	} | 
 |  | 
 | <SCRIPT,EXPRESSION,WILD,VERS_NODE,INPUTLIST>"\""[^\"]*"\"" { | 
 | 		/* No matter the state, quotes give what's inside.  */ | 
 | 		yylval.name = stat_memdup (yytext + 1, yyleng - 2, yyleng - 1); | 
 | 		return NAME; | 
 | 	} | 
 |  | 
 | <SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"\n" { | 
 | 				lineno++; } | 
 | <MRI,SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>[ \t\r]+ { | 
 | 				/* Eat up whitespace */ } | 
 | <SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT>#.* { | 
 | 				/* Eat up comments */ } | 
 |  | 
 | <VERS_NODE,VERS_SCRIPT>[:,;]	{ return *yytext; } | 
 |  | 
 | <VERS_NODE>global		{ RTOKEN(GLOBAL); } | 
 |  | 
 | <VERS_NODE>local		{ RTOKEN(LOCAL); } | 
 |  | 
 | <VERS_NODE>extern		{ RTOKEN(EXTERN); } | 
 |  | 
 | <VERS_NODE>{V_IDENTIFIER}	{ yylval.name = stat_strdup (yytext); | 
 | 				  return VERS_IDENTIFIER; } | 
 |  | 
 | <VERS_SCRIPT>{V_TAG}		{ yylval.name = stat_strdup (yytext); | 
 | 				  return VERS_TAG; } | 
 |  | 
 | <VERS_START>"{"			{ BEGIN(VERS_SCRIPT); return *yytext; } | 
 |  | 
 | <VERS_SCRIPT>"{"		{ BEGIN(VERS_NODE); | 
 | 				  vers_node_nesting = 0; | 
 | 				  return *yytext; | 
 | 				} | 
 | <VERS_SCRIPT>"}"		{ return *yytext; } | 
 | <VERS_NODE>"{"			{ vers_node_nesting++; return *yytext; } | 
 | <VERS_NODE>"}"			{ if (--vers_node_nesting < 0) | 
 | 				    BEGIN(VERS_SCRIPT); | 
 | 				  return *yytext; | 
 | 				} | 
 |  | 
 | <<EOF>> { | 
 |   yy_delete_buffer (YY_CURRENT_BUFFER); | 
 |   include_stack_ptr--; | 
 |   if (include_stack_ptr == 0) | 
 |     { | 
 |       lineno = 0; | 
 |       yyterminate (); | 
 |     } | 
 |   else | 
 |     yy_switch_to_buffer (include_stack[include_stack_ptr]); | 
 |  | 
 |   lineno = lineno_stack[include_stack_ptr]; | 
 |   input_flags.sysrooted = sysrooted_stack[include_stack_ptr]; | 
 |  | 
 |   return END; | 
 | } | 
 |  | 
 | <SCRIPT,WILD,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>.	lex_warn_invalid (_(" in script"), yytext); | 
 | <EXPRESSION>.	lex_warn_invalid (_(" in expression"), yytext); | 
 |  | 
 | %% | 
 |  | 
 |  | 
 | /* Switch flex to reading script file NAME, open on FILE, | 
 |    saving the current input info on the include stack.  */ | 
 |  | 
 | void | 
 | lex_push_file (FILE *file, const char *name, unsigned int sysrooted) | 
 | { | 
 |   if (include_stack_ptr >= MAX_INCLUDE_DEPTH) | 
 |     fatal (_("%P: includes nested too deeply\n")); | 
 |   file_name_stack[include_stack_ptr] = name; | 
 |   lineno_stack[include_stack_ptr] = lineno; | 
 |   sysrooted_stack[include_stack_ptr] = input_flags.sysrooted; | 
 |   include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; | 
 |  | 
 |   include_stack_ptr++; | 
 |   lineno = 1; | 
 |   input_flags.sysrooted = sysrooted; | 
 |   yyin = file; | 
 |   yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE)); | 
 | } | 
 |  | 
 | /* Return a newly created flex input buffer containing STRING, | 
 |    which is SIZE bytes long.  */ | 
 |  | 
 | static YY_BUFFER_STATE | 
 | yy_create_string_buffer (const char *string, size_t size) | 
 | { | 
 |   YY_BUFFER_STATE b; | 
 |  | 
 |   b = xmalloc (sizeof (struct yy_buffer_state)); | 
 |   b->yy_input_file = 0; | 
 |   b->yy_buf_size = size; | 
 |  | 
 |   /* yy_ch_buf has to be 2 characters longer than the size given because | 
 |      we need to put in 2 end-of-buffer characters.  */ | 
 |   b->yy_ch_buf = xmalloc (b->yy_buf_size + 3); | 
 |  | 
 |   b->yy_ch_buf[0] = '\n'; | 
 |   strcpy (b->yy_ch_buf+1, string); | 
 |   b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR; | 
 |   b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR; | 
 |   b->yy_n_chars = size+1; | 
 |   b->yy_buf_pos = &b->yy_ch_buf[1]; | 
 |  | 
 |   b->yy_is_our_buffer = 1; | 
 |   b->yy_is_interactive = 0; | 
 |   b->yy_at_bol = 1; | 
 |   b->yy_fill_buffer = 0; | 
 |  | 
 |   /* flex 2.4.7 changed the interface.  FIXME: We should not be using | 
 |      a flex internal interface in the first place!  */ | 
 | #ifdef YY_BUFFER_NEW | 
 |   b->yy_buffer_status = YY_BUFFER_NEW; | 
 | #else | 
 |   b->yy_eof_status = EOF_NOT_SEEN; | 
 | #endif | 
 |  | 
 |   return b; | 
 | } | 
 |  | 
 | /* Switch flex to reading from STRING, saving the current input info | 
 |    on the include stack.  */ | 
 |  | 
 | void | 
 | lex_redirect (const char *string, const char *fake_filename, unsigned int count) | 
 | { | 
 |   YY_BUFFER_STATE tmp; | 
 |  | 
 |   yy_init = 0; | 
 |   if (include_stack_ptr >= MAX_INCLUDE_DEPTH) | 
 |     fatal (_("%P: macros nested too deeply\n")); | 
 |   file_name_stack[include_stack_ptr] = fake_filename; | 
 |   lineno_stack[include_stack_ptr] = lineno; | 
 |   include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; | 
 |   include_stack_ptr++; | 
 |   lineno = count; | 
 |   tmp = yy_create_string_buffer (string, strlen (string)); | 
 |   yy_switch_to_buffer (tmp); | 
 | } | 
 |  | 
 | /* Functions to switch to a different flex start condition, | 
 |    saving the current start condition on `state_stack'.  */ | 
 |  | 
 | static int state_stack[MAX_INCLUDE_DEPTH * 2]; | 
 | static int *state_stack_p = state_stack; | 
 |  | 
 | void | 
 | ldlex_script (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (SCRIPT); | 
 | } | 
 |  | 
 | void | 
 | ldlex_inputlist (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (INPUTLIST); | 
 | } | 
 |  | 
 | void | 
 | ldlex_mri_script (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (MRI); | 
 | } | 
 |  | 
 | void | 
 | ldlex_version_script (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (VERS_START); | 
 | } | 
 |  | 
 | void | 
 | ldlex_version_file (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (VERS_SCRIPT); | 
 | } | 
 |  | 
 | void | 
 | ldlex_expression (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (EXPRESSION); | 
 | } | 
 |  | 
 | void | 
 | ldlex_wild (void) | 
 | { | 
 |   *(state_stack_p)++ = yy_start; | 
 |   BEGIN (WILD); | 
 | } | 
 |  | 
 | void | 
 | ldlex_popstate (void) | 
 | { | 
 |   yy_start = *(--state_stack_p); | 
 | } | 
 |  | 
 | /* In cases where the parser needs to look ahead and the context | 
 |    changes from expression to script or vice-versa, throw away a | 
 |    NAME.  What constitutes a NAME depends on context.  */ | 
 |  | 
 | void | 
 | ldlex_backup (void) | 
 | { | 
 |   yyless (0); | 
 | } | 
 |  | 
 | /* Return the current file name, or the previous file if no file is | 
 |    current.  */ | 
 |  | 
 | const char* | 
 | ldlex_filename (void) | 
 | { | 
 |   return file_name_stack[include_stack_ptr - (include_stack_ptr != 0)]; | 
 | } | 
 |  | 
 |  | 
 | /* Place up to MAX_SIZE characters in BUF and return | 
 |    either the number of characters read, or 0 to indicate EOF.  */ | 
 |  | 
 | static int | 
 | yy_input (char *buf, int max_size) | 
 | { | 
 |   int result = 0; | 
 |   if (YY_CURRENT_BUFFER != NULL && YY_CURRENT_BUFFER->yy_input_file) | 
 |     { | 
 |       if (yyin) | 
 | 	{ | 
 | 	  result = fread (buf, 1, max_size, yyin); | 
 | 	  if (result < max_size && ferror (yyin)) | 
 | 	    fatal (_("%P: read in flex scanner failed\n")); | 
 | 	} | 
 |     } | 
 |   return result; | 
 | } | 
 |  | 
 | /* Eat the rest of a C-style comment.  */ | 
 |  | 
 | static void | 
 | comment (void) | 
 | { | 
 |   int c; | 
 |  | 
 |   while (1) | 
 |     { | 
 |       c = input(); | 
 |       while (c != '*' && c != 0) | 
 | 	{ | 
 | 	  if (c == '\n') | 
 | 	    lineno++; | 
 | 	  c = input(); | 
 | 	} | 
 |  | 
 |       if (c == '*') | 
 | 	{ | 
 | 	  c = input(); | 
 | 	  while (c == '*') | 
 | 	    c = input(); | 
 | 	  if (c == '/') | 
 | 	    break;			/* found the end */ | 
 | 	} | 
 |  | 
 |       if (c == '\n') | 
 | 	lineno++; | 
 |  | 
 |       if (c == 0) | 
 | 	{ | 
 | 	  fatal (_("%P: EOF in comment\n")); | 
 | 	  break; | 
 | 	} | 
 |     } | 
 | } | 
 |  | 
 | /* Warn the user about a garbage character WHAT in the input | 
 |    in context WHERE.  */ | 
 |  | 
 | static void | 
 | lex_warn_invalid (char *where, char *what) | 
 | { | 
 |   char buf[5]; | 
 |  | 
 |   /* If we have found an input file whose format we do not recognize, | 
 |      and we are therefore treating it as a linker script, and we find | 
 |      an invalid character, then most likely this is a real object file | 
 |      of some different format.  Treat it as such.  */ | 
 |   if (ldfile_assumed_script) | 
 |     { | 
 |       bfd_set_error (bfd_error_file_not_recognized); | 
 |       fatal (_("%s: file not recognized: %E\n"), ldlex_filename ()); | 
 |     } | 
 |  | 
 |   if (! ISPRINT (*what)) | 
 |     { | 
 |       sprintf (buf, "\\%03o", *(unsigned char *) what); | 
 |       what = buf; | 
 |     } | 
 |  | 
 |   einfo (_("%P:%pS: ignoring invalid character `%s'%s\n"), NULL, what, where); | 
 | } |