#include #include #include #include // generated #include "bin/calc.h" #include "bin/calc.c" #include "parts/grammar.h" #include "parts/precedence.h" #include "parts/toklist.h" static struct token { symbol s; int v; } tok; static char *next_token(char *str); symbol token_sym(struct token *t) { return t->s; } intptr_t token_val(struct token *t) { return (intptr_t)t->v; } static char *input; struct token *toklist_eat() { static struct token t; t = tok; input = next_token(input); return &t; } struct token *toklist_peek() { return &tok; } #include "lr-parser.c" int main(int argc, char **argv) { if(argc != 2) return 1; input = next_token(argv[1]); intptr_t value; if(lr_parser(&value)) return 1; printf("INPUT: '%s'\n", argv[1]); printf("OUTPUT: %jd\n", value); return 0; } // LEXER static inline int issep(char c) { return isspace(c) || c == '\0' || c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '>' || c == '<' || c == '=' || c == '?' || c == ':'; } static inline int tillsep(char *str) { size_t i = 0; while(!issep(str[i++])); return i-1; } static inline char *substring(char *str, size_t sub_end) { static char sub[128]; if(sub_end+1 > sizeof(sub)) return NULL; sub[sub_end] = '\0'; return memcpy(sub, str, sub_end); } static char *next_token(char *str) { size_t off = 0; char c0 = str[0]; if(c0 == '\0') tok.s = END_INPUT; if(isspace(c0)) return next_token(str+1); else { off = tillsep(str); if(off == 0) { // sep switch(str[off++]) { case '(': tok.s = LPAREN; break; case ')': tok.s = RPAREN; break; case '-': tok.s = MINUS; break; case '+': tok.s = PLUS; break; case '*': tok.s = TIMES; break; case '>': tok.s = MORE; break; case '<': tok.s = LESS; break; case '=': tok.s = EQUA; break; case '?': tok.s = QMARK; break; case ':': tok.s = COLON; break; } } else if(c0 >= '0' && c0 <= '9') { // num tok.s = NUM; tok.v = atoi(substring(str, off)); } } return str+off; }