diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2017-01-01 19:31:12 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2017-01-01 19:31:12 +0100 |
commit | 69fe7b182a1eedfb75c611f7dd35fa60200426f4 (patch) | |
tree | 329a0c6cc9b06c23d8782ece09f0f7dfa9b16b13 /old/parser.c | |
download | compilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.gz compilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.bz2 |
initial checkin
Diffstat (limited to 'old/parser.c')
-rw-r--r-- | old/parser.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/old/parser.c b/old/parser.c new file mode 100644 index 0000000..79a7905 --- /dev/null +++ b/old/parser.c @@ -0,0 +1,180 @@ +#include <stdio.h> +#include <ctype.h> + +#define MAXLEN 80 + +typedef enum { + undef, + eof, + error, + identifier, + literal, + dot, + eql, + lparen, + rparen, + lbrak, + rbrak, + lbrace, + rbrace, + bar +} Sym; + +typedef struct { + Sym sym; + char value[MAXLEN]; +} Symbol; + +typedef struct { + int line; + int col; + FILE *f; +} Scanner; + +static int get_char( Scanner *scan ) { + int c = getc( scan->f ); + scan->col++; + if( c == '\n' ) { + scan->line++; + scan->col = 1; + } + return c; +} + +static void unget_char( Scanner *scan, int c ) { + ungetc( c, scan->f ); + scan->col--; +} + +static Symbol skip_blanks( Scanner *scan ) { + int c; + Symbol s; + + while( ( c = get_char( scan ) ) != EOF && iscntrl( c ) || ( c == ' ' ) ); + + if( c == EOF ) { + s.sym = eof; + return s; + } + + unget_char( scan, c ); + + s.sym = undef; + return s; +} + +static int is_letter( char c ) { + return( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) ); +} + +static int is_digit( char c ) { + return( c >= '0' && c <= '9' ); +} + +static Symbol get_sym( Scanner *scan ) { + int c; + Symbol s; + int i; + + s.sym = undef; + + s = skip_blanks( scan ); + if( s.sym == eof ) return s; + + c = get_char( scan ); + if( c == EOF ) { + s.sym = EOF; + return s; + } + unget_char( scan, c ); + + if( is_letter( c ) ) { + i = 0; + s.sym = identifier; + while( ( c = get_char( scan ) ) != EOF && is_letter( c ) ) { + s.value[i++] = c; + } + s.value[i] = '\0'; + printf( "(%d:%d): ident '%s'\n", scan->line, scan->col, s.value ); + } else if( c == '\"' ) { + int escaped = 0; + i = 0; + s.sym = literal; + (void)get_char( scan ); /* skip first quote */ + while( ( c = get_char( scan ) ) != EOF && c != '\"' || escaped ) { + if( c == '\\' ) { + escaped = 1; + } else { + s.value[i++] = c; + escaped = 0; + } + } + s.value[i] = '\0'; + /* ensure we end in a quote */ + if( c != '\"' ) { + fprintf( stderr, "ERROR(%d:%d): Unbalanced quote after literal '%s'\n", + scan->line, scan->col, s.value ); + s.sym = error; + return s; + } + printf( "(%d:%d): literal '%s'\n", scan->line, scan->col, s.value ); + } else if( c == '=' ) { + c = get_char( scan ); + s.sym = eql; + } else if( c == '(' ) { + c = get_char( scan ); + s.sym = lparen; + } else if( c == ')' ) { + c = get_char( scan ); + s.sym = rparen; + } else if( c == '[' ) { + c = get_char( scan ); + s.sym = lbrak; + } else if( c == ']' ) { + c = get_char( scan ); + s.sym = rbrak; + } else if( c == '{' ) { + c = get_char( scan ); + s.sym = lbrace; + } else if( c == '}' ) { + c = get_char( scan ); + s.sym = rbrace; + } else if( c == '|' ) { + c = get_char( scan ); + s.sym = bar; + } else if( c == '.' ) { + c = get_char( scan ); + s.sym = dot; + } else { + c = get_char( scan ); + s.sym = error; + } + + return s; +} + +static Scanner init_scanner( FILE *f ) +{ + Scanner s; + + s.line = 1; + s.col = 1; + s.f = f; + + return s; +} + +int main( void ) +{ + Symbol s; + Scanner scan; + + scan = init_scanner( stdin ); + + do { + s = get_sym( &scan ); + if( s.sym == eof ) continue; + } while( s.sym != eof ); + + return 0; +} |