Jelajahi Sumber

Finished parser.

Taddeüs Kroes 14 tahun lalu
induk
melakukan
c3ba2d2dca
6 mengubah file dengan 172 tambahan dan 153 penghapusan
  1. 1 1
      .gitignore
  2. 12 9
      src/Makefile
  3. 0 124
      src/grammar.y
  4. 0 19
      src/lex.l
  5. 24 0
      src/peephole.l
  6. 135 0
      src/peephole.y

+ 1 - 1
.gitignore

@@ -7,4 +7,4 @@
 lex.yy.c
 lex.yy.c
 y.tab.c
 y.tab.c
 y.tab.h
 y.tab.h
-parser
+peephole

+ 12 - 9
src/Makefile

@@ -1,16 +1,19 @@
 CC=gcc
 CC=gcc
 LEX=lex
 LEX=lex
 YACC=yacc
 YACC=yacc
-CFLAGS=-ll
 
 
-parser: yacc lex
-	$(CC) -c lex.yy.c y.tab.c
-	$(CC) -o $@ lex.yy.o y.tab.o $(CFLAGS)
+CFLAGS = -std=c99 -pedantic -Wall -D_POSIX_SOURCE -D_GNU_SOURCE $(PIC) -pipe
 
 
-lex: lex.l
-	$(LEX) lex.l
+all: peephole
 
 
-yacc: grammar.y
-	$(YACC) -d grammar.y
+peephole: y.tab.o lex.yy.o
+	$(CC) -o $@ $^ -lm
 
 
-all: parser
+y.tab.c y.tab.h: peephole.y
+	$(YACC) -d $^
+
+lex.yy.c: peephole.l
+	$(LEX) $^
+
+clean:
+	rm -f lex.yy.* y.tab.* *.o peephole

+ 0 - 124
src/grammar.y

@@ -1,124 +0,0 @@
-%{
-#include <stdio.h>
-#include <stdlib.h>
-
-// Instruction types
-#define TYPE_COMMENT 0
-#define TYPE_DIRECTIVE 1
-#define TYPE_LABEL 2
-#define TYPE_CMD 3
-
-// Argument types
-#define ARG_INT 0
-#define ARG_REG 1
-#define ARG_LABEL 2
-#define ARG_OFFSET 3
-
-typedef struct line {
-    int type;
-    const char *name;
-    int argc;
-    char **argv;
-    int *argt;
-
-    struct line *prev;
-    struct line *next;
-} line;
-
-void yyerror(char*);
-void add_line(int type, const char *name, int argc, char **argv, int *argt);
-
-line *first_line, *last_line;
-
-%}
-
-%union {
-    int ival;
-    char *sval;
-}
-
-%token NL COMMA
-%token <ival> INT
-%token <sval> COMMENT DIRECTIVE WORD LABEL OFFSET CMD
-%start symbol
-
-%type <sval> command
-
-%%
-
-command:
-    "add" WORD COMMA WORD COMMA WORD {
-        char **argv = (char **)malloc(3 * sizeof(char *));
-        int *argt = (int *)malloc(3 * sizeof(int));
-        argv[0] = $2;
-        argv[1] = $4;
-        argv[2] = $6;
-        argt[2] = argt[1] = argt[0] = ARG_REG;
-        add_line(TYPE_CMD, "add", 3, argv, argt);
-    }
-    ;
-
-symbol:
-    symbol symbol
-    | COMMENT   { printf("Found comment: %s\n", $1); }
-    | DIRECTIVE { printf("Found directive: %s\n", $1); }
-    | WORD      { printf("Found word: %s\n", $1); }
-    | LABEL     { printf("Found label: %s\n", $1); }
-    | INT       { printf("Found integer: %d\n", $1); }
-    | OFFSET    { printf("Found offset registry address: %s\n", $1); }
-    | CMD       { printf("Found command: %s\n", $1); }
-    | COMMA     { printf("Found comma\n"); }
-    | NL        { printf("Found newline\n"); }
-    ;
-%%
-
-extern int yylex();
-extern int yyparse();
-extern FILE *yyin;
-
-main(int argc, const char *argv[])
-{
-    if( argc < 2 ) {
-        printf("No file specified");
-        exit(-1);
-    }
-
-    // open a file handle to a particular file:
-	FILE *myfile = fopen(argv[1], "r");
-	// make sure it is valid:
-	if( !myfile ) {
-		printf("Cannot open %s\n", argv[1]);
-		return -1;
-	}
-	// set lex to read from it instead of defaulting to STDIN:
-	yyin = myfile;
-
-	// parse through the input until there is no more:
-	do {
-		yyparse();
-	} while( !feof(yyin) );
-}
-
-void yyerror(char *s)
-{
-    printf("Error: %s\n", s);
-    exit(1);
-}
-
-void add_line(int type, const char *name, int argc, char **argv, int *argt) {
-    line *l = (line*)malloc(sizeof(line));
-    printf("\nName: %s\n\n", name);
-
-    l->argc = argc;
-    l->argv = argv;
-    l->argt = argt;
-
-    if( last_line == NULL ) {
-        // First line
-        first_line = last_line = l;
-    } else {
-        // Add line to linked list
-        l->prev = last_line;
-        last_line = last_line->next = l;
-    }
-}

+ 0 - 19
src/lex.l

