Author: kjs
Date: Mon Mar 26 04:10:58 2007
New Revision: 17764

Modified:
   trunk/compilers/pirc/doc/design.pod
   trunk/compilers/pirc/src/pirlexer.c
   trunk/compilers/pirc/src/pirlexer.h
   trunk/compilers/pirc/src/pirparser.c

Log:
compilers/pirc:
* added binary and hex constants to lexer
* removed 2 unused token types
* fixed pod error in design.pod
* some code refactoring in parser.

Modified: trunk/compilers/pirc/doc/design.pod
==============================================================================
--- trunk/compilers/pirc/doc/design.pod (original)
+++ trunk/compilers/pirc/doc/design.pod Mon Mar 26 04:10:58 2007
@@ -16,11 +16,11 @@
 =head2 OVERVIEW
 
 The lexer is defined in C<pirlexer.c>. The header file lists all tokens that
-may be returned by the lexer. 
+may be returned by the lexer.
 
 The lexer reads the complete file contents into a buffer, from which it reads
 the individual words, or I<tokens>. A buffer is much faster than using 
C<getc()>
-for each character, as I/O is relatively slow. 
+for each character, as I/O is relatively slow.
 
 The lexer has three functions that may be invoked to receive the next token:
 
@@ -42,6 +42,7 @@
 C<read_macro()> is used to read a macro body. It reads up to the C<.endm> word,
 and then returns the T_ENDM token, which can then be matched by the parser.
 
+=back
 
 =head2 IMPLEMENTATION
 
@@ -52,10 +53,10 @@
 The structure looks like this:
 
  typedef struct lexer_state {
-    struct file_buffer *curfile;    
-    char *token_chars;              
-    char *charptr;                  
- 
+    struct file_buffer *curfile;
+    char *token_chars;
+    char *charptr;
+
  } lexer_state;
 
 It has three pointers: the first one is a pointer to a file_buffer structure, 
which
@@ -63,24 +64,24 @@
 This is a buffer in which the characters for the current token are stored.
 The field C<charptr> acts like an index to add and delete characters from 
C<token_chars>.
 
-As mentioned, the lexer reads the source file and returns tokens. The source 
file is 
+As mentioned, the lexer reads the source file and returns tokens. The source 
file is
 represented by another structure, called C<file_buffer>. It looks like this:
 
  typedef struct file_buffer {
-     char *filename;                 
-     char *buffer;                   
-     char *curchar;                  
-     unsigned filesize;              
-     unsigned int line;              
-     unsigned short linepos;         
-     char lastchar;                  
-     struct file_buffer *prevbuffer; 
- 
+     char *filename;
+     char *buffer;
+     char *curchar;
+     unsigned filesize;
+     unsigned int line;
+     unsigned short linepos;
+     char lastchar;
+     struct file_buffer *prevbuffer;
+
  } file_buffer;
- 
-The first field C<filename> holds the name of the file that is being scanned. 
+
+The first field C<filename> holds the name of the file that is being scanned.
 The second field C<buffer> is a pointer to the contents of the file. The field
-C<curchar> points into this buffer to the current position, and can be 
considered 
+C<curchar> points into this buffer to the current position, and can be 
considered
 the I<cursor>.
 Then, C<filesize> contains the length of the file; C<line> keeps track of what 
line
 is being processed; linepos keeps track of the number of characters since the 
last
@@ -100,7 +101,7 @@
 
 The parser communicates with the lexer through the lexer's accessor function. 
Of
 these, the C<next_token()> function is most important: it requests the next 
token
-from the lexer. 
+from the lexer.
 
 The parser does not know anything about the spelling of tokens, although it can
 request these through C<find_keyword()>.
@@ -112,17 +113,17 @@
 shown below:
 
  typedef struct parser_state {
-     struct lexer_state *lexer;      
-     token curtoken;                 
-     char *heredoc_ids[10];          
-     int heredoc_index;              
-     unsigned parse_errors;          
-  
+     struct lexer_state *lexer;
+     token curtoken;
+     char *heredoc_ids[10];
+     int heredoc_index;
+     unsigned parse_errors;
+
  } parser_state;
 
 It consists of the following fields: a pointer to a lexer_state object; the 
