123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- #include "Lpars.h"
- #include <stdio.h>
- #include <ctype.h>
- /* This file contains the function mylex() which recognizes the following
- * tokens :
- * EOFILE
- * C_INSTR - 'C_loc', 'C_lol', etc.
- * DEF_C_INSTR - 'C_loe..', 'C_ste..', '..icon, '..fcon', etc
- * CONDITION - C-expression, for example: '$1 == 481'
- * ARROW - '==>'
- * CALL - C-style functioncall, for example: 'error( 17)'
- * ASSEM_INSTR - C-style string, for example: '"mov r0, (r1)"'
- * DEFAULT - 'default'
- * ERROR - An error occured in one of the tokens.
- *
- * If the input matches non of these tokens the next character will be returned.
- *
- * Besides mylex() the following variable is exported :
- *
- * char yytext[]; - Contains the string representation of the current
- * token.
- * char *next; - Points to the first free position in yytext[].
- */
- #define YYTEXT 65536
- char yytext[YYTEXT], /* string-buffer for the token */
- *next; /* points to the first free posistion in yytext[] */
- extern char scanc();
- #define FALSE 0
- #define TRUE 1
- int CD_pos = FALSE; /* 'CD_pos' is used as a flag to signal if it is
- * possible to match a CONDITION or DEFAULT-token at
- * this moment. Thus mylex() knows about the grammar
- * of the "EM_table"!!
- * This flag is needed because CALL is a subset of
- * CONDITION.
- */
- int CALL_pos = FALSE; /* Needed to distinguish between
- * C_INSTR CONDITION and CALL
- */
- static char skip_space();
- static read_string();
- int mylex()
- {
- char c;
- static int special = FALSE; /* rule with conditions + default ? */
- next = yytext;
- c = *next++ = skip_space();
- switch ( c) {
- case EOF : next = yytext;
- return( 0);
- case '"' : read_string();
- return( ASSEM_INSTR);
- case '.' : c = scanc();
- backc( c);
- if ( c != '.') { /* Just a plain '.', not something like
- * '..icon'.
- */
- if ( special)
- CD_pos = TRUE;
- CALL_pos = FALSE;
- return( '.');
- }
- break;
- case ';' : return( ';');
- case '=' : if ( arrow()) {
- CD_pos = FALSE;
- CALL_pos = TRUE;
- return( ARROW);
- }
- break;
- case 'd' : if ( CD_pos && _default()) {
- CD_pos = FALSE;
- special = FALSE;
- return( DEFAULT);
- }
- break;
- }
- /* Possible tokens at this place : CONDITION, CALL, C_INSTR,
- * DEF_C_INSTR
- */
- if ( CD_pos) {
- read_condition();
- CD_pos = FALSE;
- special = TRUE;
- return( CONDITION);
- }
- if ( isalpha( c)) {
- read_ident();
- if ( CALL_pos) {
- c = skip_space();
- if ( c == '(') {
- *next++ = c;
- read_call();
- return( CALL);
- }
- else {
- backc( c);
- return( ERROR);
- }
- }
- else {
- if ( is_DEF_C_INSTR( yytext)) {
- CD_pos = TRUE;
- return( DEF_C_INSTR);
- }
- if ( is_C_INSTR( yytext)) {
- CD_pos = TRUE;
- return( C_INSTR);
- }
- return( ERROR);
- }
- }
- if ( c == '.') {
- c = scanc();
- if ( c == '.') {
- *next++ = '.';
- read_ident();
- if ( is_DEF_C_INSTR( yytext)) {
- CD_pos = TRUE;
- return( DEF_C_INSTR);
- }
- return( ERROR);
- }
- else {
- backc( c);
- return( '.');
- }
- }
- return( c);
- }
- static int isletter( c)
- char c;
- {
- return( isalpha( c) || isdigit( c) || c == '_');
- }
- static char skip_space()
- {
- char c;
- while ( isspace( c = scanc()))
- ;
- return( c);
- }
- /* first character has been read */
- static read_string()
- /* match something like "mov r0, (r1)".
- * strip the double quotes off! Inside a string, the character '"' must
- * be preceded by a '\'.
- */
- {
- next--;
- while( ( *next = scanc()) != '"' || *(next-1) == '\\')
- next++;
- }
- int arrow() /* '==>' */
- {
- if ( ( *next++ = scanc()) == '=')
- if ( ( *next++ = scanc()) == '>')
- return( TRUE);
- else
- backc( *--next);
- else
- backc( *--next);
- return( FALSE);
- }
- int _default() /* 'default' */
- {
- char c;
- if ( ( *next++ = scanc()) == 'e')
- if ( ( *next++ = scanc()) == 'f')
- if ( ( *next++ = scanc()) == 'a')
- if ( ( *next++ = scanc()) == 'u')
- if ( ( *next++ = scanc()) == 'l')
- if ( ( *next++ = scanc()) == 't')
- if ( !isletter( c = skip_space())) {
- backc( c);
- return( TRUE);
- }
- else
- backc( c);
- else
- backc( *--next);
- else
- backc( *--next);
- else
- backc( *--next);
- else
- backc( *--next);
- else
- backc( *--next);
- else
- backc( *--next);
- return( FALSE);
- }
- read_ident()
- {
- char c;
- while ( isletter( c = scanc()))
- *next++ = c;
- backc( c);
- }
- read_call()
- {
- int n = 1;
- while ( TRUE)
- switch( *next++ = scanc()) {
- case EOF : return;
- case '(' : n++;
- break;
- case ')' : n--;
- if ( n == 0)
- return;
- break;
- }
- }
- read_condition()
- /* A CONDITION is followed by '==>'
- */
- {
- while ( TRUE) {
- switch ( *next++ = scanc()) {
- case EOF : return;
- case '=' : if ( arrow()) {
- backc( '>');
- backc( '=');
- backc( '=');
- next -= 3;
- return;
- }
- break;
- }
- }
- }
- is_C_INSTR( str)
- char *str;
- {
- if ( *str == 'C' && *(str+1) == '_') /* C_xxx */
- return( TRUE);
- else
- return( FALSE);
- }
- is_DEF_C_INSTR( str)
- char *str;
- /* yytext[] contains either '..[letter]*' ( 2 dots possibly followed by an
- * identifer) * or '[letter]+' ( just an identifier)
- * Try to match something like 'C_loe..' or '..icon'
- */
- {
- if ( *str == '.' && *(str+1) == '.')
- return( next > yytext+1);
- if ( ( *next++ = scanc()) == '.')
- if ( ( *next++ = scanc()) == '.')
- return( next > yytext+1);
- else
- backc( *--next);
- else
- backc( *--next);
- return( FALSE);
- }
|