--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "gram.h"
+#include "tok.h"
+#include "lemon.h"
+#include "parser.h"
+
+struct reserved {
+ char word[16];
+ int token;
+};
+
+ /* not quite reserved, but will fallback to WORD in the grammar */
+static struct reserved rwords[] = {
+ { "case", TOKEN_Case }
+ ,{ "esac", TOKEN_Esac }
+ ,{ "in", TOKEN_In }
+ ,{ "if", TOKEN_If }
+ ,{ "then", TOKEN_Then }
+ ,{ "else", TOKEN_Else }
+ ,{ "elif", TOKEN_Elif }
+ ,{ "fi", TOKEN_Fi }
+ ,{ "do", TOKEN_Do }
+ ,{ "done", TOKEN_Done }
+ ,{ "while", TOKEN_While }
+ ,{ "until", TOKEN_Until }
+ ,{ "for", TOKEN_For }
+ ,{ "!", TOKEN_Bang }
+ ,{ "}", TOKEN_Rbrace }
+ ,{ "{", TOKEN_Lbrace }
+ ,{ "",0 }
+};
+
+static int is_name(char *word) {
+ int i;
+ if (isdigit(word[0])) {
+ return 0;
+ }
+ for (i=0;word[i];i++) {
+ if (word[i] != '_' && !isalnum(word[i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int is_reserved(char *word) {
+ int i;
+ for (i=0;rwords[i].token;i++) {
+ fprintf(stderr, "checking rword %s ?= %s\n", word, rwords[i].word);
+ if (!strcmp(word, rwords[i].word)) {
+ fprintf(stderr, "matched\n");
+ return rwords[i].token;
+ }
+ }
+ return 0;
+}
+
+int main(void) {
+ void* parser;
+ struct token_state ts;
+ struct token token;
+ int type, rtype;
+
+ struct parser_state pstate;
+ pstate.casewords = 0;
+ pstate.incase = 0;
+
+ parser = ParseAlloc(malloc);
+ ts_init(&ts, stdin);
+ ParseTrace(stderr, "par: ");
+ while(type = get_token(&ts, &token)) {
+ rtype = 0;
+ if (type == EOF) break;
+ if (token.type == TOKEN_WORD) {
+ rtype = is_reserved(token.text);
+ if (!rtype && is_name(token.text) && 0) {
+ rtype = TOKEN_NAME;
+ }
+ }
+ if (rtype) {
+ token.rtype = rtype;
+ } else {
+ token.rtype = token.type;
+ }
+
+ fprintf(stderr, "feeding type %d\n", token.rtype);
+
+ Parse(parser, token.rtype, &token, &pstate);
+ }
+ Parse(parser, 0, &token, &pstate);
+
+ /* First input:
+ 15 / 5
+ */
+ ParseFree(parser, free );
+
+ return 0;
+}