/*-----------------------------------------------------------------------
- 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
-------------------------------------------------------------------------*/
D [0-9]
-L [a-zA-Z_]
+L [a-zA-Z_$]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
FS (f|F|l|L)
#define TKEYWORD99(token) return (options.std_c99 ? token : check_type())
-extern int lineno, column;
extern char *filename;
+extern int lineno;
+int column = 0; /* current column */
/* global definitions */
-char *currFname;
-int mylineno = 1;
+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);
"__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[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); }
\\ {
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(); }
%%
static int checkCurrFile (const char *s)
{
- int lNum;
- char *tptr;
+ int lNum;
+ char *tptr;
- /* skip '#' character */
- if (*s++ != '#')
- return 0;
+ /* skip '#' character */
+ if (*s++ != '#')
+ return 0;
- /* check if this is a #line
- this is not standard and can be removed in the future */
+ /* check if this is a #line
+ this is not standard and can be removed in the future */
#define LINE_STR "line"
#define LINE_LEN ((sizeof LINE_STR) - 1)
return 0;
s = tptr;
+ /* adjust the line number */
+ lineno = lexLineno = lNum;
+
/* now see if we have a file name */
while (*s != '"' && *s)
++s;
- /* if we don't have a filename then */
- /* set the current line number to */
- /* line number if printFlag is on */
- if (!*s) {
- lineno = mylineno = lNum;
- return 0;
- }
+ if (!*s)
+ {
+ /* no file name: return */
+ return 0;
+ }
- /* if we have a filename then check */
- /* if it is "standard in" if yes then */
- /* get the currentfile name info */
+ /* skip the double quote */
++s;
- /* in c1mode fullSrcFileName is NULL */
+ /* get the file name and see if it is different from current one.
+ in c1mode fullSrcFileName is NULL */
if (fullSrcFileName &&
- strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0)
+ strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
{
- lineno = mylineno = lNum;
- currFname = 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;
- currFname = Safe_malloc(s - sb + 1);
- memcpy(currFname, sb, s - sb);
- currFname[s - sb] = '\0';
- lineno = mylineno = lNum;
+
+ 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 = currFname;
+ filename = lexFilename;
+
return 0;
}
-int column = 0;
-int plineIdx =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 = ++mylineno;
- }
- 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)
for (; ; )
{
ch = input();
- ++column;
+ count_char(ch);
if (ch == EOF)
break;
{
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 = ++mylineno;
- column = 0;
}
else
{
if (ch == EOF)
goto out;
- ++column;
buf[0] = '\\';
buf[1] = ch;
dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
/* if new line we have a new line break, which is illegal */
werror(W_NEWLINE_IN_STRING);
dbuf_append_char(&dbuf, '\n');
- lineno = ++mylineno;
- column = 0;
break;
case '"':
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 = ++mylineno;
- column = 0;
- }
- break;
+ else
+ count_char(ch);
+ break;
case '\n':
- lineno = ++mylineno;
- column = 0;
+ count_char(ch);
break;
case '#':
struct dbuf_s linebuf;
const char *line;
+ count_char(ch);
+
dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
dbuf_append_char(&linebuf, '#');
dbuf_append_char(&linebuf, (char)ch);
if (ch == '\n')
- {
- lineno = ++mylineno;
- column = 0;
- }
+ count_char(ch);
line = dbuf_c_str(&linebuf);
dbuf_destroy(&linebuf);
}
+ else
+ {
+ unput(ch);
+ goto out;
+ }
+
+ default:
+ count_char(ch);
+ break;
}
}
if (ch != '"')
{
unput(ch);
- --column;
goto out;
}
+ count_char(ch);
break;
default:
if(options.vc_err_style)
fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
- filename, mylineno, s, yytext, column);
+ lexFilename, lexLineno, s, yytext, column);
else
fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
- filename, mylineno, s ,yytext, column);
+ lexFilename, lexLineno, s ,yytext, column);
fatalError++;
return 0;