|
|
@ -8,6 +8,9 @@ |
|
|
|
#include <math.h> |
|
|
|
|
|
|
|
#include "inputBuffer.c" |
|
|
|
|
|
|
|
#include "peg-nodes.h" |
|
|
|
#include "peg-engine.c" |
|
|
|
#include "class.c" |
|
|
|
; |
|
|
|
|
|
|
@ -22,63 +25,19 @@ void fatal(char *fmt, ...) |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
enum op { String, Query, Star, Plus, Or, And, Class, Dot, Exc, Et, Id} ; |
|
|
|
|
|
|
|
|
|
|
|
typedef union Node Node; |
|
|
|
typedef struct Symbol Symbol; |
|
|
|
typedef struct Array Array; |
|
|
|
typedef struct SymbolTable SymbolTable; |
|
|
|
typedef struct NodeCount NodeCount; |
|
|
|
|
|
|
|
struct Array { |
|
|
|
Node **elements; |
|
|
|
int length; |
|
|
|
}; |
|
|
|
|
|
|
|
struct String { enum op type; char *string; int len; }; |
|
|
|
struct Query { enum op type; Node *children[1]; }; |
|
|
|
struct Star { enum op type; Node *children[1]; }; |
|
|
|
struct Plus { enum op type; Node *children[1]; }; |
|
|
|
struct Or { enum op type; Node *children[2]; }; |
|
|
|
struct And { enum op type; Node *children[2]; }; |
|
|
|
struct Class { enum op type; char *array; }; |
|
|
|
struct Dot { enum op type; }; |
|
|
|
struct Exc { enum op type; Node *children[1]; }; |
|
|
|
struct Et { enum op type; Node *children[1]; }; |
|
|
|
struct Id { enum op type; Symbol *symbol; }; |
|
|
|
|
|
|
|
union Node { |
|
|
|
enum op type; |
|
|
|
struct String String; |
|
|
|
struct Query Query; |
|
|
|
struct Star Star; |
|
|
|
struct Plus Plus; |
|
|
|
struct Or Or; |
|
|
|
struct And And; |
|
|
|
struct Class Class; |
|
|
|
struct Dot Dot; |
|
|
|
struct Exc Exc; |
|
|
|
struct Et Et; |
|
|
|
struct Id Id; |
|
|
|
}; |
|
|
|
|
|
|
|
struct Symbol{ |
|
|
|
char* name; |
|
|
|
Node *rule; |
|
|
|
}; |
|
|
|
|
|
|
|
struct SymbolTable { |
|
|
|
Symbol **elements; |
|
|
|
int length; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#define SymbolTable_initialiser {0,0} |
|
|
|
SymbolTable symbolTable= SymbolTable_initialiser; |
|
|
|
|
|
|
|
Symbol *createSymbol(char *name) { |
|
|
|
Symbol *symbol= calloc(1, sizeof(Symbol)); |
|
|
|
symbol->name= strdup(name); |
|
|
|
symbol->number=0; |
|
|
|
return symbol; |
|
|
|
} |
|
|
|
|
|
|
@ -175,15 +134,7 @@ Node *mkEt(Node *n) |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *_checktype(Node *object, enum op type) |
|
|
|
{ |
|
|
|
if (object->type == type) return object; |
|
|
|
fprintf(stderr, "\naccesing type %i as if it were a %i\n", object->type, type); |
|
|
|
exit(1); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
#define get(object, type, member) (_checktype(object, type)->type.member) |
|
|
|
|
|
|
|
void print(Node *node) |
|
|
|
{ |
|
|
@ -299,7 +250,7 @@ declaration = i:id '=' - e:expression { setRule(get(i, Id, symbol)->name, e) } |
|
|
|
|
|
|
|
expression = or |
|
|
|
|
|
|
|
or = a:and "|" - o:or { $$ = mkOr(o, a) } |
|
|
|
or = a:and "|" - o:or { $$ = mkOr(a, o) } |
|
|
|
| a:and { $$ = a } |
|
|
|
|
|
|
|
and = p:prefix a:and { $$ = mkAnd(p, a) } |
|
|
@ -332,88 +283,7 @@ space = [ \t] | '\n' '\r'* | '\r' '\n'* |
|
|
|
|
|
|
|
%% |
|
|
|
|
|
|
|
int execute(Node *node, InputBuffer *in) |
|
|
|
{ |
|
|
|
switch (node->type) { |
|
|
|
case String: { |
|
|
|
if (strncmp(currentText(in), get(node,String,string), get(node,String,len))) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
advance(in, get(node,String,len)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case And: { |
|
|
|
int pos= getPosition(in); |
|
|
|
if (!execute(get(node,And,children[0]), in)) //si il y a eu une erreur |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} //si ça s'est bien passé |
|
|
|
if (!execute(get(node,And,children[1]), in)) { |
|
|
|
setPosition(in, pos); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case Or: { |
|
|
|
if (execute(get(node,Or,children[0]), in)) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return execute(get(node,Or,children[1]), in); |
|
|
|
} |
|
|
|
case Star: { |
|
|
|
while (execute(get(node,Star,children[0]), in)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case Plus: { |
|
|
|
if (!execute(get(node,Plus,children[0]), in)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
while (execute(get(node,Plus,children[0]), in)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case Class: { |
|
|
|
if (testBit(get(node,Class,array),currentChar(in))) { |
|
|
|
advance(in, 1); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
case Query: { |
|
|
|
execute(get(node,Query,children[0]), in); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case Exc: { |
|
|
|
int pos= getPosition(in); |
|
|
|
if (!execute(get(node,Exc,children[0]), in)) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
setPosition(in, pos); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
case Et: { |
|
|
|
int pos= getPosition(in); |
|
|
|
if (!execute(get(node,Et,children[0]), in)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
setPosition(in, pos); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case Dot: { |
|
|
|
if (atEnd(in)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
advance(in, 1); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case Id: { |
|
|
|
Symbol *symbol= get(node, Id, symbol); |
|
|
|
if (0 == symbol->rule) { printf("undefined rule: %s\n", symbol->name); } |
|
|
|
return execute(symbol->rule, in); |
|
|
|
} |
|
|
|
} |
|
|
|
printf("this cannot happen\n"); |
|
|
|
abort(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct NodeCount{ |
|
|
|
int String; |
|
|
@ -544,76 +414,72 @@ int nodeNumber=0; |
|
|
|
|
|
|
|
int printCode(FILE *file,Node *node) |
|
|
|
{ |
|
|
|
|
|
|
|
int thisNumber=++nodeNumber; |
|
|
|
switch (node->type) { |
|
|
|
|
|
|
|
case String:{ |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
|
|
|
|
fprintf(file,"Node node%i = { .String = { String, ",thisNumber); |
|
|
|
fprintf(file,"\"%s\"", node->String.string); |
|
|
|
fprintf(file," , %i }}; \n",node->String.len); |
|
|
|
fprintf(file," , %i }}; \n",node->String.len); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Query: { |
|
|
|
int i = printCode(file,node->Query.children[0]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i",thisNumber); |
|
|
|
fprintf(file,"= { .Query = { Query, &node%i }};\n",i); |
|
|
|
fprintf(file,"= { .Query = { Query, {&node%i} }};\n",i); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Star: { |
|
|
|
int i = printCode(file,node->Star.children[0]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i",thisNumber); |
|
|
|
fprintf(file,"= { .Star = { Star, &node%i }};\n",i); |
|
|
|
fprintf(file,"= { .Star = { Star, {&node%i} }};\n",i); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Plus:{ |
|
|
|
int i = printCode(file,node->Plus.children[0]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i = { .Plus = { Plus, &node%i }};\n",thisNumber,i); |
|
|
|
fprintf(file,"Node node%i = { .Plus = { Plus, {&node%i} }};\n",thisNumber,i); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Or:{ |
|
|
|
int i = printCode(file,node->Or.children[0]); |
|
|
|
int j = printCode(file,node->Or.children[1]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i= { .Or = { Or, &node%i",thisNumber,i); |
|
|
|
fprintf(file," , &node%i }};\n",j); |
|
|
|
fprintf(file,"Node node%i= { .Or = { Or, {&node%i",thisNumber,i); |
|
|
|
fprintf(file," , &node%i} }};\n",j); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case And:{ |
|
|
|
int i = printCode(file,node->And.children[0]); |
|
|
|
int j = printCode(file,node->And.children[1]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i= { .And = { And, &node%i",thisNumber,i); |
|
|
|
fprintf(file," , &node%i }};\n",j); |
|
|
|
fprintf(file,"Node node%i= { .And = { And, {&node%i",thisNumber,i); |
|
|
|
fprintf(file," , &node%i} }};\n",j); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Class:{ |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i= { .Class = { Class, %s }};\n",thisNumber,node->Class.array); |
|
|
|
fprintf(file,"Node node%i= { .Class = { Class, \"",thisNumber); |
|
|
|
for(int i=0;i<32;i++){ |
|
|
|
fprintf(file,"\\%03o",(unsigned char)node->Class.array[i]); |
|
|
|
} |
|
|
|
fprintf(file,"\" }};\n"); |
|
|
|
|
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Dot:{ |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i= { .Dot = { Dot}};\n",thisNumber); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Exc:{ |
|
|
|
int i = printCode(file,node->Exc.children[0]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i = { .Exc = { Exc, &node%i }};\n",thisNumber,i); |
|
|
|
fprintf(file,"Node node%i = { .Exc = { Exc, {&node%i} }};\n",thisNumber,i); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Et: { |
|
|
|
int i = printCode(file,node->Et.children[0]); |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i = { .Et = { Et, &node%i }};\n",thisNumber,i); |
|
|
|
fprintf(file,"Node node%i = { .Et = { Et, {&node%i} }};\n",thisNumber,i); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
|
case Id: { |
|
|
|
int thisNumber=nodeNumber++; |
|
|
|
fprintf(file,"Node node%i = { .Id = { Id, %s", thisNumber, get(node,Id, symbol)->name); |
|
|
|
fprintf(file,"Node node%i = { .Id = { Id, &symbol_%s", thisNumber, get(node,Id, symbol)->name); |
|
|
|
fprintf(file," }};\n"); |
|
|
|
return thisNumber; |
|
|
|
} |
|
|
@ -628,6 +494,18 @@ void printSymbolTable(FILE *file) { |
|
|
|
for (int k= 0; k<symbolTable.length; k++) { |
|
|
|
int i=printCode(file,symbolTable.elements[k]->rule); |
|
|
|
fprintf(file,"Node *%s= &node%i;\n",symbolTable.elements[k]->name,i); |
|
|
|
symbolTable.elements[k]->number=i; |
|
|
|
} |
|
|
|
} |
|
|
|
void declareSymbols(FILE *file) { |
|
|
|
for (int k= 0; k<symbolTable.length; k++) { |
|
|
|
fprintf(file,"Symbol symbol_%s ;\n",symbolTable.elements[k]->name); |
|
|
|
} |
|
|
|
} |
|
|
|
void defineSymbols(FILE *file) { |
|
|
|
for (int k= 0; k<symbolTable.length; k++) { |
|
|
|
Symbol *s=symbolTable.elements[k]; |
|
|
|
fprintf(file,"Symbol symbol_%s = { \"%s\", &node%i, %i};\n",s->name,s->name,s->number,s->number); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -688,7 +566,9 @@ int main(int argc, char **argv) |
|
|
|
//int i=printCode(intern("start")->rule); |
|
|
|
//printf("Node *start_rule= &node%i;\n",i); |
|
|
|
FILE *outputFile = fopen(opt_c,"w"); |
|
|
|
declareSymbols(outputFile); |
|
|
|
printSymbolTable(outputFile); |
|
|
|
defineSymbols(outputFile); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|