vm-translator/parser.c

144 lines
2.7 KiB
C
Raw Normal View History

2020-10-29 20:22:03 -04:00
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "parser.h"
2020-11-01 08:53:20 -05:00
void freelns(struct lnarray* lns) {
for(int i = 0; i < lns->count; i++) {
int tkcount = lns->lns[i]->tokenscount;
2020-10-29 21:06:33 -04:00
for(int j = 0; j < tkcount; j++) {
2020-11-01 08:53:20 -05:00
free(lns->lns[i]->tokens[j]);
2020-10-29 21:06:33 -04:00
}
2020-11-01 08:53:20 -05:00
free(lns->lns[i]->tokens);
free(lns->lns[i]);
2020-10-29 21:06:33 -04:00
}
2020-11-01 08:53:20 -05:00
free(lns->lns);
2020-10-29 21:06:33 -04:00
free(lns);
}
2020-11-01 08:53:20 -05:00
void freeparser(struct Parser* p) {
freelns(p->lns);
free(p);
}
2020-10-29 20:22:03 -04:00
void gountilbrk (FILE* input) {
char c;
while(c = fgetc(input), c != -1) {
if(c == '\n') {
ungetc(c, input);
return;
}
}
}
2020-11-01 08:53:20 -05:00
void getinfo(struct Parser* p) {
p->lns->count = 0;
p->maxtokens = 0;
p->widestln = 0;
2020-10-29 20:22:03 -04:00
char c, nc;
int widest = 0;
int currsz = 0;
int tokens = 0;
short readsmt = 0;
2020-11-01 08:53:20 -05:00
while(c = fgetc(p->input), c != -1) {
2020-10-29 21:06:33 -04:00
currsz++;
if(isspace(c)) {
if(readsmt) {
tokens++;
readsmt = 0;
}
if(c == '\n' && tokens > 0) {
2020-11-01 08:53:20 -05:00
p->lns->count++;
if(currsz > p->widestln)
p->widestln = currsz;
if(tokens > p->maxtokens)
p->maxtokens = tokens;
2020-10-29 20:22:03 -04:00
currsz = 0;
tokens = 0;
}
continue;
}
if(c == '/') {
2020-11-01 08:53:20 -05:00
nc = fgetc(p->input);
2020-10-29 20:22:03 -04:00
if(nc == '/') {
2020-11-01 08:53:20 -05:00
gountilbrk(p->input);
2020-10-29 20:22:03 -04:00
continue;
}
2020-11-01 08:53:20 -05:00
ungetc(nc, p->input);
2020-10-29 20:22:03 -04:00
}
readsmt = 1;
}
2020-11-01 08:53:20 -05:00
rewind(p->input);
}
struct Parser* mkparser(FILE* input) {
struct Parser* p = (struct Parser*)malloc(sizeof(struct Parser));
struct lnarray* lns = (struct lnarray*)malloc(sizeof(struct lnarray));
p->input = input;
p->lns = lns;
getinfo(p);
return p;
2020-10-29 20:22:03 -04:00
}
2020-11-01 08:53:20 -05:00
void parse(struct Parser* p) {
struct line** lns = (struct line**)malloc(sizeof(struct line*)*p->lns->count);
p->lns->lns = lns;
p->lns->count = 0;
char tmp[p->widestln];
char* tokens[p->maxtokens];
2020-10-29 20:22:03 -04:00
char c, nc;
short readsmt = 0;
int tmpind = 0;
int tokensind = 0;
int truelncount = 0;
2020-11-01 08:53:20 -05:00
while(c = fgetc(p->input), c != -1) {
2020-10-29 20:22:03 -04:00
if(isspace(c)) {
if(readsmt) {
tmp[tmpind] = '\0';
char* newtoken = (char*)malloc(sizeof(char)*tmpind+1);
strcpy(newtoken, tmp);
tokens[tokensind] = newtoken;
tmpind = 0;
readsmt = 0;
tokensind++;
}
if(c == '\n') {
truelncount++;
if(tokensind > 0) {
struct line* newln = (struct line*)malloc(sizeof(struct line));
newln->tokens = (char**)malloc(sizeof(char*)*tokensind);
for(int i = 0; i < tokensind; i++) {
newln->tokens[i] = tokens[i];
}
newln->tokenscount = tokensind;
newln->truen = truelncount;
2020-11-01 08:53:20 -05:00
lns[p->lns->count] = newln;
p->lns->count++;
2020-10-29 20:22:03 -04:00
tokensind = 0;
}
}
continue;
}
if(c == '/') {
2020-11-01 08:53:20 -05:00
nc = fgetc(p->input);
2020-10-29 20:22:03 -04:00
if(nc == '/') {
2020-11-01 08:53:20 -05:00
gountilbrk(p->input);
2020-10-29 20:22:03 -04:00
continue;
}
2020-11-01 08:53:20 -05:00
ungetc(nc, p->input);
2020-10-29 20:22:03 -04:00
}
tmp[tmpind] = c;
tmpind++;
readsmt = 1;
}
2020-11-01 08:53:20 -05:00
fclose(p->input);
2020-10-29 20:22:03 -04:00
}