/* pa.c */ #include #include "io.h" #include "la.h" #include "pa.h" #include "sa.h" void print_type(FILE *f, void *t); void init_parser(void) { init_lexical_analyser(); } void prepare_parser(void) { get_lexeme(); } void nlind(FILE *f, int ind, int ln) { int i; fprintf(f,"\n%5d: ",ln); for (i=0; ilinenum); } void ps(FILE *f, Syntax *t, int ind) { struct Sgeneric *g=t; if (t==NULL) { fprintf(f,""); return; } switch (g->tag) { case TTbad: { fprintf(f,""); return; } case TTnull: { fprintf(f,"NULL"); return; } case TTidentifier: { struct Sidentifier *s=t; print_identifier(f,s->symbol); return; } case TTinteger: { struct Sinteger *s=t; fprintf(f,"%d",s->value); return; } case TTfloat: { struct Sfloat *s=t; fprintf(f,"%f",s->value); return; } case TTstring: { struct Sstring *s=t; print_string(f,s->thestring); return; } case TTbinaryexpr: { struct Sbinaryexpr *s=t; fprintf(f,"("); ps(f,s->left,ind); print_operator(f,s->operator); ps(f,s->right,ind); fprintf(f,")"); return; } case TTunaryexpr: { struct Sunaryexpr *s=t; fprintf(f,"("); print_operator(f,s->operator); ps(f,s->operand,ind); fprintf(f,")"); return; } case TTfunctioncall: { struct Sfunctioncall *s=t; fprintf(f,"("); ps(f,s->function,ind); fprintf(f,"("); if(s->arguments!=NULL) ps(f,s->arguments,ind); fprintf(f,"))"); return; } case TTarrayaccess: { struct Sarrayaccess *s=t; fprintf(f,"("); ps(f,s->array,ind); fprintf(f,"["); ps(f,s->index,ind); fprintf(f,"])"); return; } case TTfieldselect: { struct Sfieldselect *s=t; fprintf(f,"("); ps(f,s->structure,ind); fprintf(f,"."); print_identifier(f,s->field); fprintf(f,")"); return; } case TTexpressionlist: { struct Sexpressionlist *s=t; while (s->tag==TTexpressionlist) { ps(f,s->first,ind); s=s->rest; if (s==NULL) return; fprintf(f,","); } ps(f,s,ind); return; } case TTstatementlist: { struct Sstatementlist *s=t; while (s->tag==TTstatementlist) { ps(f,s->first,ind); s=s->rest; if (s==NULL) return; nlind(f,ind,getlinenumber(s)); } ps(f,s,ind); return; } case TTblock: { struct Sblock *s=t; fprintf(f,"{ "); if (s->declarations!=NULL) { ps(f,s->declarations,ind+2); if (s->statements!=NULL) nlind(f,ind+2,getlinenumber(s->statements)); } if (s->statements!=NULL) ps(f,s->statements,ind+2); fprintf(f," }"); return; } case TTexprstatement: { struct Sexprstatement *s=t; ps(f,s->expression,ind); fprintf(f,";"); return; } case TTifstatement: { struct Sifstatement *s=t; fprintf(f,"if "); ps(f,s->condition,ind); nlind(f,ind,getlinenumber(s->iftrue)); ps(f,s->iftrue,ind); if (s->iffalse!=NULL) { nlind(f,ind,getlinenumber(s->iffalse)); fprintf(f,"else"); nlind(f,ind,getlinenumber(s->iffalse)); ps(f,s->iffalse,ind); } return; } case TTwhilestatement: { struct Swhilestatement *s=t; fprintf(f,"while "); ps(f,s->condition,ind); nlind(f,ind,getlinenumber(s->body)); ps(f,s->body,ind); return; } case TTreturnstatement: { struct Sreturnstatement *s=t; if (s->value==NULL) fprintf(f,"return;"); else { fprintf(f,"return ("); ps(f,s->value,ind); fprintf(f,");"); } return; } case TTfixeddecl: { struct Sfixeddecl *s=t; fprintf(f,"declare "); print_identifier(f,s->var); fprintf(f,": "); print_type(f,s->type); fprintf(f,";"); return; } case TTfixedparam: { struct Sfixeddecl *s=t; print_identifier(f,s->var); fprintf(f,": "); print_type(f,s->type); return; } case TTstructtype: { struct Sstructtype *s=t; int len=7; fprintf(f,"struct "); if (s->name!=NULL) { print_identifier(f,s->name); len+=strlen(s->name->name)+3; fprintf(f," "); } if (s->fielddecs!=NULL) { fprintf(f,"{ "); ps(f,s->fielddecs,ind+len); fprintf(f," }"); } return; } case TTsimpletype: { struct Ssimpletype *s=t; print_type_symbol(f,s->type); return; } case TTdeclareitemvar: { struct Sdeclareitemvar *s=t; print_identifier(f,s->variable); return; } case TTdeclareitemptr: { struct Sdeclareitemptr *s=t; fprintf(f,"(*"); ps(f,s->towhat,ind); fprintf(f,")"); return; } case TTdeclareitemarray: { struct Sdeclareitemarray *s=t; int numels=s->numelements; fprintf(f,"("); ps(f,s->ofwhat,ind); if (numels==-1) fprintf(f,"[])"); else fprintf(f,"[%d])",s->numelements); return; } case TTdeclareitemfunction: { struct Sdeclareitemfunction *s=t; ps(f,s->name,ind); fprintf(f,"("); if (s->parameters!=NULL) ps(f,s->parameters,ind); fprintf(f,")"); if (s->body==NULL) return; nlind(f,ind,getlinenumber(s->body)); ps(f,s->body,ind); return; } case TTfixedfuncdef: { struct Sfixedfuncdef *s=t; fprintf(f,"define "); print_identifier(f,s->name); fprintf(f,": "); print_type(f,s->type); if (s->body==NULL) fprintf(f,";"); else { nlind(f,ind,getlinenumber(s->body)); ps(f,s->body,ind); } return; } case TTfixedstructdef: { struct Sfixedstructdef *s=t; fprintf(f,"define "); print_identifier(f,s->name); fprintf(f,"= "); print_type(f,s->type); fprintf(f,";"); return; } case TTdeclareparamlist: { struct Sdeclareparamlist *s=t; while (s->tag==TTdeclareparamlist) { ps(f,s->first,ind); s=s->rest; if (s==NULL) return; fprintf(f,","); } ps(f,s,ind); return; } case TTcoerce: { struct Scoerce *s=t; fprintf(f,"coerce["); ps(f,s->fromtype,ind); fprintf(f,"->"); ps(f,s->totype,ind); fprintf(f,"]("); ps(f,s->operand,ind); fprintf(f,")"); return; } case TTsimple: { struct Tsimple *s=t; print_type_symbol(f,s->type); return; } case TTpointerto: { struct Tpointerto *s=t; fprintf(f,"ptr("); ps(f,s->what,ind); fprintf(f,")"); return; } case TTarrayof: { struct Tarrayof *s=t; int numels=s->numels; if (numels==-1) fprintf(f,"arr[](",s->numels); else fprintf(f,"arr[%d](",s->numels); ps(f,s->what,ind); fprintf(f,")"); return; } case TTfunction: { struct Tfunction *s=t; struct Sdeclareparamlist *p=s->params; fprintf(f,"fn("); if (p==NULL) fprintf(f,"void"); else { while (p!=NULL) { ps(f,p->first,ind); p=p->rest; if (p!=NULL) fprintf(f,", "); } } fprintf(f,"->"); ps(f,s->returns,ind); fprintf(f,")"); return; } case TTstruct: { struct Tstruct *s=t; structlink *p=s->fields; fprintf(f,"struct"); if (s->name!=NULL) { print_identifier(f,s->name); if (p==NULL) return; } fprintf(f,"{"); while (p!=NULL) { ps(f,p->field,ind); p=p->rest; } fprintf(f,"}"); return; } default: fprintf(f,"",g->tag); } } void pt(FILE *f, Syntax *t, int ind) { struct Sgeneric *g=t; int i; for (i=0; i\n"); return; } switch (g->tag) { case TTbad: { fprintf(f,"\n"); return; } case TTnull: { fprintf(f,"constant NULL\n"); return; } case TTidentifier: { struct Sidentifier *s=t; fprintf(f,"identifier: "); print_identifier(f,s->symbol); fputc('\n',f); return; } case TTinteger: { struct Sinteger *s=t; fprintf(f,"integer: %d\n",s->value); return; } case TTfloat: { struct Sfloat *s=t; fprintf(f,"float: %f\n",s->value); return; } case TTstring: { struct Sstring *s=t; fprintf(f,"string: "); print_string(f,s->thestring); fputc('\n',f); return; } case TTbinaryexpr: { struct Sbinaryexpr *s=t; fprintf(f,"binaryexpr: "); print_operator(f,s->operator); fputc('\n',f); pt(f,s->left,ind+1); pt(f,s->right,ind+1); return; } case TTunaryexpr: { struct Sunaryexpr *s=t; fprintf(f,"unaryexpr: "); print_operator(f,s->operator); fputc('\n',f); pt(f,s->operand,ind+1); return; } case TTfunctioncall: { struct Sfunctioncall *s=t; fprintf(f,"functioncall:\n"); pt(f,s->function,ind+1); if(s->arguments!=NULL) pt(f,s->arguments,ind+1); return; } case TTarrayaccess: { struct Sarrayaccess *s=t; fprintf(f,"arrayaccess:\n"); pt(f,s->array,ind+1); pt(f,s->index,ind+1); return; } case TTfieldselect: { struct Sfieldselect *s=t; fprintf(f,"fieldselect: ."); print_identifier(f,s->field); fputc('\n',f); pt(f,s->structure,ind+1); return; } case TTexpressionlist: { struct Sexpressionlist *s=t; fprintf(f,"expressionlist:\n"); while (s->tag==TTexpressionlist) { pt(f,s->first,ind+1); s=s->rest; if (s==NULL) return; } pt(f,s,ind+1); return; } case TTstatementlist: { struct Sstatementlist *s=t; fprintf(f,"statementlist:\n"); while (s->tag==TTstatementlist) { pt(f,s->first,ind+1); s=s->rest; if (s==NULL) return; } pt(f,s,ind+1); return; } case TTblock: { struct Sblock *s=t; fprintf(f,"block:\n"); pt(f,s->declarations,ind+1); pt(f,s->statements,ind+1); return; } case TTexprstatement: { struct Sexprstatement *s=t; fprintf(f,"exprstatement:\n"); pt(f,s->expression,ind+1); return; } case TTifstatement: { struct Sifstatement *s=t; fprintf(f,"ifstatement:\n"); pt(f,s->condition,ind+1); pt(f,s->iftrue,ind+1); pt(f,s->iffalse,ind+1); return; } case TTwhilestatement: { struct Swhilestatement *s=t; fprintf(f,"whilestatement:\n"); pt(f,s->condition,ind+1); pt(f,s->body,ind+1); return; } case TTreturnstatement: { struct Sreturnstatement *s=t; fprintf(f,"returnstatement:\n"); pt(f,s->value,ind+1); return; } case TTfixeddecl: { struct Sfixeddecl *s=t; fprintf(f,"fixeddecl "); print_identifier(f,s->var); fprintf(f,": "); print_type(f,s->type); fputc('\n',f); return; } case TTfixedparam: { struct Sfixeddecl *s=t; fprintf(f,"fixedparam "); print_identifier(f,s->var); fprintf(f,": "); print_type(f,s->type); fputc('\n',f); return; } case TTcoerce: { struct Scoerce *s=t; fprintf(f,"coerce:\n"); pt(f,s->fromtype,ind+1); pt(f,s->totype,ind+1); pt(f,s->operand,ind+1); return; } case TTstructtype: { struct Sstructtype *s=t; fprintf(f,"structtype "); if (s->name==NULL) fprintf(f,""); else print_identifier(f,s->name); fprintf(f,":\n"); pt(f,s->fielddecs,ind+1); return; } case TTsimpletype: { struct Ssimpletype *s=t; fprintf(f,"simpletype: "); print_type_symbol(f,s->type); fputc('\n',f); return; } case TTdeclareitemvar: { struct Sdeclareitemvar *s=t; fprintf(f,"declareitemvar: "); print_identifier(f,s->variable); fputc('\n',f); return; } case TTdeclareitemptr: { struct Sdeclareitemptr *s=t; fprintf(f,"declareitemptr:\n"); pt(f,s->towhat,ind+1); return; } case TTdeclareitemarray: { struct Sdeclareitemarray *s=t; fprintf(f,"declareitemarray: [%d]\n",s->numelements); pt(f,s->ofwhat,ind+1); return; } case TTdeclareitemfunction: { struct Sdeclareitemfunction *s=t; fprintf(f,"declareitemfunction:\n"); pt(f,s->name,ind+1); pt(f,s->parameters,ind+1); pt(f,s->body,ind+1); return; } case TTfixedfuncdef: { struct Sfixedfuncdef *s=t; fprintf(f,"fixedfuncdef "); print_identifier(f,s->name); fprintf(f,": "); print_type(f,s->type); fputc('\n',f); pt(f,s->body,ind+1); return; } case TTfixedstructdef: { struct Sfixedstructdef *s=t; fprintf(f,"fixedstructdef "); if (s->name==NULL) fprintf(f,""); else print_identifier(f,s->name); fprintf(f,": "); print_type(f,s->type); fputc('\n',f); return; } case TTdeclareparamlist: { struct Sdeclareparamlist *s=t; fprintf(f,"declareparamlist:\n"); while (s->tag==TTdeclareparamlist) { pt(f,s->first,ind+1); s=s->rest; if (s==NULL) return; } pt(f,s,ind+1); return; } case TTsimple: { struct Tsimple *s=t; fprintf(f,"simple-type "); print_type_symbol(f,s->type); fputc('\n',f); return; } case TTpointerto: { struct Tpointerto *s=t; fprintf(f,"pointer-to:\n"); pt(f,s->what,ind+1); return; } case TTarrayof: { struct Tarrayof *s=t; int numels=s->numels; if (numels==-1) fprintf(f,"sizeless-array-of:\n"); else fprintf(f,"array-of-%d:\n",s->numels); pt(f,s->what,ind+1); return; } case TTfunction: { struct Tfunction *s=t; if (s->defined) fprintf(f,"function-type:\n"); else fprintf(f,"function-type (not yet defined):\n"); if (s->params==NULL) for (i=0; iparams,ind+1); pt(f,s->returns,ind+1); return; } case TTstruct: { struct Tstruct *s=t; fprintf(f,"struct "); if (s->name!=NULL) print_identifier(f,s->name); else fprintf(f,"(nameless)"); fprintf(f,":\n"); pt(f,s->fields,ind+1); } default: fprintf(f,"\n",g->tag); } } void print_statement(Syntax *t) { nlind(stdout,0,getlinenumber(t)); ps(stdout,t,0); } void print_tagged_tree(FILE *f, Syntax *t) { pt(stdout,t,0); } void print_syntax(FILE *f, Syntax *t) { ps(f,t,0); } Syntax *Pdeclareitemptr(void); Syntax *Ptype(void); Syntax *Pstatement(void); Syntax *Pexpression(void); Syntax *Pblock(void); Syntax *Pdeclareitem(void) { return (Pdeclareitemptr()); } Syntax *Pdeclareparam(void) { struct Sfixedparam *r=malloc(sizeof(struct Sfixedparam)); Syntax *type, *item; Atype *basic; type=Ptype(); item=Pdeclareitem(); r->tag=TTfixedparam; r->linenum=current_line_number(); basic=MakeBasicType(type); ProcessDeclaration(item,basic,&(r->type),&(r->var)); return (r); } Syntax *Pdeclareparamlist(void) { struct Sdeclareparamlist *head=NULL, *tail=NULL; while (lex_kind!=SKclosepar) { struct Sdeclareparamlist *b=malloc(sizeof(struct Sdeclareparamlist)); b->tag=TTdeclareparamlist; b->first=Pdeclareparam(); b->rest=NULL; if (tail==NULL) head=b; else tail->rest=b; tail=b; if (lex_kind!=SKcomma) break; get_lexeme(); } return (head); } Syntax *Pdeclareitemsimple(void) { if (lex_kind==SKopenpar) { Syntax *r; get_lexeme(); r=Pdeclareitem(); if (lex_kind==SKclosepar) get_lexeme(); else syntax_error("error in declaration, ) expected"); return (r); } else if (lex_kind==SKidentifier) { SymbolDescription *name=lex_symbol; struct Sdeclareitemvar *r=malloc(sizeof(struct Sdeclareitemvar)); get_lexeme(); r->tag=TTdeclareitemvar; r->variable=name; return (r); } else { syntax_error("error in declaration"); return (NULL); } } Syntax *Pdeclareitemfunction(void) { Syntax *r=Pdeclareitemsimple(); while (lex_kind==SKopenpar) { struct Sdeclareitemfunction *f=malloc(sizeof(struct Sdeclareitemfunction)); f->tag=TTdeclareitemfunction; f->name=r; get_lexeme(); f->parameters=Pdeclareparamlist(); if (lex_kind!=SKclosepar) syntax_error("error in parameter list, ) expected"); else get_lexeme(); f->body=NULL; r=f; } return (r); } Syntax *Pdeclareitemarray(void) { Syntax *r=Pdeclareitemfunction(); while (lex_kind==SKopensquare) { struct Sdeclareitemarray *s=malloc(sizeof(struct Sdeclareitemarray)); s->tag=TTdeclareitemarray; get_lexeme(); if (lex_kind==SKclosesquare) { s->numelements=-1; } else if (lex_kind==SKinteger) { s->numelements=lex_integer; get_lexeme(); } else { syntax_error("array size must be constant integer"); s->numelements=1; } if (lex_kind==SKclosesquare) get_lexeme(); else syntax_error("error in declaration, ] expected"); s->ofwhat=r; r=s; } return (r); } Syntax *Pdeclareitemptr(void) { struct Sdeclareitemptr *head=NULL, *tail=NULL, *s; while (lex_kind==OPstar) { get_lexeme(); s=malloc(sizeof(struct Sdeclareitemptr)); s->tag=TTdeclareitemptr; s->towhat=NULL; if (head==NULL) head=s; else tail->towhat=s; tail=s; } if (head==NULL) return (Pdeclareitemarray()); tail->towhat=Pdeclareitemarray(); return (head); } Syntax *Pstructtype(void) { struct Sstructtype *r=malloc(sizeof(struct Sstructtype)); struct Sblock *b; r->tag=TTstructtype; if (lex_kind!=TYstruct) syntax_error("struct expected here"); else get_lexeme(); if (lex_kind==SKidentifier) { r->name=lex_symbol; get_lexeme(); } else r->name=NULL; if (lex_kind==SKbegin) { struct Sstatementlist *head=NULL, *last=NULL, *curr; get_lexeme(); while (lex_kind>FirstType && lex_kindrest=curr; while (curr!=NULL) { last=curr; curr=curr->rest; } } if (lex_kind!=SKend) syntax_error("error in last field: END symbol } expected here"); else get_lexeme(); r->fielddecs=head; } else r->fielddecs=NULL; if (r->fielddecs==NULL && r->name==NULL) syntax_error("struct must have either a name or some contents"); return (r); } Syntax *Psimpletype(void) { struct Ssimpletype *r; if (lex_kindLastType) { syntax_error("not a valid type"); return (NULL); } r=malloc(sizeof(struct Ssimpletype)); r->tag=TTsimpletype; r->type=lex_kind; get_lexeme(); return (r); } Syntax *Ptype(void) { if (lex_kind==TYstruct) return (Pstructtype()); else return (Psimpletype()); } Syntax *Pdeclaration(void) { struct Sstatementlist *head=NULL, *last=NULL, *link; Atype *basic; struct Sgeneric *type; type=Ptype(); basic=MakeBasicType(type); if (type->tag==TTstructtype) { struct Sstructtype *s=(struct Sstructtype *)type; if (s->name!=NULL && s->fielddecs!=NULL) { struct Sfixedstructdef *fixedstruct; struct Tstruct *bt=basic; fixedstruct=malloc(sizeof(struct Sfixedstructdef)); fixedstruct->tag=TTfixedstructdef; fixedstruct->linenum=current_line_number(); fixedstruct->name=bt->name; fixedstruct->type=basic; head=malloc(sizeof(struct Sstatementlist)); head->tag=TTstatementlist; head->linenum=current_line_number(); head->first=fixedstruct; head->rest=NULL; last=head; } } while (lex_kind!=SKsemicolon) { struct Sgeneric *item; Syntax *fixeditem; Atype *finaltype; SymbolDescription *thevariable; item=Pdeclareitem(); ProcessDeclaration(item,basic,&finaltype,&thevariable); if (is_function_type(finaltype)) { struct Sfixedfuncdef *decl=malloc(sizeof(struct Sfixedfuncdef)); struct Sdeclareitemfunction *orig=(struct Sdeclareitemfunction *)item; decl->tag=TTfixedfuncdef; decl->linenum=current_line_number(); if (lex_kind==SKbegin) decl->body=Pblock(); else decl->body=NULL; decl->type=finaltype; decl->name=thevariable; fixeditem=decl; } else { struct Sfixeddecl *decl=malloc(sizeof(struct Sfixeddecl)); decl->tag=TTfixeddecl; decl->linenum=current_line_number(); decl->type=finaltype; decl->var=thevariable; fixeditem=decl; } link=malloc(sizeof(struct Sstatementlist)); link->tag=TTstatementlist; link->linenum=current_line_number(); link->first=fixeditem; link->rest=NULL; if (head==NULL) head=link; else last->rest=link; last=link; if (lex_kind!=SKcomma) break; get_lexeme(); } if (lex_kind==SKsemicolon) get_lexeme(); else syntax_error("error in declaration, semicolon expected"); return (head); } Syntax *Pstatementlist(void) { struct Sstatementlist *head=NULL, *end=NULL, *curr; while (lex_kind!=SKend) { curr=malloc(sizeof(struct Sstatementlist)); curr->tag=TTstatementlist; curr->first=Pstatement(); curr->linenum=getlinenumber(curr->first); curr->rest=NULL; if (head==NULL) head=curr; else end->rest=curr; end=curr; } return (head); } Syntax *Pdeclarationlist(void) { struct Sstatementlist *head=NULL, *last=NULL, *curr; while (lex_kind>FirstType && lex_kindrest=curr; while (curr!=NULL) { last=curr; curr=curr->rest; } } return (head); } Syntax *Pblock(void) { struct Sblock *s; if (lex_kind!=SKbegin) syntax_error("BEGIN symbol { required for block"); get_lexeme(); s=malloc(sizeof(struct Sblock)); s->tag=TTblock; s->linenum=current_line_number(); s->declarations=Pdeclarationlist(); s->statements=Pstatementlist(); if (lex_kind!=SKend) syntax_error("error in last statement: END symbol { expected here"); else get_lexeme(); return (s); } Syntax *MakeIntoBlock(Syntax *t) { struct Sgeneric *s=t; struct Sblock *r; if (s!=NULL && s->tag==TTblock) return (s); if (s==NULL || s->tag!=TTstatementlist) { struct Sstatementlist *l=malloc(sizeof(struct Sstatementlist)); l->tag=TTstatementlist; l->linenum=getlinenumber(s); l->first=s; l->rest=NULL; s=(void *)l; } r=malloc(sizeof(struct Sblock)); r->tag=TTblock; r->linenum=getlinenumber(s); r->declarations=NULL; r->statements=s; return (r); } Syntax *Pifstatement(void) { struct Sifstatement *r; if (lex_kind!=RWif) { syntax_error("if expected"); return (NULL); } get_lexeme(); r=malloc(sizeof(struct Sifstatement)); r->tag=TTifstatement; r->linenum=current_line_number(); r->condition=Pexpression(); r->iftrue=MakeIntoBlock(Pstatement()); if (lex_kind==RWelse) { get_lexeme(); r->iffalse=MakeIntoBlock(Pstatement()); } else r->iffalse=NULL; return (r); } Syntax *Pwhilestatement(void) { struct Swhilestatement *r; if (lex_kind!=RWwhile) { syntax_error("while expected"); return (NULL); } get_lexeme(); r=malloc(sizeof(struct Swhilestatement)); r->tag=TTwhilestatement; r->linenum=current_line_number(); r->condition=Pexpression(); r->body=MakeIntoBlock(Pstatement()); return (r); } Syntax *Preturnstatement(void) { struct Sreturnstatement *r; if (lex_kind!=RWreturn) { syntax_error("return expected"); return (NULL); } get_lexeme(); r=malloc(sizeof(struct Sreturnstatement)); r->tag=TTreturnstatement; r->linenum=current_line_number(); if (lex_kind==SKsemicolon) r->value=NULL; else r->value=Pexpression(); if (lex_kind==SKsemicolon) get_lexeme(); else syntax_error("error in return statement, semicolon expected"); return (r); } Syntax *Pstatement(void) { if (lex_kind==SKbegin) return (Pblock()); else if (lex_kind==RWreturn) return (Preturnstatement()); else if (lex_kind==RWif) return (Pifstatement()); else if (lex_kind==RWwhile) return (Pwhilestatement()); else if (lex_kind>FirstType && lex_kindtag=TTexprstatement; e->linenum=current_line_number(); e->expression=Pexpression(); if (lex_kind!=SKsemicolon) syntax_error("error in expression/statement; semicolon was expected"); else get_lexeme(); return (e); } } Syntax *Pexpressionlist(void) { struct Sexpressionlist *head=NULL, *last=NULL; while (lex_kind!=SKclosepar && lex_kind!=SKsemicolon) { struct Sexpressionlist *b=malloc(sizeof(struct Sexpressionlist)); b->tag=TTexpressionlist; b->first=Pexpression(); b->rest=NULL; if (last==NULL) head=b; else last->rest=b; last=b; if (lex_kind!=SKcomma) break; get_lexeme(); } return (head); } Syntax *P18expression(void) { if (lex_kind==SKidentifier) { struct Sidentifier *s=malloc(sizeof(struct Sidentifier)); s->tag=TTidentifier; s->symbol=lex_symbol; get_lexeme(); return (s); } else if (lex_kind==SKnull) { struct Sgeneric *s=malloc(sizeof(struct Sgeneric)); s->tag=TTnull; return (s); } else if (lex_kind==SKstring) { struct Sstring *s=malloc(sizeof(struct Sstring)); s->tag=TTstring; s->thestring=malloc(strlen(lex_name)+1); strcpy(s->thestring,lex_name); get_lexeme(); return (s); } else if (lex_kind==SKinteger) { struct Sinteger *s=malloc(sizeof(struct Sinteger)); s->tag=TTinteger; s->value=lex_integer; get_lexeme(); return (s); } else if (lex_kind==SKfloat) { struct Sfloat *s=malloc(sizeof(struct Sfloat)); s->tag=TTfloat; s->value=lex_float; get_lexeme(); return (s); } else if (lex_kind==SKopenpar) { Syntax *s; get_lexeme(); s=Pexpression(); if (lex_kind!=SKclosepar) syntax_error("error in expression, ) expected here"); else get_lexeme(); return (s); } syntax_error("Improper beginning for an expression or statement"); get_lexeme(); return (NULL); } Syntax *P17expression(void) { Syntax *r; r=P18expression(); while (lex_kind==SKopenpar || lex_kind==OParrow || lex_kind==OPdot || lex_kind==SKopensquare) { SymbolKind op=lex_kind; get_lexeme(); if (op==SKopenpar) { struct Sfunctioncall *b=malloc(sizeof(struct Sfunctioncall)); b->tag=TTfunctioncall; b->function=r; b->arguments=Pexpressionlist(); if (lex_kind==SKclosepar) get_lexeme(); else syntax_error("error in expression list, ) expected"); r=b; } else if (op==SKopensquare) { struct Sarrayaccess *b=malloc(sizeof(struct Sarrayaccess)); b->tag=TTarrayaccess; b->array=r; b->index=Pexpression(); if (lex_kind==SKclosesquare) get_lexeme(); else syntax_error("error in index, ] expected"); r=b; } else if (op==OPdot) { struct Sfieldselect *b=malloc(sizeof(struct Sfieldselect)); b->tag=TTfieldselect; b->structure=r; if (lex_kind!=SKidentifier) syntax_error("Field name required after ."); b->field=lex_symbol; get_lexeme(); r=b; } else if (op==OParrow) { struct Sunaryexpr *c; struct Sfieldselect *b; c=malloc(sizeof(struct Sunaryexpr)); c->tag=TTunaryexpr; c->operator=OPstar; c->operand=r; b=malloc(sizeof(struct Sfieldselect)); b->tag=TTfieldselect; b->structure=c; if (lex_kind!=SKidentifier) syntax_error("Field name required after ->"); b->field=lex_symbol; get_lexeme(); r=b; } } return (r); } Syntax *P15expression(void) { Syntax *r; struct Sunaryexpr *head, *last=NULL; while (lex_kind==OPnot || lex_kind==OPplus || lex_kind==OPminus || lex_kind==OPaddress || lex_kind==OPstar) { struct Sunaryexpr *b=malloc(sizeof(struct Sunaryexpr)); b->tag=TTunaryexpr; b->operator=lex_kind; b->operand=NULL; if (last==NULL) head=b; else last->operand=b; last=b; get_lexeme(); } r=P17expression(); if (last==NULL) return (r); last->operand=r; return (head); } Syntax *P13expression(void) { Syntax *r; r=P15expression(); while (lex_kind==OPstar || lex_kind==OPdivide || lex_kind==OPmod) { SymbolKind op=lex_kind; struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); get_lexeme(); b->tag=TTbinaryexpr; b->left=r; b->operator=op; b->right=P15expression(); r=b; } return (r); } Syntax *P12expression(void) { Syntax *r; r=P13expression(); while (lex_kind==OPplus || lex_kind==OPminus) { SymbolKind op=lex_kind; struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); get_lexeme(); b->tag=TTbinaryexpr; b->left=r; b->operator=op; b->right=P13expression(); r=b; } return (r); } Syntax *P10expression(void) { Syntax *r; r=P12expression(); while (lex_kind==OPless || lex_kind==OPlessequal || lex_kind==OPgreater || lex_kind==OPgreaterequal) { SymbolKind op=lex_kind; struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); get_lexeme(); b->tag=TTbinaryexpr; b->left=r; b->operator=op; b->right=P12expression(); r=b; } return (r); } Syntax *P9expression(void) { Syntax *r; r=P10expression(); while (lex_kind==OPequalequal || lex_kind==OPnotequal) { SymbolKind op=lex_kind; struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); get_lexeme(); b->tag=TTbinaryexpr; b->left=r; b->operator=op; b->right=P10expression(); r=b; } return (r); } Syntax *P5expression(void) { Syntax *r; r=P9expression(); while (lex_kind==OPand) { SymbolKind op=lex_kind; struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); get_lexeme(); b->tag=TTbinaryexpr; b->left=r; b->operator=op; b->right=P9expression(); r=b; } return (r); } Syntax *P4expression(void) { Syntax *r; r=P5expression(); while (lex_kind==OPor) { SymbolKind op=lex_kind; struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); get_lexeme(); b->tag=TTbinaryexpr; b->left=r; b->operator=op; b->right=P5expression(); r=b; } return (r); } Syntax *P2expression(void) { Syntax *lastitem; struct Sbinaryexpr *head=NULL, *last=NULL; lastitem=P4expression(); while (lex_kind==OPequal || lex_kind==OPplusequal || lex_kind==OPminusequal || lex_kind==OPstarequal || lex_kind==OPdivideequal || lex_kind==OPmodequal) { struct Sbinaryexpr *b=malloc(sizeof(struct Sbinaryexpr)); b->tag=TTbinaryexpr; b->left=lastitem; b->operator=lex_kind; get_lexeme(); lastitem=P4expression(); b->right=lastitem; if (last==NULL) head=b; else last->right=b; last=b; } if (last==NULL) return (lastitem); else return (head); } Syntax *Pexpression(void) { return (P2expression()); }