diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-08-06 11:51:11 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-08-06 11:51:11 +0200 |
commit | 6eb5ea040f9ebc1a99953ff72c48ebe9f97f7f3c (patch) | |
tree | 8cfe5e013cf551053ebb4faceaa514c435a7e3c6 /parser.c | |
parent | 2696105687d9c889ec4cccd449846135f83af404 (diff) |
Ditch suffix; make prefix work better
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 15 |
1 files changed, 14 insertions, 1 deletions
@@ -118,6 +118,14 @@ static Token nexttoken(const char **sourcep,bool expectop){ *sourcep+=oplen; return tok; } + if(!expectop){ + char buf[4]={'(',*source,')','\0'}; + if(precedence(buf)!=-1){ + Token tok={TT_OP,source,1}; + (*sourcep)++; + return tok; + } + } if(strchr("(){}",*source)!=NULL){ Token tok={TT_SYM,source,1}; (*sourcep)++; @@ -275,7 +283,7 @@ static AST* parseterm(const char *source,int *reslen){ node->o.op=opconststring_len(buf,tok.len+2); node->o.left=NULL; int len; - node->o.right=parseterm(source,&len); + node->o.right=parseexpr(source,&len,precedence(buf)); if(!node->o.right){ free(node); return NULL; @@ -290,6 +298,7 @@ static AST* parseterm(const char *source,int *reslen){ case TT_ERR: return NULL; } + *reslen=source-origsource; return node; } @@ -306,10 +315,12 @@ static AST* parseexpr(const char *source,int *reslen,int minprec){ Token tok=nexttoken(&source,true); printtoken(stderr,tok,"parseEXPR"); if(tok.type==TT_ENDSTMT){ + fprintf(stderr," (token undo)\n"); source=beforeop; break; } if(tok.type==TT_SYM&&tok.len==1&&tok.str[0]==')'){ + fprintf(stderr," (token undo)\n"); source=beforeop; break; } @@ -319,6 +330,7 @@ static AST* parseexpr(const char *source,int *reslen,int minprec){ } int prec=precedence_len(tok.str,tok.len); if(prec<minprec){ + fprintf(stderr," (token undo)\n"); source=beforeop; break; } @@ -383,6 +395,7 @@ AST* parse(const char *source){ cursor+=reslen; const char *src=source+cursor; Token tok=nexttoken(&src,false); + printtoken(stderr,tok,"parse "); if(tok.type!=TT_ENDSTMT){ ast_free(bl); return NULL; |