Yet more diffs due to my incompetence.
authorSteve Chamberlain <steve@cygnus>
Fri, 19 Apr 1991 00:59:53 +0000 (00:59 +0000)
committerSteve Chamberlain <steve@cygnus>
Fri, 19 Apr 1991 00:59:53 +0000 (00:59 +0000)
ld/ldgram.y
ld/ldlex.l

index 304b0b2ab8e6124834f475fd3037a9202351e6f2..c3578b51db74a16a1111b290fa3c631b79fb6aaf 100644 (file)
@@ -60,9 +60,10 @@ char *current_file;
 boolean ldgram_want_filename = true;
 boolean had_script = false;
 boolean force_make_executable = false;
-boolean ldgram_in_expression = false;
+
 boolean ldgram_in_script = false;
 boolean ldgram_in_defsym = false;
+boolean ldgram_had_equals = false;
 /* LOCALS */
 
 
@@ -280,13 +281,13 @@ command_line_option:
        |       OPTION_defsym 
                        {
                        ldgram_in_defsym = true;
-                       ldgram_in_expression = true;    
-
+                       ldgram_had_equals = false;
                        }
-                        assignment
+               NAME     '='
+               exp_head 
                        {
+                       lang_add_assignment(exp_assop($4,$3,$5));
                        ldgram_in_defsym = false;
-                       ldgram_in_expression = false;
                        }       
        | '-' NAME
                 { info("%P%F Unrecognised option -%s\n", $2);  }
@@ -654,14 +655,7 @@ opt_things:
        ;
 
 exp_head:
-               { 
-               ldgram_in_expression = true; 
-               }
-       exp
-               {
-               ldgram_in_expression = false; 
-               $$ = $2;
-               }
+       exp { $$ = $1; }
        ;
 
 opt_exp:
index dd67083695fd4716cec2620ea098a82428bbfcc8..9d74ea1d5b9e0d4ac2900f36da4a39e358f05370 100644 (file)
@@ -46,8 +46,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define unput lex_unput
 int debug;
 
-extern boolean ldgram_in_expression;
+
 extern boolean ldgram_in_defsym;
+static boolean ldgram_had_equals;
 extern boolean ldgram_in_script;
 static char *command_line;
 
@@ -61,6 +62,7 @@ int value;
 #define RTOKEN(x)  {  yylval.token = x; return x; }
 keyword_type keywords[] = 
 {
+"/", '/',
 "MEMORY",MEMORY,
 "ORIGIN",ORIGIN,
 "BLOCK",BLOCK,
@@ -101,6 +103,7 @@ unsigned int lineno;
 extern boolean hex_mode;
 FILE *ldlex_input_stack;
 static unsigned int have_pushback;
+
 #define NPUSHBACK 10
 int pushback[NPUSHBACK];
 int thischar;
@@ -215,33 +218,46 @@ char **av;
 
 }
 
-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') {
+  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;
 }
 %}
 
@@ -249,9 +265,7 @@ int base;
 %o 5000
 FILENAMECHAR   [a-zA-Z0-9\/\.\-\_\+\=]
 FILENAME       {FILENAMECHAR}+
-
-
-WHITE          [ \t]+
+WHITE          [ \t]+ 
 
 %%
 
@@ -320,7 +334,8 @@ WHITE               [ \t]+
                  yylval.name = buystring(yytext+3);
                 return OPTION_Aarch;
               }
-" " { }
+
+" "            { if (ldgram_had_equals == true) ldgram_in_defsym = false; }
 "<<="          { RTOKEN(LSHIFTEQ);}
 ">>="          { RTOKEN(RSHIFTEQ);}
 "||"           { RTOKEN(OROR);}
@@ -384,121 +399,92 @@ WHITE            [ \t]+
   return NAME;
 }
 
-"\#"{WHITE}*{FILENAMECHAR}+ {
-  char *p = yytext+1;
-  while(*p ==' ' || *p == '\t') p++;
-  yylval.name = buystring(p);
-  return NAME;
-}
 {FILENAMECHAR} {
 
   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 ldlang_in_script 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.
-    
-    The more I think about this the more I hate it. I've got a problem
-    now with the = sign, what should I do ? imagine:
-    __start=.;
-    You'd think that was pretty unambiguous wouldn't you. Well it's
-    not since __start=. is (at the moment) a perfectly valid
-    filename. And in some cases we don't know what's going on. I'm
-    going to have to hack this. If we see a '/' before the = sign then
-    we say we've got an = in a filename, otherwise it's an operator.
-    (later)
-    That's it, I've had enough. From now on, an =s on a command line
-    will be taken to be part of a file name unless its in a defsym,
-    and an = in a file will be taken to be an operator.
-    */
   int ch;
   keyword_type *k;
 
-  if ((hex_mode && isxdigit(yytext[0]))
-      ||
-      (isdigit(yytext[0]) && (ldgram_in_expression == true || ldgram_in_script == true))) {
-    char *start = yytext;
-    unsigned int base = 10;
-    if (hex_mode == true) base = 16;
-    if (yytext[0] == '0') {
-      base = 8;
-    }
-    ch = input();
-    while (isxdigit(ch) 
-          || ch == 'x'
-          || ch == 'X'
-          || ch == 'M'         
-          )
-       {
-         if (ch == 'x' || ch == 'X') {
-           base = 16;
-           start = yytext + yyleng;
-         }
-         else {
-           yytext[yyleng++] = ch;
-         }
-         ch = input();
-       }
-    yytext[yyleng] = 0;
-    unput(ch);
-    yylval.integer = number(start, base);
-    return INT;
+  /* 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. */
+
+  if (hex_mode) {      
+    return number(16, 16);
   }
 
-  if (ldfile_input_filename) {
-    /* We're inside a file */
-    if (yytext[0]== '=') {
-      RTOKEN('=');
-    }
+  /* 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);
+  }
+
+
+  /* Otherwise if we're in a script we will parse the numbers
+     normally */
+
+  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) {
 
-  /* Otherwise we only notice special things if were in an
-     expression */
+    switch (yytext[0]) {
+      case '*': RTOKEN('*');
 
-  if (ldgram_in_expression) {
-    if (yytext[0] != '/' ||  ldgram_in_defsym == false)  {
-      switch (yytext[0]) {
-      case '/': RTOKEN('/');
-      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;
-       }
-       else if (ch == '=' && ldgram_in_script) {
-         /* An = within a script is always taken to be an operator */
-         break;
+       if (ldgram_in_defsym == true) {
+         switch (ch) {
+         case '*': 
+         case '=': 
+         case '+': 
+         case '/': 
+         case '-': 
+         case '!': 
+         case '~': 
+           goto quit;
+         }
+         
        }
-       else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
-         if (ldgram_in_expression) break;
+       
+       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);
-  /* Filenames  of just =signs are tokens */
-  if (yyleng == 1 && yytext[0] == '=') {
-    RTOKEN('=');
-  }
-  for(k = keywords; k ->name != (char *)NULL; k++) {
 
+  for(k = keywords; k ->name != (char *)NULL; k++) {
     if (strcmp(k->name, yytext)==0) {
       yylval.token = k->value;
       return k->value;