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

Finished parser.

parent 655adbfb
......@@ -7,4 +7,4 @@
lex.yy.c
y.tab.c
y.tab.h
parser
peephole
CC=gcc
LEX=lex
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
%{
#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 @@
// 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
#define TYPE_INLINE_COMMENT 1
#define TYPE_DIRECTIVE 2
#define TYPE_LABEL 3
#define TYPE_CMD 4
typedef struct line {
// Type:
int type;
const char *name;
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);
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 {
int ival;
char *sval;
}
%token NL COMMA
%token <ival> INT
%token <sval> COMMENT DIRECTIVE WORD LABEL OFFSET CMD
%start symbol
%type <sval> command
%token <sval> COMMENT DIRECTIVE LABEL WORD
%token NEWLINE COMMA COLON
%%
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);
}
input:
/* Empty */
| input line
;
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"); }
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;
main(int argc, const char *argv[])
{
/*int main(void) {
return yyparse();
}*/
int main(int argc, const char *argv[]) {
if( argc < 2 ) {
printf("No file specified");
exit(-1);
......@@ -99,26 +110,26 @@ main(int argc, const char *argv[])
} while( !feof(yyin) );
}
void yyerror(char *s)
{
printf("Error: %s\n", s);
exit(1);
void yyerror(char *error) {
fprintf(stderr, "Error at line %d: %s\n", lineno, error);
}
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));
printf("\nName: %s\n\n", name);
printf("%d: %s\n", lineno, 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;
}
}
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