Author: kjs
Date: Tue Mar 27 02:53:43 2007
New Revision: 17784
Modified:
trunk/compilers/pirc/src/pirlexer.c
Log:
compilers/pirc:
* fix lexer for scanning pasm registers (or not-pasm registers).
Modified: trunk/compilers/pirc/src/pirlexer.c
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.c (original)
+++ trunk/compilers/pirc/src/pirlexer.c Tue Mar 27 02:53:43 2007
@@ -379,6 +379,23 @@
*lexer->charptr++ = c;
}
+
+/*
+
+=item unbuffer_char()
+
+Remove the last added character from the buffer.
+
+=cut
+
+*/
+static void
+unbuffer_char(lexer_state *lexer) {
+ --lexer->charptr;
+ *lexer->charptr = '\0';
+}
+
+
/*
=item read_char()
@@ -794,43 +811,57 @@
=cut
*/
- /* now start checking for real tokens */
+ /* now start checking for real tokens */
switch(c) {
case 'P':
- count = read_digits(lexer);
- buffer_char(lexer, c);
- c = read_char(lexer->curfile);
- if (count > 0 && isspace(c) ) return T_PASM_PREG;
- //else unread_char(lexer->curfile);
+ buffer_char(lexer, c); /* buffer 'P'
*/
+ count = read_digits(lexer); /* read as many digits as
you can */
+ c = read_char(lexer->curfile); /* read next, this is not
a digit */
+ if (count > 0 && !isalnum(c) ) { /* only if the #read
digits > 0 .. */
+ unread_char(lexer->curfile); /* .. and current char is
not alnum .. */
+ return T_PASM_PREG; /* put back last read
char, and .. */
+ } /* return token for
register. */
break;
case 'S':
- count = read_digits(lexer);
buffer_char(lexer, c);
+ count = read_digits(lexer);
+
c = read_char(lexer->curfile);
- if (count > 0 && isspace(c) ) return T_PASM_SREG;
- //else unread_char(lexer->curfile);
+ if (count > 0 && !isalnum(c) ) {
+ unread_char(lexer->curfile);
+ return T_PASM_SREG;
+ }
break;
case 'I':
- count = read_digits(lexer);
buffer_char(lexer, c);
+ count = read_digits(lexer);
c = read_char(lexer->curfile);
- if (count > 0 && isspace(c) ) return T_PASM_IREG;
- //else unread_char(lexer->curfile);
+ if (count > 0 && !isalnum(c) ) {
+ unread_char(lexer->curfile);
+ return T_PASM_IREG;
+ }
break;
case 'N':
- count = read_digits(lexer);
buffer_char(lexer, c);
+ count = read_digits(lexer);
c = read_char(lexer->curfile);
- if (count > 0 && isspace(c) ) return T_PASM_NREG;
- //else unread_char(lexer->curfile);
+ if (count > 0 && !isalnum(c) ) {
+ unread_char(lexer->curfile);
+ return T_PASM_NREG;
+ }
break;
- default:
+ default:
break; /* continue below */
}
-
- /* it was not a PASM register */
+
+ /* it was not a PASM register. In case of the letters [S|N|I|P] and
possibly
+ * some digits after that, those are already stored in the token
buffer. That's
+ * no problem, just continue from there. Apparently this is an
identifier, so
+ * it will match the rest of the identifier characters in the first
if-block to
+ * come.
+ */
/*
@@ -1315,6 +1346,12 @@
if (tmp == T_NOT_FOUND) return T_ERROR;
else return tmp;
}
+ else if (isspace(c) && (lexer->charptr > lexer->token_chars) ) {
+ /* we read a register letter, but nothing more, then current char.
is
+ * a space. Check if token buffer is not empty (then charptr >
token_chars pointer)
+ * if not empty, it's an identifier */
+ return T_IDENTIFIER;
+ }
else {
fprintf(stderr, "BUG IN LEXER: Unknown character: %c", c);
fprintf(stderr, "Was parsing file: '%s'\n",
lexer->curfile->filename);
@@ -1322,12 +1359,10 @@
printf("FATAL: end of file passed!\n");
}
exit(1);
-
-
}
}
- fprintf(stderr, "THIS SHOULD NEVER HAPPEN\n");
+ /* it is impossible to come here, but just keep the compiler happy: */
return T_ERROR;
}
@@ -1507,7 +1542,8 @@
switch_buffer(lexer);
}
else { /* no more buffers. */
- fprintf(stderr, "FATAL: attempt to close file '%s' without any open
files left\n", lexer->curfile->filename);
+ fprintf(stderr, "FATAL: attempt to close file '%s' without any open
files left\n",
+ lexer->curfile->filename);
}
}