Commit c3ba2d2d authored by Taddeüs Kroes's avatar Taddeüs Kroes

Finished parser.

parent 655adbfb
...@@ -7,4 +7,4 @@ ...@@ -7,4 +7,4 @@
lex.yy.c lex.yy.c
y.tab.c y.tab.c
y.tab.h y.tab.h
parser peephole
CC=gcc CC=gcc
LEX=lex LEX=lex
YACC=yacc YACC=yacc
CFLAGS=-ll
parser: yacc lex CFLAGS = -std=c99 -pedantic -Wall -D_POSIX_SOURCE -D_GNU_SOURCE $(PIC) -pipe
$(CC) -c lex.yy.c y.tab.c
$(CC) -o $@ lex.yy.o y.tab.o $(CFLAGS)
lex: lex.l all: peephole
$(LEX) lex.l
yacc: grammar.y peephole: y.tab.o lex.yy.o
$(YACC) -d grammar.y $(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
%{
#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 */
%{
#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]+ ;
...@@ -4,80 +4,91 @@ ...@@ -4,80 +4,91 @@
// Instruction types // Instruction types
#define TYPE_COMMENT 0 #define TYPE_COMMENT 0
#define TYPE_DIRECTIVE 1 #define TYPE_INLINE_COMMENT 1
#define TYPE_LABEL 2 #define TYPE_DIRECTIVE 2
#define TYPE_CMD 3 #define TYPE_LABEL 3
#define TYPE_CMD 4
// Argument types
#define ARG_INT 0
#define ARG_REG 1
#define ARG_LABEL 2
#define ARG_OFFSET 3
typedef struct line { typedef struct line {
// Type:
int type; int type;
const char *name; char *name;
int argc; int argc;
char **argv; char **argv;
int *argt;
struct line *prev;
struct line *next; struct line *next;
} line; } line;
void yyerror(char*); void yyerror(char *error);
void add_line(int type, const char *name, int argc, char **argv, int *argt); 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; line *first_line, *last_line;
int lineno = 0;
%} %}
%union { %union {
int ival;
char *sval; char *sval;
} }
%token NL COMMA %token <sval> COMMENT DIRECTIVE LABEL WORD
%token <ival> INT %token NEWLINE COMMA COLON
%token <sval> COMMENT DIRECTIVE WORD LABEL OFFSET CMD
%start symbol
%type <sval> command
%% %%
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: command:
"add" WORD COMMA WORD COMMA WORD { WORD WORD COMMA WORD COMMA WORD {
char **argv = (char **)malloc(3 * sizeof(char *)); char **argv = malloc_args(3);
int *argt = (int *)malloc(3 * sizeof(int));
argv[0] = $2; argv[0] = $2;
argv[1] = $4; argv[1] = $4;
argv[2] = $6; argv[2] = $6;
argt[2] = argt[1] = argt[0] = ARG_REG; add_line(TYPE_CMD, $1, 3, argv);
add_line(TYPE_CMD, "add", 3, argv, argt); }
| 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);
} }
; ;
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 yylex();
extern int yyparse(); extern int yyparse();
extern FILE *yyin; extern FILE *yyin;
main(int argc, const char *argv[]) /*int main(void) {
{ return yyparse();
}*/
int main(int argc, const char *argv[]) {
if( argc < 2 ) { if( argc < 2 ) {
printf("No file specified"); printf("No file specified");
exit(-1); exit(-1);
...@@ -99,26 +110,26 @@ main(int argc, const char *argv[]) ...@@ -99,26 +110,26 @@ main(int argc, const char *argv[])
} while( !feof(yyin) ); } while( !feof(yyin) );
} }
void yyerror(char *s) void yyerror(char *error) {
{ fprintf(stderr, "Error at line %d: %s\n", lineno, error);
printf("Error: %s\n", s);
exit(1);
} }
void add_line(int type, const char *name, int argc, char **argv, int *argt) { void add_line(int type, char *name, int argc, char **argv) {
line *l = (line*)malloc(sizeof(line)); line *l = (line*)malloc(sizeof(line));
printf("\nName: %s\n\n", name); printf("%d: %s\n", lineno, name);
l->argc = argc; l->argc = argc;
l->argv = argv; l->argv = argv;
l->argt = argt;
if( last_line == NULL ) { if( last_line == NULL ) {
// First line // First line
first_line = last_line = l; first_line = last_line = l;
} else { } else {
// Add line to linked list // Add line to linked list
l->prev = last_line;
last_line = last_line->next = l; last_line = last_line->next = l;
} }
} }
char **malloc_args(int argc) {
return (char **)malloc(3 * sizeof(char *));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment