1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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);
}
|