From 460d4f4259153ff3fffb2618c4e5e385b5b29f24 Mon Sep 17 00:00:00 2001 From: lquint Date: Fri, 6 Aug 2021 01:39:54 +0200 Subject: [PATCH] adding new files --- peg-engine.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ peg-nodes.h | 44 +++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 peg-engine.c create mode 100644 peg-nodes.h diff --git a/peg-engine.c b/peg-engine.c new file mode 100644 index 0000000..0322f86 --- /dev/null +++ b/peg-engine.c @@ -0,0 +1,106 @@ +#include +#include +#include + +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 setBit(char *bits, int n) +{ + bits[n/8] |= (1 << n%8); +} + +int testBit(char *bits, int n) +{ + return bits[n/8] & (1 << n%8); +} + +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(); +} \ No newline at end of file diff --git a/peg-nodes.h b/peg-nodes.h new file mode 100644 index 0000000..4432da4 --- /dev/null +++ b/peg-nodes.h @@ -0,0 +1,44 @@ +enum op { String, Query, Star, Plus, Or, And, Class, Dot, Exc, Et, Id} ; + + +typedef union Node Node; +typedef struct Symbol Symbol; +typedef struct SymbolTable SymbolTable; +typedef struct NodeCount NodeCount; + + +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; + int number; +}; + + +