summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-18 20:52:28 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-18 20:52:28 +0200
commit2c30522aa65126ebacfd52f7b38a2e24682d7065 (patch)
tree12baf2dfe17cc86f3c9711a700f6f9bbd3764275 /parser.c
parent235ffca9db0c2ba0d1ecbc79bdfb3dcdfca939c7 (diff)
Second
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..7e7a1c2
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,94 @@
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "parser.h"
+#include "util.h"
+
+typedef struct Cursor{
+ const char *s;
+ int l;
+} Cursor;
+
+typedef enum Tokentype{
+ TT_EOF, //str=NULL, len=-1
+ TT_SYMBOL,
+ TT_WORD,
+ TT_NUMBER,
+
+ TT_ERR=-1 //str is an error description, len=-1
+} Tokentype;
+
+typedef struct Token{
+ Tokentype type;
+ const char *str; //pointer into source
+ int len;
+} Token;
+
+#define SYMBOLCHARS "()[]"
+
+
+static Token tt_make(Tokentype type,const char *str,int len){
+ Token tok={type,str,len};
+ return tok;
+}
+
+static Token tt_eof(void){
+ return tt_make(TT_EOF,NULL,-1);
+}
+
+static Token tt_err(const char *errstr){
+ return tt_make(TT_ERR,errstr,-1);
+}
+
+
+static void advance(Cursor *cursor,int n){
+ assert(cursor->l>=n);
+ cursor->s+=n;
+ cursor->l-=n;
+}
+
+static bool iswordchar(char c){
+ return strchr(SYMBOLCHARS,c)==NULL&&c>=33&&c<=126;
+}
+
+static Token nexttoken(Cursor *cursor){
+ while(cursor->l>=1&&isspace(*cursor->s))advance(cursor,1);
+ if(cursor->l==0)return tt_eof();
+
+ if(strchr(SYMBOLCHARS,*cursor->s)!=NULL){
+ advance(cursor,1);
+ return tt_make(TT_SYMBOL,cursor->s-1,1);
+ }
+
+ if(isdigit(*cursor->s)||(cursor->l>=2&&cursor->s[0]=='-'&&isdigit(cursor->s[1]))){
+ char *endp;
+ strtod(cursor->s,&endp);
+ assert(endp>cursor->s);
+ int len=endp-cursor->s;
+ advance(cursor,len);
+ return tt_make(TT_NUMBER,cursor->s-len,len);
+ }
+
+ int i;
+ for(i=0;i<cursor->l;i++){
+ if(!iswordchar(cursor->s[i]))break;
+ }
+ if(i==0){
+ return tt_err("Unrecognised character while looking for next token");
+ }
+ advance(cursor,i);
+ return tt_make(TT_WORD,cursor->s-i,i);
+}
+
+
+static ParseRet parse_(Cursor *cursor){
+ ;
+}
+
+
+ParseRet parse(const char *source,int length){
+ Cursor cursor={source,length};
+ return parse_(&cursor);
+}