/*SUPPRESS 529*/
/*SUPPRESS 26*/
/*SUPPRESS 29*/
-#define LEXDEBUG
+#define LEXDEBUG 0
#include "sysdep.h"
#include "bfd.h"
#define unput lex_unput
int debug;
-extern boolean ldgram_in_expression;
-extern boolean ldgram_in_defsym;
+static boolean ldgram_in_defsym;
+static boolean ldgram_had_equals;
+extern boolean ldgram_in_script;
static char *command_line;
extern int fgetc();
#define RTOKEN(x) { yylval.token = x; return x; }
keyword_type keywords[] =
{
+"/", '/',
"MEMORY",MEMORY,
"ORIGIN",ORIGIN,
"BLOCK",BLOCK,
"LENGTH",LENGTH,
"ALIGN",ALIGN_K,
-"SUBSECTION_ALIGN",SUBSECTION_ALIGN,
"ADDR",ADDR,
"ENTRY",ENTRY,
"NEXT",NEXT,
+"sizeof_headers",SIZEOF_HEADERS,
+"SIZEOF_HEADERS",SIZEOF_HEADERS,
"MAP",MAP,
"SIZEOF",SIZEOF,
"TARGET",TARGET_K,
"INPUT",INPUT,
"DEFINED",DEFINED,
"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
+"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
"SECTIONS",SECTIONS,
"FILL",FILL,
"STARTUP",STARTUP,
+"OUTPUT_FORMAT",OUTPUT_FORMAT,
+"OUTPUT_ARCH", OUTPUT_ARCH,
"HLL",HLL,
"SYSLIB",SYSLIB,
"FLOAT",FLOAT,
extern boolean hex_mode;
FILE *ldlex_input_stack;
static unsigned int have_pushback;
+
#define NPUSHBACK 10
int pushback[NPUSHBACK];
int thischar;
extern char *ldfile_input_filename;
-
+int donehash = 0;
int
lex_input()
{
-
-
if (have_pushback > 0)
- {
- have_pushback --;
- return thischar = pushback[have_pushback];
- }
+ {
+ have_pushback --;
+ return thischar = pushback[have_pushback];
+ }
if (ldlex_input_stack) {
thischar = fgetc(ldlex_input_stack);
fclose(ldlex_input_stack);
ldlex_input_stack = (FILE *)NULL;
ldfile_input_filename = (char *)NULL;
- thischar = lex_input();
+ /* First char after script eof is a @ so that we can tell the grammer
+ that we've left */
+ thischar = '@';
}
}
else if (command_line && *command_line) {
thischar = *(command_line++);
}
- else thischar = 0;
+ else {
+ thischar = 0;
+ }
if(thischar == '\t') thischar = ' ';
if (thischar == '\n') { thischar = ' '; lineno++; }
return thischar ;
}
-long number(text, base)
-char *text;
-int base;
+static long
+DEFUN(number,(default_if_zero,base),
+ int default_if_zero AND
+ int base)
{
-unsigned long l = 0;
- char *p;
- for (p = text; *p != 0; p++) {
- if (*p == 'K') {
+ unsigned long l = 0;
+ int ch = yytext[0];
+ if (ch == 0) {
+ base = default_if_zero;
+ }
+ while (1) {
+ switch (ch) {
+ case 'x':
+ base = 16;
+ break;
+ case 'k':
+ case 'K':
l =l * 1024;
- }
- else if(*p== 'M') {
+ break;
+ case 'm':
+ case 'M':
l =l * 1024 * 1024;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ l = l * base + ch - '0';
+ break;
+ case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
+ l =l *base + ch - 'a' + 10;
+ break;
+ case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
+ l =l *base + ch - 'A' + 10;
+ break;
+ default:
+ unput(ch);
+ yylval.integer = l;
+ return INT;
}
- else {
- l =l * base;
- if (isdigit(*p)) {
- l += *p - '0';
- }
- else if (islower(*p)) {
- l += *p - 'a' + 10;
- }
- else {
- l += *p - 'A' + 10;
- }
- }
+ch = input();
}
- return l;
}
%}
%a 4000
%o 5000
-FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+]
+FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
FILENAME {FILENAMECHAR}+
-
-
-WHITE [ \t]+
+WHITE [ \t]+
%%
-
-"\ -defsym" { return OPTION_defsym; }
-"\ -noinhibit_exec" { return OPTION_noinhibit_exec; }
-"\ -format" { return OPTION_format; }
-"\ -n" { return OPTION_n; }
-"\ -r" { return OPTION_r; }
-"\ -Ur" { return OPTION_Ur; }
-"\ -o" { return OPTION_o; }
-"\ -g" { return OPTION_g; }
-"\ -e" { return OPTION_e; }
-"\ -b" { return OPTION_b; }
-"\ -dc" { return OPTION_dc; }
-"\ -dp" { return OPTION_dp; }
-"\ -d" { return OPTION_d; }
-"\ -v" { return OPTION_v; }
-"\ -M" { return OPTION_M; }
-"\ -t" { return OPTION_t; }
-"\ -X" { return OPTION_X; }
-"\ -x" { return OPTION_x; }
-"\ -c" { return OPTION_c; }
-"\ -s" { return OPTION_s; }
-"\ -S" { return OPTION_S; }
+"@" { return '}'; }
+"\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
+"\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
+"\ -sort_common\ " { return OPTION_sort_common;}
+"\ -format\ " { return OPTION_format; }
+"\ -n\ " { return OPTION_n; }
+"\ -r\ " { return OPTION_r; }
+"\ -i\ " { return OPTION_r; }
+"\ -Ur\ " { return OPTION_Ur; }
+"\ -o\ " { return OPTION_o; }
+"\ -g\ " { return OPTION_g; }
+"\ -e\ " { return OPTION_e; }
+"\ -b\ " { return OPTION_b; }
+"\ -dc\ " { return OPTION_dc; }
+"\ -dp\ " { return OPTION_dp; }
+"\ -d\ " { return OPTION_d; }
+"\ -v\ " { return OPTION_v; }
+"\ -M\ " { return OPTION_M; }
+"\ -t\ " { return OPTION_t; }
+"\ -X\ " { return OPTION_X; }
+"\ -x\ " { return OPTION_x; }
+"\ -c\ " { return OPTION_c; }
+"\ -R\ " { return OPTION_R; }
+"\ -u\ " { return OPTION_u; }
+"\ -s\ " { return OPTION_s; }
+"\ -S\ " { return OPTION_S; }
+"\ -B{FILENAME}\ " { /* Ignored */ }
"\ -l"{FILENAME} {
yylval.name = buystring(yytext+3);
return OPTION_l;
yylval.name = buystring(yytext+3);
return OPTION_L;
}
-"\ -Ttext" {
+"\ -Ttext\ " {
yylval.name = ".text";
return OPTION_Texp;
}
-"\ -Tdata" {
+"\ -Tdata\ " {
yylval.name = ".data";
return OPTION_Texp;
}
-"\ -Tbss" {
+"\ -Tbss\ " {
yylval.name = ".bss";
return OPTION_Texp;
}
yylval.name = buystring(yytext+3);
return OPTION_Tfile;
}
-"\ -T" {
+"\ -T\ " {
return OPTION_T;
}
"\ -F"{FILENAME} {
return OPTION_F;
}
-"\ -F" {
+"\ -F\ " {
return OPTION_F;
}
yylval.name = buystring(yytext+3);
return OPTION_Aarch;
}
-" " { }
+
+" " {
+ if (ldgram_had_equals == true) {
+ ldgram_in_defsym = false;
+ ldgram_had_equals = false;
+ }
+ }
"<<=" { RTOKEN(LSHIFTEQ);}
">>=" { RTOKEN(RSHIFTEQ);}
"||" { RTOKEN(OROR);}
"/=" { RTOKEN(DIVEQ);}
"&=" { RTOKEN(ANDEQ);}
"|=" { RTOKEN(OREQ);}
-
"&&" { RTOKEN(ANDAND);}
">" { RTOKEN('>');}
"," { RTOKEN(',');}
"*" { RTOKEN('*');}
"%" { RTOKEN('%');}
"<" { RTOKEN('<');}
-"+" { RTOKEN('+');}
">" { RTOKEN('>');}
"}" { RTOKEN('}') ; }
"{" { RTOKEN('{'); }
"]" { RTOKEN(']');}
"[" { RTOKEN('[');}
":" { RTOKEN(':'); }
-";" { RTOKEN(';');}
+";" { RTOKEN('\;');}
"-" { RTOKEN('-');}
-"=" { RTOKEN('=');}
+
"/*" {
yylval.name[yyleng-2] = 0; /* Fry final quote */
return NAME;
}
-[0][0-7KM]* {
- yylval.integer = number(yytext+1, 8);
- return INT;
-}
+{FILENAMECHAR} {
+
+ boolean loop = false;
+ int ch;
+ keyword_type *k;
+
+ /* If we're in hex mode (only after a -T) then all we can see are numbers
+ hex digit we see will be a number. */
-[0-9]+[KM]? {
- if (hex_mode == true) {
- yylval.integer = number(yytext, 16);
+ if (hex_mode) {
+ return number(16, 16);
}
- else {
- yylval.integer = number(yytext, 10);
+
+ /* If we're in a defsym then all things starting with a digit are in
+ hex */
+
+ if (isdigit(yytext[0]) && ldgram_in_defsym) {
+ return number(16,16);
}
- return INT;
-}
-0[Xx][0-9a-fA-FKM]+ {
-
- yylval.integer = number(yytext+2,16);
- return INT;
-}
-"\#"{WHITE}*{FILENAMECHAR}+ {
- char *p = yytext+1;
- while(*p ==' ' || *p == '\t') p++;
- yylval.name = buystring(p);
- return NAME;
-}
-{FILENAMECHAR} {
+ /* Otherwise if we're in a script we will parse the numbers
+ normally */
- boolean loop = false;
- /*
- Tokenize a name, this is really pain, since a name can be a
- filename or a symbol name. filenames have slashes and stuff whist
- in an expression those things are seperate tokens. We hack this by
- setting lang_in_expression when we are expecting a symbol, so that
- [/+-] get taken to be seperate tokens. An extra gotcha is
- expressions after defsyms, we only allow +s and -s in a defsym
- expression, so -defsym foo=bar+9 /file.o is parsed ok.
-
- */
- int ch;
- keyword_type *k;
- if (ldgram_in_expression) {
- if (yytext[0] != '/' || ldgram_in_defsym == false) {
- switch (yytext[0]) {
- case '/': RTOKEN('/');
+ if (ldgram_in_script == true && isdigit(yytext[0])) {
+ return number(8,10);
+ }
+
+ /* Anywhere not in a script or defsym, an opertor is part of a
+ filename, except / and, which is an operator when on its own */
+ if (ldgram_in_script == true|| ldgram_in_defsym == true) {
+
+ switch (yytext[0]) {
+ case '*': RTOKEN('*');
+
+ case '=': {
+ ldgram_had_equals = true;
+ RTOKEN('=');
+ }
+ break;
+ case '/': {
+ if (ldgram_in_defsym) RTOKEN('/');
+ }
+ break;
case '+': RTOKEN('+');
case '-': RTOKEN('-');
+ case '!': RTOKEN('!');
+ case '~': RTOKEN('~');
}
}
- }
+
+/* Otherwise this must be a file or a symbol name, and it will continue to be a
+ filename until we get to something strange. In scripts operator looking
+ things are taken to be operators, except /, which will be left
+ */
ch = input();
while (true)
{
- if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_') {
- yytext[yyleng++] = ch;
+ if (ldgram_in_defsym == true) {
+ switch (ch) {
+ case '*':
+ case '=':
+ case '+':
+ case '/':
+ case '-':
+ case '!':
+ case '~':
+ goto quit;
+ }
+
}
- else if (ch == '+' || ch == '-' || ch == '/') {
- if (ldgram_in_expression) break;
+ if(ldgram_in_script == true) {
+ switch (ch) {
+ case '*':
+ case '=':
+ case '+':
+ case '-':
+ case '!':
+ case '~':
+ goto quit;
+ }
+ }
+
+ if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ||
+ ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
yytext[yyleng++] = ch;
}
else
break;
ch = input();
}
-
+ quit:;
yytext[yyleng] = 0;
unput(ch);
for(k = keywords; k ->name != (char *)NULL; k++) {
-
if (strcmp(k->name, yytext)==0) {
yylval.token = k->value;
return k->value;