Applied patch #2762516
[fw/sdcc] / src / SDCC.lex
index a338d9b075dca91f95f8f078ce7b5d7be058a274..0fc43d00445ed1bd3f5881bb047b091f04423282 100644 (file)
@@ -1,6 +1,6 @@
 /*-----------------------------------------------------------------------
-  SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
-  8/16 bit microcontrollers)
+  SDCC.lex - lexical analyser for use with sdcc (free open source
+  compiler for 8/16 bit microcontrollers)
   Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
 
   This program is free software; you can redistribute it and/or modify it
@@ -22,8 +22,9 @@
   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+B       [0-1]
 D       [0-9]
-L       [a-zA-Z_]
+L       [a-zA-Z_$]
 H       [a-fA-F0-9]
 E       [Ee][+-]?{D}+
 FS      (f|F|l|L)
@@ -49,12 +50,18 @@ extern char *filename;
 extern int lineno;
 int column = 0;         /* current column */
 
+/* global definitions */
+char *lexFilename;
+int lexLineno = 1;
+
 /* local definitions */
 static struct dbuf_s asmbuff; /* reusable _asm buffer */
 
 /* forward declarations */
+int yyerror(char *s);
 static const char *stringLiteral(void);
 static void count(void);
+static void count_char(int);
 static int process_pragma(const char *);
 static int check_type(void);
 static int isTargetKeyword(const char *s);
@@ -185,7 +192,23 @@ _?"_asm"         {
 "__overlay"    { count(); TKEYWORD(OVERLAY); }
 "inline"       { count(); TKEYWORD99(INLINE); }
 "restrict"     { count(); TKEYWORD99(RESTRICT); }
-{L}({L}|{D})*  { count(); return(check_type()); }
+{L}({L}|{D})*  {
+  if (!options.dollars_in_ident && strchr(yytext, '$'))
+    {
+      yyerror("stray '$' in program");
+    }
+  count();
+  return(check_type());
+}
+0[bB]{B}+{IS}? {
+  if (!options.std_sdcc)
+    {
+      yyerror("binary (0b) constants are not allowed in ISO C");
+    }
+  count();
+  yylval.val = constVal(yytext);
+  return(CONSTANT);
+}
 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
 0[0-7]*{IS}?     { count(); yylval.val = constVal(yytext); return(CONSTANT); }
 [1-9]{D}*{IS}?      { count(); yylval.val = constVal(yytext); return(CONSTANT); }
@@ -250,13 +273,14 @@ _?"_asm"         {
 \\ {
   int ch = input();
 
-  ++column;
-  if (ch != '\n') {
-    /* that could have been removed by the preprocessor anyway */
-    werror (W_STRAY_BACKSLASH, column);
-    unput(ch);
-    --column;
-  }
+  if (ch == '\n')
+    count_char(ch);
+  else
+    {
+      /* that could have been removed by the preprocessor anyway */
+      werror (W_STRAY_BACKSLASH, column);
+      unput(ch);
+    }
 }
 .              { count(); }
 %%
@@ -291,7 +315,7 @@ static int checkCurrFile (const char *s)
   s = tptr;
 
   /* adjust the line number */
-  lineno = lNum;
+  lineno = lexLineno = lNum;
 
   /* now see if we have a file name */
   while (*s != '"' && *s)
@@ -311,40 +335,54 @@ static int checkCurrFile (const char *s)
   if (fullSrcFileName &&
     strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
     {
-      filename = fullSrcFileName;
+      lexFilename = fullSrcFileName;
     }
   else
     {
       const char *sb = s;
+      char *tmpFname;
 
-      /* find the end of the filename */
+      /* find the end of the file name */
       while (*s && *s != '"')
         ++s;
 
-      filename = Safe_malloc(s - sb + 1);
-      memcpy(filename, sb, s - sb);
-      filename[s - sb] = '\0';
+      tmpFname = Safe_malloc(s - sb + 1);
+      memcpy(tmpFname, sb, s - sb);
+      tmpFname[s - sb] = '\0';
+
+      lexFilename = Safe_malloc(s - sb + 1);
+      copyStr(lexFilename, tmpFname);
     }
+  filename = lexFilename;
+
   return 0;
 }
 
-static void count(void)
+static void count_char(int ch)
 {
-  int i;
-  for (i = 0; yytext[i] != '\0'; i++)
+  switch (ch)
     {
-      if (yytext[i] == '\n')
-        {
-          column = 0;
-          ++lineno;
-        }
-      else
-        if (yytext[i] == '\t')
-          column += 8 - (column % 8);
-        else
-          column++;
+    case '\n':
+      column = 0;
+      lineno = ++lexLineno;
+      break;
+
+    case '\t':
+      column += 8 - (column % 8);
+      break;
+
+    default:
+      ++column;
+      break;
     }
-  /* ECHO; */
+}
+
+static void count(void)
+{
+  const char *p;
+
+  for (p = yytext; *p; ++p)
+    count_char(*p);
 }
 
 static int check_type(void)
@@ -355,7 +393,7 @@ static int check_type(void)
 
   /* check if it is in the table as a typedef */
   if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
-      && SPEC_TYPEDEF (sym->etype))
+      && SPEC_TYPEDEF (sym->etype) && findSym(TypedefTab, NULL, yytext))
     return (TYPE_NAME);
   else
     return(IDENTIFIER);