current
 token as returned by the lexer; a list to store heredoc identifiers, which is 
used
-when parsing heredocs as subroutine arguments; an index for this list; and 
finally a 
+when parsing heredocs as subroutine arguments; an index for this list; and 
finally a
 counter to keep track of parse errors.
 
 =head1 AUTHOR

Modified: trunk/compilers/pirc/src/pirlexer.c
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.c (original)
+++ trunk/compilers/pirc/src/pirlexer.c Mon Mar 26 04:10:58 2007
@@ -186,7 +186,6 @@
     "'string'",                 /* T_SINGLE_QUOTED_STRING,  */
     "'literal'",                /* T_LITERAL,               */
     "invocant id",              /* T_INVOCANT_IDENT,        */
-    "'number'",                 /* T_NUMBER,                */
     "'error'",                  /* T_ERROR,                 */
     "**",                       /* T_POWER,                 */
     "**=",                      /* T_POWER_ASSIGN,          */
@@ -194,7 +193,6 @@
     "+=",                       /* T_PLUS_ASSIGN,           */
     "-=",                       /* T_MINUS_ASSIGN,          */
     ".=",                       /* T_CONCAT_ASSIGN          */
-    "'register'",               /* T_REGISTER,              */
     "/=",                       /* T_DIVIDE_ASSIGN,         */
     "//=",                      /* T_FDIVIDE_ASSIGN,        */
     "%=",                       /* T_MODULO_ASSIGN,         */
@@ -247,15 +245,20 @@
 the current file being read, a buffer holding the current
 token, and a pointer to add characters to the token buffer.
 
+ typedef struct lexer_state {
+     struct file_buffer *curfile;    -- pointer to the current file
+     char *token_chars;              -- characters of the current token
+     char *charptr;                  -- used for adding/removing token chars
+
+ } lexer_state;
+
 =cut
 
 */
 typedef struct lexer_state {
-    struct file_buffer *curfile;    /* pointer to the current file           */
-    char *token_chars;              /* characters of the current token       */
-    char *charptr;                  /* used for adding/removing token chars  */
-    /*Parrot_Interp interp;
-    */
+    struct file_buffer *curfile;
+    char *token_chars;
+    char *charptr;
 
 } lexer_state;
 
@@ -278,11 +281,10 @@
     if ((t >= 0) && (t <= MAX_TOKEN)) {
         return dictionary[t];
     }
-    else {
+    else { /* this should never happen; error in dictionary */
         fprintf(stderr, "FATAL: invalid token in find_keyword()\n");
         fprintf(stderr, "No entry for token %d\n", t);
-        if (t-1 <= MAX_TOKEN) fprintf(stderr, "Previous token: %s\n", 
dictionary[t - 1]);
-        return "ERROR";
+        exit(1);
     }
 }
 
@@ -342,16 +344,17 @@
 */
 void
 print_error_context(struct lexer_state *s) {
-    /* print context of size ERROR_CONTEXT_SIZE */
+    /* print context of max. size ERROR_CONTEXT_SIZE */
     int read_chars = s->curfile->curchar - s->curfile->buffer;
     int context_length = read_chars > ERROR_CONTEXT_SIZE ? ERROR_CONTEXT_SIZE 
: read_chars;
     char *start = s->curfile->curchar - context_length;
     char *end = s->curfile->curchar;
 
+    /* print all characters from start to end */
     while (start < end ) {
         fprintf(stderr, "%c", *start++);
     }
-    /* print an indicator like "^" */
+    /* print an indicator like "^" on the next line */
     fprintf(stderr, "\n%*s\n", s->curfile->linepos - 1, "^");
 }
 
@@ -391,13 +394,12 @@
 
     /* store previous character, but only if not at first character of file */
     if (buf->curchar > buf->buffer) buf->lastchar = *(buf->curchar - 1);
-    else buf->lastchar = '\n';
+    else buf->lastchar = '\n'; /* makes the check for prev. char. at start of 
file successful */
 
     buf->curchar++;  /* update pointer to current char. */
     buf->linepos++; /* update the token position */
 
     return c;