@@ -1,19 +0,0 @@
-%{
-#include <stdio.h>
-#include "y.tab.h"
-%}
-word    [a-zA-Z0-9$_]+
-int     [0-9]+
-%%
-
-[\n]                { return NL; }                              /* Newline */
-#.*                 { yylval.sval = yytext; return COMMENT; }   /* Comment */
-\..*                { yylval.sval = yytext; return DIRECTIVE; } /* Assembly directive */
-{word}:             { yylval.sval = yytext; return LABEL; }      /* Label */
-{int}               { yylval.ival = atoi(yytext); return INT; } /* Integer */
-{word}              { yylval.sval = yytext; return WORD; }      /* Label reference / registry address */
-{int}(\({word}\))?  { yylval.sval = yytext; return OFFSET; }    /* Registry offset address */
-[a-z0-9\.]+         { yylval.sval = yytext; return CMD;   }     /* Command */
-[,]                 { return COMMA; }                           /* Comma */
-
-[ \t]+              ;                                           /* Ignore whitespace */

+ 24 - 0
src/peephole.l

@@ -0,0 +1,24 @@
+%{
+#include <stdio.h>
+#include <string.h>
+#include "y.tab.h"
+
+extern int lineno;
+%}
+
+%option noyywrap
+
+word    [a-zA-Z0-9$_.]+
+int     [0-9]+
+
+%%
+
+\n                  { lineno++; printf("ikmatchhemwel!"); return NEWLINE; }
+:                   { return COLON; }
+,                   { return COMMA; }
+#.*                 { yylval.sval = strdup(yytext); return COMMENT; }
+\..*                { yylval.sval = strdup(yytext); return DIRECTIVE; }
+{word}              { yylval.sval = strdup(yytext); return WORD; }
+{int}(\({word}\))?  { yylval.sval = strdup(yytext); return WORD; }
+
+[ \t]+              ;

+ 135 - 0
src/peephole.y

@@ -0,0 +1,135 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+
+// Instruction types
+#define TYPE_COMMENT 0
+#define TYPE_INLINE_COMMENT 1
+#define TYPE_DIRECTIVE 2
+#define TYPE_LABEL 3
+#define TYPE_CMD 4
+
+typedef struct line {
+    // Type:
+    int type;
+    char *name;
+    int argc;
+    char **argv;
+
+    struct line *next;
+} line;
+
+void yyerror(char *error);
+extern int yylex(void);
+void add_line(int type, char *name, int argc, char **argv);
+char **malloc_args(int argc);
+
+line *first_line, *last_line;
+int lineno = 0;
+
+%}
+
+%union {
+    char *sval;
+}
+
+%token <sval> COMMENT DIRECTIVE LABEL WORD
+%token NEWLINE COMMA COLON
+
+%%
+
+input:
+    /* Empty */
+    | input line
+    ;
+
+line:
+    NEWLINE
+    | COMMENT NEWLINE               { add_line(TYPE_COMMENT, $1, 0, NULL); }
+    | instruction NEWLINE
+    | instruction COMMENT NEWLINE   { add_line(TYPE_INLINE_COMMENT, $2, 0, NULL); }
+    ;
+
+instruction:
+    command
+    | DIRECTIVE                     { add_line(TYPE_DIRECTIVE, $1, 0, NULL); }
+    | WORD COLON                    { add_line(TYPE_LABEL, $1, 0, NULL); }
+    | error
+    ;
+
+command:
+    WORD WORD COMMA WORD COMMA WORD {
+            char **argv = malloc_args(3);
+            argv[0] = $2;
+            argv[1] = $4;
+            argv[2] = $6;
+            add_line(TYPE_CMD, $1, 3, argv);
+        }
+    | WORD WORD COMMA WORD {
+            char **argv = malloc_args(2);
+            argv[0] = $2;
+            argv[1] = $4;
+            add_line(TYPE_CMD, $1, 2, argv);
+        }
+    | WORD WORD {
+            char **argv = malloc_args(1);
+            argv[0] = $2;
+            add_line(TYPE_CMD, $1, 1, argv);
+        }
+    ;
+
+%%
+
+extern int yylex();
+extern int yyparse();
+extern FILE *yyin;
+
+/*int main(void) {
+    return yyparse();
+}*/
+
+int main(int argc, const char *argv[]) {
+    if( argc < 2 ) {
+        printf("No file specified");
+        exit(-1);
+    }
+
+    // open a file handle to a particular file:
+	FILE *myfile = fopen(argv[1], "r");
+	// make sure it is valid:
+	if( !myfile ) {
+		printf("Cannot open %s\n", argv[1]);
+		return -1;
+	}
+	// set lex to read from it instead of defaulting to STDIN:
+	yyin = myfile;
+
+	// parse through the input until there is no more:
+	do {
+		yyparse();
+	} while( !feof(yyin) );
+}
+
+void yyerror(char *error) {
+    fprintf(stderr, "Error at line %d: %s\n", lineno, error);
+}
+
+void add_line(int type, char *name, int argc, char **argv) {
+    line *l = (line*)malloc(sizeof(line));
+    printf("%d: %s\n", lineno, name);
+
+    l->argc = argc;
+    l->argv = argv;
+
+    if( last_line == NULL ) {
+        // First line
+        first_line = last_line = l;
+    } else {
+        // Add line to linked list
+        last_line = last_line->next = l;
+    }
+}
+
+char **malloc_args(int argc) {
+    return (char **)malloc(3 * sizeof(char *));
+}