char *rnx_p2str(int p) { char *s=NULL,*s1; int dt,ps,val,nc,p1; switch(RN_P_TYP(p)) { case RN_P_ERROR: s=s_clone("error"); break; case RN_P_NOT_ALLOWED: s=s_clone("notAllowed"); break; case RN_P_EMPTY: s=s_clone("empty"); break; case RN_P_TEXT: s=s_clone("text"); break; case RN_P_CHOICE: s=s_clone("choice (|)"); break; case RN_P_INTERLEAVE: s=s_clone("interleave (&)"); break; case RN_P_GROUP: s=s_clone("group (,)"); break; case RN_P_ONE_OR_MORE: s=s_clone("one or more (+)"); break; case RN_P_LIST: s=s_clone("list"); break; case RN_P_DATA: rn_Data(p,dt,ps); s1=rnx_nc2str(dt); s=(char*)m_alloc(strlen("data ")+1+strlen(s1),sizeof(char)); strcpy(s,"data "); strcat(s,s1); m_free(s1); break; case RN_P_DATA_EXCEPT: s=s_clone("dataExcept (-)"); break; case RN_P_VALUE: rn_Value(p,dt,val); s1=rnx_nc2str(dt); s=(char*)m_alloc(strlen("value \"\" ")+1+strlen(s1)+strlen(rn_string+val),sizeof(char)); strcpy(s,"value "); strcat(s,s1); strcat(s," \""); strcat(s,rn_string+val); strcat(s,"\""); m_free(s1); break; case RN_P_ATTRIBUTE: rn_Attribute(p,nc,p1); s1=rnx_nc2str(nc); s=(char*)m_alloc(strlen("attribute ")+1+strlen(s1),sizeof(char)); strcpy(s,"attribute "); strcat(s,s1); m_free(s1); break; case RN_P_ELEMENT: rn_Element(p,nc,p1); s1=rnx_nc2str(nc); s=(char*)m_alloc(strlen("element ")+1+strlen(s1),sizeof(char)); strcpy(s,"element "); strcat(s,s1); m_free(s1); break; case RN_P_REF: s=s_clone("ref"); break; case RN_P_AFTER: s=s_clone("after"); break; default: assert(0); } return s; }
static int isanymix(int p) { int p0,nc,p1,p2,i,res,flat[2]; p0=p; if(!RN_P_IS(p0,RN_P_ONE_OR_MORE)) return 0; rn_OneOrMore(p0,p1); p0=p1; if(!RN_P_IS(p0,RN_P_CHOICE)) return 0; rn_Choice(p0,p1,p2); flat[0]=p1; flat[1]=p2; res=0; for(i=0;i!=2;++i) { p0=flat[i]; switch(RN_P_TYP(p0)) { case RN_P_ELEMENT: rn_Element(p0,nc,p1); if(!(RN_NC_IS(nc,RN_NC_ANY_NAME)&& isanycont(p1))) return 0; res|=1; break; case RN_P_TEXT: break; default: return 0; } } return res==1; }
static void expected(int p,int first,int req) { int p1,p2,px=0,i; if(req && rn_nullable(p)) return; switch(RN_P_TYP(p)) { case RN_P_ERROR: break; case RN_P_NOT_ALLOWED: break; case RN_P_EMPTY: break; case RN_P_TEXT: px=p; break; case RN_P_CHOICE: rn_Choice(p,p1,p2); expected(p1,first,req); expected(p2,first,req); break; case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); expected(p1,first,req); expected(p2,first,req); break; case RN_P_GROUP: rn_Group(p,p1,p2); expected(p1,first,req); expected(p2,first&&rn_nullable(p1),req); break; case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); expected(p1,first,req); break; case RN_P_LIST: rn_List(p,p1); expected(p1,first,req); break; case RN_P_DATA: px=p; break; case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); expected(p1,first,req); break; case RN_P_VALUE: px=p; break; case RN_P_ATTRIBUTE: px=p; break; case RN_P_ELEMENT: px=p; break; case RN_P_AFTER: rn_After(p,p1,p2); expected(p1,first,req); if(rn_nullable(p1)) px=p; break; case RN_P_REF: break; default: assert(0); } if(px&&(first||RN_P_IS(px,RN_P_ATTRIBUTE))) { for(i=0;i!=rnx_n_exp;++i) { if(rnx_exp[i]==px) {px=0; break;} } if(px) { if(rnx_n_exp==len_exp) rnx_exp=(int*)m_stretch(rnx_exp,len_exp=2*rnx_n_exp,rnx_n_exp,sizeof(int)); rnx_exp[rnx_n_exp++]=px; } } }