-
 }
 
 /*
@@ -405,14 +407,12 @@
 =item unread_char()
 
 Push back the last read character.
-It was never removed from the buffer, so just
-decrement the pointer in the buffer.
 
 =cut
 
 */
 static void
-unread_char(file_buffer *buf, char c) {
+unread_char(file_buffer *buf) {
    --buf->curchar;
    --buf->linepos;
 }
@@ -681,7 +681,7 @@
         c = read_char(lexer->curfile);
         count++;
     }
-    unread_char(lexer->curfile, c); /* no digit, put it back */
+    unread_char(lexer->curfile); /* no digit, put it back */
     return count;
 }
 
@@ -766,7 +766,7 @@
             }
             while (c != '\n');
 
-            unread_char(lexer->curfile, c);
+            unread_char(lexer->curfile);
             continue; /* with main loop */
         }
 
@@ -862,7 +862,7 @@
             else { /* not a label or invocant put the last read char. back */
                 token tmp;
 
-                unread_char(lexer->curfile, c);
+                unread_char(lexer->curfile);
 
                 tmp = check_dictionary(lexer, dictionary); /* look up the id */
 
@@ -889,7 +889,7 @@
             if (c == '.') return T_DOTDOT;  /* ".." */
 
             if ( isspace(c) ) { /* a dot followed by a space */
-                unread_char(lexer->curfile, c);
+                unread_char(lexer->curfile);
                 return T_CONCAT;
             }
 
@@ -898,7 +898,7 @@
                 c = read_char(lexer->curfile);
                 if (c == EOF_MARKER) break;
             }
-            unread_char(lexer->curfile, c);
+            unread_char(lexer->curfile);
             tmp = check_dictionary(lexer, dictionary);
 
             /* if not found, then it is a macro id */
@@ -911,18 +911,40 @@
         }
         else if (isdigit(c) ) { /* check for numbers */
             buffer_char(lexer, c);
-            read_digits(lexer);
-
             c = read_char(lexer->curfile);
-            if (c == '.') { /* floating point number */
+
+            if (isdigit(c)) { /* integer or float */
+                do {
+                    buffer_char(lexer, c);
+                    c = read_char(lexer->curfile);
+                }
+                while (isdigit(c));
+
+                /* it is a different char, either '.', ' ' or something else */
+                if (c == '.') { /* floating point number */
+                    buffer_char(lexer, c);
+                    read_digits(lexer);
+                    return T_NUMBER_CONSTANT;
+                }
+                else {
+                    unread_char(lexer->curfile); /* put back last read char. */
+                    return T_INTEGER_CONSTANT;
+                }
+            }
+            else if (c == 'b' || c == 'B') { /* 0b<digit>+ or 0B<digit>+ */
                 buffer_char(lexer, c);
                 read_digits(lexer);
-                return T_NUMBER_CONSTANT;
+                return T_INTEGER_CONSTANT;
             }
-            else {
-                unread_char(lexer->curfile, c); /* put back last read char. */
+            else if (c == 'x' || c == 'X') { /* 0x<digit>+ or 0X<digit>+ */
+                buffer_char(lexer, c);
+                read_digits(lexer);
                 return T_INTEGER_CONSTANT;
             }
+            else { /* 1 digit */
+                return T_INTEGER_CONSTANT;
+            }
+
         }
         else if (c == '$') { /* parse PIR register or macro label */
             token regtype;
@@ -954,7 +976,7 @@
                         return T_MACRO_LABEL;
                     }
                     else { /* $ ??? */
-                        unread_char(lexer->curfile, c);
+                        unread_char(lexer->curfile);
                         return T_ERROR;
                     }
             }
@@ -1012,7 +1034,7 @@
 
 =head3 Augmented operators
 
-    **=   *=    %=   /=   //=   +=   -=  .=  >>=  >>>=   <<=  &=   |=   ~= 
+    **=   *=    %=   /=   //=   +=   -=  .=  >>=  >>>=   <<=  &=   |=   ~=
 
 =head3 Conditional operators
 
@@ -1034,7 +1056,7 @@
                 case '=': return T_POWER_ASSIGN; /* **= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_MULTIPLY;           /* * */
             }
         }