@@ -384,7 +422,7 @@ static const char *stringLiteral(void)
   for (; ; )
     {
       ch = input();
-      ++column;
+      count_char(ch);
       if (ch == EOF)
         break;
 
@@ -392,11 +430,11 @@ static const char *stringLiteral(void)
         {
         case '\\':
           /* if it is a \ then escape char's are allowed */
-          if ((ch = input()) == '\n')
+          ch = input();
+          count_char(ch);
+          if (ch == '\n')
             {
               /* \<newline> is a continuator */
-              ++lineno;
-              column = 0;
             }
           else
             {
@@ -405,7 +443,6 @@ static const char *stringLiteral(void)
               if (ch == EOF)
                 goto out;
 
-              ++column;
               buf[0] = '\\';
               buf[1] = ch;
               dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
@@ -416,8 +453,6 @@ static const char *stringLiteral(void)
           /* if new line we have a new line break, which is illegal */
           werror(W_NEWLINE_IN_STRING);
           dbuf_append_char(&dbuf, '\n');
-          ++lineno;
-          column = 0;
           break;
 
         case '"':
@@ -427,31 +462,24 @@ static const char *stringLiteral(void)
           dbuf_append_char(&dbuf, '"');  /* Pass end of this string or substring to evaluator */
           while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
             {
-              ++column;
-
               switch (ch)
                 {
                 case '\\':
+                  count_char(ch);
                   if ((ch = input()) != '\n')
                     {
-                      ++column;
                       werror(W_STRAY_BACKSLASH, column);
                       if (ch != EOF)
-                        {
-                          unput(ch);
-                          --column;
-                        }
+                        unput(ch);
+                      else
+                        count_char(ch);
                     }
-                    else
-                      {
-                        ++lineno;
-                        column = 0;
-                      }
-                    break;
+                  else
+                    count_char(ch);
+                  break;
 
                 case '\n':
-                  ++lineno;
-                  column = 0;
+                  count_char(ch);
                   break;
 
                 case '#':
@@ -461,6 +489,8 @@ static const char *stringLiteral(void)
                       struct dbuf_s linebuf;
                       const char *line;
 
+                      count_char(ch);
+
                       dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
                       dbuf_append_char(&linebuf, '#');
 
@@ -468,10 +498,7 @@ static const char *stringLiteral(void)
                         dbuf_append_char(&linebuf, (char)ch);
 
                       if (ch == '\n')
-                        {
-                          ++lineno;
-                          column = 0;
-                        }
+                        count_char(ch);
 
                       line = dbuf_c_str(&linebuf);
 
@@ -483,6 +510,15 @@ static const char *stringLiteral(void)
 
                       dbuf_destroy(&linebuf);
                     }
+                  else
+                    {
+                      unput(ch);
+                      goto out;
+                    }
+
+                default:
+                  count_char(ch);
+                  break;
                 }
             }
 
@@ -492,9 +528,9 @@ static const char *stringLiteral(void)
           if (ch != '"')
             {
               unput(ch);
-              --column;
               goto out;
             }
+          count_char(ch);
           break;
 
         default:
@@ -1105,10 +1141,10 @@ int yyerror(char *s)
 
   if(options.vc_err_style)
     fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
-      filename, lineno, s, yytext, column);
+      lexFilename, lexLineno, s, yytext, column);
   else
     fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
-      filename, lineno, s ,yytext, column);
+      lexFilename, lexLineno, s ,yytext, column);
   fatalError++;
 
   return 0;