diff options
-rw-r--r-- | example.pl | 1 | ||||
-rw-r--r-- | fns.h | 2 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | parser.c | 36 |
4 files changed, 22 insertions, 22 deletions
@@ -16,6 +16,7 @@ likes(sam, ice). could_be_friends(Person1, Person2) :- likes(Person1, Thing1), likes(Person2, Thing2), + !, Thing1 = Thing2. list1(A) :- A = [1,2,3,4]. @@ -1,5 +1,5 @@ /* parser.c */ -void parse(int); +Term *parse(int); /* prettyprint.c */ Rune *prettyprint(Term *); @@ -29,7 +29,10 @@ main(int argc, char *argv[]) int fd = open(parsetestfile, OREAD); if(fd < 0) exits("open"); - parse(fd); + Term *prog = parse(fd); + Term *clause; + for(clause = prog; clause != nil; clause = clause->next) + print("%S.\n", prettyprint(clause)); } exits(nil); @@ -7,9 +7,6 @@ #define PrecedenceLevels 1200 -/* The parser doesn't produce an ast for now, it only acts like a recognizer, - printing errors if it fails */ - typedef struct Token Token; typedef struct Operator Operator; typedef struct OpInfo OpInfo; @@ -79,50 +76,48 @@ Term *compound(void); Term *parseoperators(Term *); void match(int); void syntaxerror(char *); -void prologtext(void); +Term *prologtext(void); -void +Term * parse(int fd) { parsein = Bfdopen(fd, OREAD); if(parsein == nil){ print("Could not open file\n"); - return; + return nil; } initoperators(); nexttoken(); - prologtext(); + return prologtext(); } -void +Term * prologtext(void) { if(lookahead.tag == EofTok) - return; + return nil; Term *t = fullterm(AtomTok, L".", nil); + if(lookahead.tag == AtomTok && runestrcmp(lookahead.text, L".") == 0) + match(AtomTok); + else + syntaxerror("prologtext"); if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 1){ /* A Directive */ print("Got directive: %S\n", prettyprint(t)); + t = prologtext(); }else if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){ - /* A clause with a body */ - print("Got clause with body: %S\n", prettyprint(t)); + t->next = prologtext(); }else if(t->tag == AtomTerm || t->tag == CompoundTerm){ - /* A clause without a body */ - print("Got clause without body: %S\n", prettyprint(t)); + t->next = prologtext(); }else{ print("Expected directive or clause as toplevel\n"); syntaxerror("prologtext"); } - if(lookahead.tag == AtomTok && runestrcmp(lookahead.text, L".") == 0) - match(AtomTok); - else - syntaxerror("prologtext"); - - prologtext(); + return t; } Term * @@ -567,7 +562,7 @@ Integer: } /* Other */ - if(runestrchr(L",.()]}|", peek)){ + if(runestrchr(L",.()]}|!", peek)){ switch(peek){ case L',': lookahead.tag = CommaTok; break; case L'(': lookahead.tag = ParenLeftTok; break; @@ -575,6 +570,7 @@ Integer: case L']': lookahead.tag = SquareBracketRightTok; break; case L'}': lookahead.tag = CurlyBracketRightTok; break; case L'|': lookahead.tag = PipeTok; break; + case L'!': lookahead.tag = AtomTok; lookahead.text = runestrdup(L"!"); break; } return; } |