summaryrefslogtreecommitdiff
path: root/old/parser.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-01-01 19:31:12 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2017-01-01 19:31:12 +0100
commit69fe7b182a1eedfb75c611f7dd35fa60200426f4 (patch)
tree329a0c6cc9b06c23d8782ece09f0f7dfa9b16b13 /old/parser.c
downloadcompilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.gz
compilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.bz2
initial checkin
Diffstat (limited to 'old/parser.c')
-rw-r--r--old/parser.c180
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;
+}