@@ -1044,27 +1066,27 @@
                 case '=': return T_MODULO_ASSIGN; /* %= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_MODULO;              /* % */
             }
         }
         else if (c == '/') {
             c = read_char(lexer->curfile);
             switch(c) {
-                case '/': 
+                case '/':
                     c = read_char(lexer->curfile);
                     if (c == '=') {
                         return T_FDIVIDE_ASSIGN; /* //= */
                     }
                     else {
-                        unread_char(lexer->curfile, c);
-                        return T_FDIVIDE;   
+                        unread_char(lexer->curfile);
+                        return T_FDIVIDE;
                     }
                     break;
                 case '=': return T_DIVIDE_ASSIGN; /* /= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_DIVIDE;              /* / */
             }
         }
@@ -1074,7 +1096,7 @@
                 case '=': return T_PLUS_ASSIGN; /* += */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_PLUS;              /* + */
             }
         }
@@ -1085,7 +1107,7 @@
                 case '=': return T_MINUS_ASSIGN; /* -= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_MINUS;
             }
         }
@@ -1095,7 +1117,7 @@
                 case '=': return T_NE;              /* != */
                 case EOF_MARKER: return T_EOF;
                 default:                            /* ! */
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_NOT;
             }
         }
@@ -1106,7 +1128,7 @@
                 case '=': return T_EQ;             /* == */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_ASSIGN;               /* = */
             }
         }
@@ -1121,7 +1143,7 @@
                             return T_LOG_RSHIFT_ASSIGN;
                         }
                         else { /* >>> */
-                            unread_char(lexer->curfile, c);
+                            unread_char(lexer->curfile);
                             return T_LOG_RSHIFT;
                         }
                     }
@@ -1129,13 +1151,13 @@
                         return T_RSHIFT_ASSIGN;
                     }
                     else { /* >> */
-                        unread_char(lexer->curfile, c);
+                        unread_char(lexer->curfile);
                         return T_RSHIFT;
                     }
                 case '=': return T_GE; /* >= */
                 case EOF_MARKER: return T_EOF;
                 default:  /* > */
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_GT;
             }
         }
@@ -1156,17 +1178,17 @@
                     }
                     else { /* no heredoc */
                         if (c == '=') {                 /* <<= */
-                            return T_LSHIFT_ASSIGN;   
+                            return T_LSHIFT_ASSIGN;
                         }
                         else {                          /* << */
-                            unread_char(lexer->curfile, c);
+                            unread_char(lexer->curfile);
                             return T_LSHIFT;
                         }
                     }
                     break;
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile);
                     return T_LT;
             }
         }
@@ -1177,7 +1199,7 @@
                 case '=': return T_BXOR_ASSIGN;     /* ~= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c); /* ~ */
+                    unread_char(lexer->curfile); /* ~ */
                     return T_BXOR;
             }
         }
@@ -1188,18 +1210,18 @@
                 case '=': return T_BAND_ASSIGN;     /* &= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c); /* & */
+                    unread_char(lexer->curfile); /* & */
                     return T_BAND;
             }
         }
-        else if (c == '|') {                        
+        else if (c == '|') {
             c = read_char(lexer->curfile);
             switch(c) {
                 case '|': return T_OR;              /* || */
                 case '=': return T_BOR_ASSIGN;      /* |= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c); /* | */
+                    unread_char(lexer->curfile); /* | */
                     return T_BOR;
             }
         }
@@ -1217,7 +1239,7 @@
             while (isspace(c));
 
             /* the last read char. was not space/newline, put it back */
-            unread_char(lexer->curfile, c);
+            unread_char(lexer->curfile);
 
             return T_NEWLINE;
         }
@@ -1265,7 +1287,7 @@
             }
             while ( isalnum(c) );
 
-            unread_char(lexer->curfile, c); /* push back last character not 
needed */
+            unread_char(lexer->curfile); /* push back last character not 
needed */
             tmp = check_dictionary(lexer, dictionary);
 
             /* if not found, then no valid flag found */
@@ -1333,7 +1355,7 @@
 
             /* the loop broke, but why? */
             if (*heredoc_iter == '\0' && isspace(c)) { /* loop broke because 
heredoc label was fully iterated; success! */
-                unread_char(lexer->curfile, c); /* we read 1 char too many; 
put back last read character */
+                unread_char(lexer->curfile); /* we read 1 char too many; put 
back last read character */
                 return T_HEREDOC_STRING;   /* return success */
             }
         }

Modified: trunk/compilers/pirc/src/pirlexer.h
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.h (original)
+++ trunk/compilers/pirc/src/pirlexer.h Mon Mar 26 04:10:58 2007
@@ -124,7 +124,6 @@
         T_SINGLE_QUOTED_STRING,             /* "'string'",                */
         T_LITERAL,                          /* "'literal'",               */
         T_INVOCANT_IDENT,                   /* "invocant id",             */
-        T_NUMBER,                           /* "'number'",                */
         T_ERROR,                            /* "'error'",                 */
         T_POWER,                            /* "**",                      */
         T_POWER_ASSIGN,                     /* "**=",                     */
@@ -132,7 +131,6 @@
         T_PLUS_ASSIGN,                      /* "+=",                      */
         T_MINUS_ASSIGN,                     /* "-=",                      */
         T_CONCAT_ASSIGN,                    /* ".="                       */
-        T_REGISTER,                         /* "'register'",              */
         T_DIVIDE_ASSIGN,                    /* "/=",                      */
         T_FDIVIDE_ASSIGN,                   /* "//=",                     */
         T_MODULO_ASSIGN,                    /* "%=",                      */

Modified: trunk/compilers/pirc/src/pirparser.c
==============================================================================
--- trunk/compilers/pirc/src/pirparser.c        (original)
+++ trunk/compilers/pirc/src/pirparser.c        Mon Mar 26 04:10:58 2007
@@ -516,7 +516,7 @@
 
 =item methodcall()
 
-  methodcall -> INVOCANT_IDENT method arguments '\n'
+  methodcall -> INVOCANT_IDENT method arguments
 
 =cut
 
@@ -584,8 +584,8 @@
                     | 'global' stringconstant
                     | heredocstring
                     | methodcall
-                    | 'null'
-                    ) '\n'
+                    | 'null' )
+                    '\n'
 
   unop       -> '-' | '!' | '~'
 
@@ -673,15 +673,11 @@
 }
 
 
-
-
-
-
 /*
 
 =item return_statement()
 
-  return_statement -> '.return' ( arguments | target arguments | methodcall ) 
'\n'
+  return_statement -> '.return' ( arguments | target ['->' method] arguments | 
methodcall ) '\n'
 
 =cut
 
@@ -690,13 +686,13 @@
 return_statement(parser_state *p) {
     match(p, T_RETURN);
     switch (p->curtoken) {
-        case T_LPAREN:
+        case T_LPAREN:   /* return_statement -> '.return' '(' [args] ')' */
             arguments(p);
             break;
-        case T_INVOCANT_IDENT: /* tail method call */
+        case T_INVOCANT_IDENT: /* '.return' methodcall */
             methodcall(p);
             break;
-        default: /* normal sub tailcall */
+        default: /* '.return' target ['->' method] arguments */
             target(p);
             if (p->curtoken == T_PTR) {
                 next(p);
@@ -1643,13 +1639,28 @@
 parameters(parser_state *p) {
     while (p->curtoken == T_PARAM) {
         next(p); /* skip '.param */
-        if (p->curtoken == T_REGISTER) { /* parameter -> '.param' register */
-            next(p);
-        }
-        else { /* parameter -> '.param' type IDENT param_flag */
-            type(p);
-            match(p, T_IDENTIFIER);
-            param_flags(p);
+        switch (p->curtoken) {
+            case T_INT:
+            case T_NUM:
+            case T_PMC:
+            case T_STRING:
+                type(p);
+                match(p, T_IDENTIFIER);
+                param_flags(p);
+                break;
+            case T_PREG:
+            case T_NREG:
+            case T_SREG:
+            case T_IREG:
+            case T_PASM_PREG:
+            case T_PASM_NREG:
+            case T_PASM_SREG:
+            case T_PASM_IREG:
+                next(p);
+                break;
+            default:
+                syntax_error(p, 1, "type or register expected");
+                break;
         }
         match(p, T_NEWLINE);
     }

Reply via email to