nsFrameUtil::Tag* nsFrameUtil::Tag::Parse(FILE* aFile) { if (!EatWS(aFile)) { return nsnull; } if (Expect(aFile, '<')) { Tag* tag = new Tag; if (Expect(aFile, '/')) { tag->type = close; } else { tag->type = open; } tag->name = ReadIdent(aFile); tag->ReadAttrs(aFile); return tag; } return nsnull; }
void nsFrameUtil::Tag::ReadAttrs(FILE* aFile) { for (;;) { if (!EatWS(aFile)) { break; } int c = getc(aFile); if (c < 0) break; if (c == '/') { if (!EatWS(aFile)) { return; } if (Expect(aFile, '>')) { type = openClose; break; } } else if (c == '>') { break; } ungetc(c, aFile); char* attr = ReadIdent(aFile); if ((nsnull == attr) || !EatWS(aFile)) { break; } char* value = nsnull; if (Expect(aFile, '=')) { value = ReadString(aFile); if (nsnull == value) { delete [] attr; break; } } AddAttr(attr, value); } }
void NextRawTok (void) /* Read the next raw token from the input stream */ { Macro* M; /* If we've a forced end of assembly, don't read further */ if (ForcedEnd) { CurTok.Tok = TOK_EOF; return; } Restart: /* Check if we have tokens from another input source */ if (InputFromStack ()) { if (CurTok.Tok == TOK_IDENT && (M = FindDefine (&CurTok.SVal)) != 0) { /* This is a define style macro - expand it */ MacExpandStart (M); goto Restart; } return; } Again: /* Skip whitespace, remember if we had some */ if ((CurTok.WS = IsBlank (C)) != 0) { do { NextChar (); } while (IsBlank (C)); } /* Mark the file position of the next token */ Source->Func->MarkStart (Source); /* Clear the string attribute */ SB_Clear (&CurTok.SVal); /* Generate line info for the current token */ NewAsmLine (); /* Hex number or PC symbol? */ if (C == '$') { NextChar (); /* Hex digit must follow or DollarIsPC must be enabled */ if (!IsXDigit (C)) { if (DollarIsPC) { CurTok.Tok = TOK_PC; return; } else { Error ("Hexadecimal digit expected"); } } /* Read the number */ CurTok.IVal = 0; while (1) { if (UnderlineInNumbers && C == '_') { while (C == '_') { NextChar (); } if (!IsXDigit (C)) { Error ("Number may not end with underline"); } } if (IsXDigit (C)) { if (CurTok.IVal & 0xF0000000) { Error ("Overflow in hexadecimal number"); CurTok.IVal = 0; } CurTok.IVal = (CurTok.IVal << 4) + DigitVal (C); NextChar (); } else { break; } } /* This is an integer constant */ CurTok.Tok = TOK_INTCON; return; } /* Binary number? */ if (C == '%') { NextChar (); /* 0 or 1 must follow */ if (!IsBDigit (C)) { Error ("Binary digit expected"); } /* Read the number */ CurTok.IVal = 0; while (1) { if (UnderlineInNumbers && C == '_') { while (C == '_') { NextChar (); } if (!IsBDigit (C)) { Error ("Number may not end with underline"); } } if (IsBDigit (C)) { if (CurTok.IVal & 0x80000000) { Error ("Overflow in binary number"); CurTok.IVal = 0; } CurTok.IVal = (CurTok.IVal << 1) + DigitVal (C); NextChar (); } else { break; } } /* This is an integer constant */ CurTok.Tok = TOK_INTCON; return; } /* Number? */ if (IsDigit (C)) { char Buf[16]; unsigned Digits; unsigned Base; unsigned I; long Max; unsigned DVal; /* Ignore leading zeros */ while (C == '0') { NextChar (); } /* Read the number into Buf counting the digits */ Digits = 0; while (1) { if (UnderlineInNumbers && C == '_') { while (C == '_') { NextChar (); } if (!IsXDigit (C)) { Error ("Number may not end with underline"); } } if (IsXDigit (C)) { /* Buf is big enough to allow any decimal and hex number to ** overflow, so ignore excess digits here, they will be detected ** when we convert the value. */ if (Digits < sizeof (Buf)) { Buf[Digits++] = C; } NextChar (); } else { break; } } /* Allow zilog/intel style hex numbers with a 'h' suffix */ if (C == 'h' || C == 'H') { NextChar (); Base = 16; Max = 0xFFFFFFFFUL / 16; } else { Base = 10; Max = 0xFFFFFFFFUL / 10; } /* Convert the number using the given base */ CurTok.IVal = 0; for (I = 0; I < Digits; ++I) { if (CurTok.IVal > Max) { Error ("Number out of range"); CurTok.IVal = 0; break; } DVal = DigitVal (Buf[I]); if (DVal >= Base) { Error ("Invalid digits in number"); CurTok.IVal = 0; break; } CurTok.IVal = (CurTok.IVal * Base) + DVal; } /* This is an integer constant */ CurTok.Tok = TOK_INTCON; return; } /* Control command? */ if (C == '.') { /* Remember and skip the dot */ NextChar (); /* Check if it's just a dot */ if (!IsIdStart (C)) { /* Just a dot */ CurTok.Tok = TOK_DOT; } else { /* Read the remainder of the identifier */ SB_AppendChar (&CurTok.SVal, '.'); ReadIdent (); /* Dot keyword, search for it */ CurTok.Tok = FindDotKeyword (); if (CurTok.Tok == TOK_NONE) { /* Not found */ if (!LeadingDotInIdents) { /* Invalid pseudo instruction */ Error ("'%m%p' is not a recognized control command", &CurTok.SVal); goto Again; } /* An identifier with a dot. Check if it's a define style ** macro. */ if ((M = FindDefine (&CurTok.SVal)) != 0) { /* This is a define style macro - expand it */ MacExpandStart (M); goto Restart; } /* Just an identifier with a dot */ CurTok.Tok = TOK_IDENT; } } return; } /* Indirect op for sweet16 cpu. Must check this before checking for local ** symbols, because these may also use the '@' symbol. */ if (CPU == CPU_SWEET16 && C == '@') { NextChar (); CurTok.Tok = TOK_AT; return; } /* Local symbol? */ if (C == LocalStart) { /* Read the identifier. */ ReadIdent (); /* Start character alone is not enough */ if (SB_GetLen (&CurTok.SVal) == 1) { Error ("Invalid cheap local symbol"); goto Again; } /* A local identifier */ CurTok.Tok = TOK_LOCAL_IDENT; return; } /* Identifier or keyword? */ if (IsIdStart (C)) { /* Read the identifier */ ReadIdent (); /* Check for special names. Bail out if we have identified the type of ** the token. Go on if the token is an identifier. */ switch (SB_GetLen (&CurTok.SVal)) { case 1: switch (toupper (SB_AtUnchecked (&CurTok.SVal, 0))) { case 'A': if (C == ':') { NextChar (); CurTok.Tok = TOK_OVERRIDE_ABS; } else { CurTok.Tok = TOK_A; } return; case 'F': if (C == ':') { NextChar (); CurTok.Tok = TOK_OVERRIDE_FAR; return; } break; case 'S': if ((CPU == CPU_4510) || (CPU == CPU_65816)) { CurTok.Tok = TOK_S; return; } break; case 'X': CurTok.Tok = TOK_X; return; case 'Y': CurTok.Tok = TOK_Y; return; case 'Z': if (C == ':') { NextChar (); CurTok.Tok = TOK_OVERRIDE_ZP; return; } else { if (CPU == CPU_4510) { CurTok.Tok = TOK_Z; return; } } break; default: break; } break; case 2: if ((CPU == CPU_4510) && (toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') && (toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) { CurTok.Tok = TOK_S; return; } /* FALL THROUGH */ default: if (CPU == CPU_SWEET16 && (CurTok.IVal = Sweet16Reg (&CurTok.SVal)) >= 0) { /* A sweet16 register number in sweet16 mode */ CurTok.Tok = TOK_REG; return; } } /* Check for define style macro */ if ((M = FindDefine (&CurTok.SVal)) != 0) { /* Macro - expand it */ MacExpandStart (M); goto Restart; } else { /* An identifier */ CurTok.Tok = TOK_IDENT; } return; } /* Ok, let's do the switch */ CharAgain: switch (C) { case '+': NextChar (); CurTok.Tok = TOK_PLUS; return; case '-': NextChar (); CurTok.Tok = TOK_MINUS; return; case '/': NextChar (); if (C != '*') { CurTok.Tok = TOK_DIV; } else if (CComments) { /* Remember the position, then skip the '*' */ Collection LineInfos = STATIC_COLLECTION_INITIALIZER; GetFullLineInfo (&LineInfos); NextChar (); do { while (C != '*') { if (C == EOF) { LIError (&LineInfos, "Unterminated comment"); ReleaseFullLineInfo (&LineInfos); DoneCollection (&LineInfos); goto CharAgain; } NextChar (); } NextChar (); } while (C != '/'); NextChar (); ReleaseFullLineInfo (&LineInfos); DoneCollection (&LineInfos); goto Again; } return; case '*': NextChar (); CurTok.Tok = TOK_MUL; return; case '^': NextChar (); CurTok.Tok = TOK_XOR; return; case '&': NextChar (); if (C == '&') { NextChar (); CurTok.Tok = TOK_BOOLAND; } else { CurTok.Tok = TOK_AND; } return; case '|': NextChar (); if (C == '|') { NextChar (); CurTok.Tok = TOK_BOOLOR; } else { CurTok.Tok = TOK_OR; } return; case ':': NextChar (); switch (C) { case ':': NextChar (); CurTok.Tok = TOK_NAMESPACE; break; case '-': CurTok.IVal = 0; do { --CurTok.IVal; NextChar (); } while (C == '-'); CurTok.Tok = TOK_ULABEL; break; case '+': CurTok.IVal = 0; do { ++CurTok.IVal; NextChar (); } while (C == '+'); CurTok.Tok = TOK_ULABEL; break; case '=': NextChar (); CurTok.Tok = TOK_ASSIGN; break; default: CurTok.Tok = TOK_COLON; break; } return; case ',': NextChar (); CurTok.Tok = TOK_COMMA; return; case ';': NextChar (); while (C != '\n' && C != EOF) { NextChar (); } goto CharAgain; case '#': NextChar (); CurTok.Tok = TOK_HASH; return; case '(': NextChar (); CurTok.Tok = TOK_LPAREN; return; case ')': NextChar (); CurTok.Tok = TOK_RPAREN; return; case '[': NextChar (); CurTok.Tok = TOK_LBRACK; return; case ']': NextChar (); CurTok.Tok = TOK_RBRACK; return; case '{': NextChar (); CurTok.Tok = TOK_LCURLY; return; case '}': NextChar (); CurTok.Tok = TOK_RCURLY; return; case '<': NextChar (); if (C == '=') { NextChar (); CurTok.Tok = TOK_LE; } else if (C == '<') { NextChar (); CurTok.Tok = TOK_SHL; } else if (C == '>') { NextChar (); CurTok.Tok = TOK_NE; } else { CurTok.Tok = TOK_LT; } return; case '=': NextChar (); CurTok.Tok = TOK_EQ; return; case '!': NextChar (); CurTok.Tok = TOK_BOOLNOT; return; case '>': NextChar (); if (C == '=') { NextChar (); CurTok.Tok = TOK_GE; } else if (C == '>') { NextChar (); CurTok.Tok = TOK_SHR; } else { CurTok.Tok = TOK_GT; } return; case '~': NextChar (); CurTok.Tok = TOK_NOT; return; case '\'': /* Hack: If we allow ' as terminating character for strings, read ** the following stuff as a string, and check for a one character ** string later. */ if (LooseStringTerm) { ReadStringConst ('\''); if (SB_GetLen (&CurTok.SVal) == 1) { CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0); CurTok.Tok = TOK_CHARCON; } else { CurTok.Tok = TOK_STRCON; } } else { /* Always a character constant */ NextChar (); if (C == EOF || IsControl (C)) { Error ("Illegal character constant"); goto CharAgain; } CurTok.IVal = C; CurTok.Tok = TOK_CHARCON; NextChar (); if (C != '\'') { if (!MissingCharTerm) { Error ("Illegal character constant"); } } else { NextChar (); } } return; case '\"': ReadStringConst ('\"'); CurTok.Tok = TOK_STRCON; return; case '\\': /* Line continuation? */ if (LineCont) { NextChar (); /* Next char should be a LF, if not, will result in an error later */ if (C == '\n') { /* Ignore the '\n' */ NextChar (); goto Again; } else { /* Make it clear what the problem is: */ Error ("EOL expected."); } } break; case '\n': NextChar (); CurTok.Tok = TOK_SEP; return; case EOF: CheckInputStack (); /* In case of the main file, do not close it, but return EOF. */ if (Source && Source->Next) { DoneCharSource (); goto Again; } else { CurTok.Tok = TOK_EOF; } return; } /* If we go here, we could not identify the current character. Skip it ** and try again. */ Error ("Invalid input character: 0x%02X", C & 0xFF); NextChar (); goto Again; }
void CPRApplication::BuildTree(char* workpath, ag::list<CPRTokenInfo>* pTok,char* sftext,ag::tree<CPRTreeNode*>*parent) { if (debugmode) std::cout<<"CPRApplication::BuildTree()\n"; int state=0; ag::tree<CPRTreeNode*>* mainparent=this->aTree; ag::tree<CPRTreeNode*>* funcparent=FindText1InTree(aTree,"FUNCTIONS"); if (funcparent==NULL) funcparent=this->aTree->addchild(MakeCPRTreeNode(tntNone,"FUNCTIONS")); ag::tree<CPRTreeNode*>* currparent=(parent)?parent:funcparent; ag::tree<CPRTreeNode*>* tp; ag::list<CPRTextDataType>::member lm; CPRTreeNode *n; CPRTextDataType *dt=new CPRTextDataType; int k=0; char *str1,*str2,*str3,*str4; int* q; int iSz; int iSz2; bool outside=false; ag::list<CPRTokenInfo>*pTokens; CPROutsideHeader* coh; if (pTok!=NULL) pTokens=pTok; else pTokens=&aTokens; bool newnode; ag::tree<CPRTreeNode*>* pfc; int iCommandsIndexOut=-1; for(ag::list<CPRTokenInfo>::member p=pTokens->head;(p!=NULL)&&(p->data.petCurrType!=petEOF);p=p->next) { switch (state) { case 0://new expression if (debugmode) aTree->drawtree_con(&std::cout);// DELETE if (debugmode) std::cout<<"(s0) start: "<<p->data.sCurrText<<", "<<p->data.petCurrType<<"\n"; if (p->data.sCurrText[0]==';'){} else if ((p->data.sCurrText[0]=='}')||(iCommandsIndexOut==0)) { bool bCmdIndexOut=(iCommandsIndexOut==0); iCommandsIndexOut=-1; if (currparent->data->tntType==tntIFTrue) { if (!bCmdIndexOut) p=p->next; if (strcmp(p->data.sCurrText,"else")==0) { currparent=currparent->parent; for(ag::list<ag::tree<CPRTreeNode*>*>::member i=currparent->childs.head;i!=NULL;i=i->next) { if (i->data->data->tntType==tntIFFalse) { currparent=i->data; break; } } p=p->next; if (p->data.sCurrText[0]!='{') { iCommandsIndexOut=2; p=p->prev; } }else { currparent=currparent->parent->parent; p=p->prev; } }else { if (currparent->data->tntType==tntForLoop) { ag::list<CPRTokenInfo>* aTo=new ag::list<CPRTokenInfo>; std::string rs1=currparent->data->text3; rs1+=';'; ParseIt(aTo,(char*)rs1.c_str()); for(ag::list<CPRTokenInfo>::member pa=aTo->head;pa!=NULL;pa=pa->next) if (debugmode) std::cout << pa->data.sCurrText << ": " << pa->data.petCurrType << "; "; if (debugmode) std::cout<<"\n"; BuildTree(workpath,aTo,(char*)rs1.c_str(),currparent); if (bCmdIndexOut) p=p->prev; currparent=currparent->parent; }else if (currparent->data->tntType==tntDoWhileLoop) { if (p->data.sCurrText[0]=='}') p=p->next; if (strcmp(p->data.sCurrText,"while")!=0) throw "There is no \"while\" in Do-While loop"; p=p->next; str1=ReadToSymbol(p,';',false); currparent->data->r1=MakePostfixFromInfix(str1); currparent=currparent->parent; }else if (currparent->data->tntType==tntIFFalse) { currparent=currparent->parent->parent; if (bCmdIndexOut) p=p->prev; }else { if (bCmdIndexOut) p=p->prev; currparent=currparent->parent; if (debugmode) std::cout<<"(s0): level up\n"; } } }else if (strcmp(p->data.sCurrText,"if")==0) { p=p->next; int brackets=0; std::string ex; do { ex+=p->data.sCurrText; brackets=(p->data.sCurrText[0]=='(')?brackets+1:brackets; brackets=(p->data.sCurrText[0]==')')?brackets-1:brackets; p=p->next; }while ((brackets>0)&&(p->data.petCurrType!=petEOF)); str4=new char[ex.size()+1]; strcpy(str4,ex.c_str()); str4[ex.size()]=0; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntIF,str4)); tp->data->r1=MakePostfixFromInfix(str4); currparent=tp; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntIFFalse,"False branch")); tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntIFTrue,"True branch")); currparent=tp; if (debugmode) std::cout<<"(s0) IF "<<ex<<", TRUE level created && FALSE level created && TRUE level down\n"; if (p->data.sCurrText[0]!='{') { iCommandsIndexOut=2; p=p->prev; } }else if (strcmp(p->data.sCurrText,"while")==0) { p=p->next; int brackets=0; std::string ex; do { ex+=p->data.sCurrText; brackets=(p->data.sCurrText[0]=='(')?brackets+1:brackets; brackets=(p->data.sCurrText[0]==')')?brackets-1:brackets; p=p->next; }while ((brackets>0)&&(p->data.petCurrType!=petEOF)); str4=new char[ex.size()+1]; strcpy(str4,ex.c_str()); str4[ex.size()]=0; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntWhileLoop,str4)); tp->data->r1=MakePostfixFromInfix(str4); currparent=tp; if (p->data.sCurrText[0]!='{') { iCommandsIndexOut=2; p=p->prev; } }else if (strcmp(p->data.sCurrText,"for")==0) { p=p->next; if (p->data.sCurrText[0]!='(') throw "'(' expected"; p=p->next; str1=ReadToSymbol(p,';',true); p=p->next; str2=ReadToSymbol(p,';',false); p=p->next; str3=ReadToSymbol(p,')',false); ag::list<CPRTokenInfo>* aTo=new ag::list<CPRTokenInfo>; std::string rs1=str1; rs1+=';'; ParseIt(aTo,(char*)rs1.c_str()); for(ag::list<CPRTokenInfo>::member pa=aTo->head;pa!=NULL;pa=pa->next) if (debugmode) std::cout << pa->data.sCurrText << ": " << pa->data.petCurrType << "; "; if (debugmode) std::cout<<"\n"; BuildTree(workpath,aTo,(char*)rs1.c_str(),currparent); tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntForLoop,str1,str2,str3)); tp->data->r2=MakePostfixFromInfix(str2); tp->data->r3=MakePostfixFromInfix(str3); currparent=tp; p=p->next; if (p->data.sCurrText[0]!='{') { iCommandsIndexOut=2; p=p->prev; } }else if (strcmp(p->data.sCurrText,"do")==0) { p=p->next; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntDoWhileLoop)); currparent=tp; if (p->data.sCurrText[0]!='{') { iCommandsIndexOut=2; p=p->prev; } }else if (strcmp(p->data.sCurrText,"pragma")==0) { str1=ReadToEOLN(&p, sftext); if (debugmode) std::cout<<"(s0): directive: "<<str1<<"\n"; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntDirective,str1)); }else if (strcmp(p->data.sCurrText,"outside")==0) { outside=true; coh=new CPROutsideHeader; p=p->next; char* x=ReadIdent(&p,sftext); while ((p!=NULL)&&(x[0]!=':')) { if(strcmp(x,"cdecl")==0) { coh->cc=occCDecl; } p=p->next; x=ReadIdent(&p,sftext); } p=p->next; }else /*if (p->data.sCurrText[0]=='@') { p=p->next; str1=ReadIdent(&p); tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntVarOutput,str1)); }*/ if (p->data.sCurrText[0]=='{') { tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntNone)); currparent=tp; if (debugmode) std::cout<<"(s0): new level created && level down\n"; }else if (IsTypename(p)) // it is typename { str1=ReadTypename(p); state=1; if (debugmode) std::cout<<"(s0): '"<<str1<<"' typename detected\n"; }else if (strcmp(p->data.sCurrText,"return")==0) { p=p->next; str1=ReadToSymbol(p,';',false); if (debugmode) std::cout<<"(s0): '"<<str1<<"' return expression\n"; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntReturn,str1)); tp->data->r1=MakePostfixFromInfix(str1); }else { str1=ReadToSymbol(p,';',false); if (debugmode) std::cout<<"(s0): '"<<str1<<"' expression\n"; tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntExpression,str1)); tp->data->r1=MakePostfixFromInfix(str1); }; if (iCommandsIndexOut>-1) iCommandsIndexOut--; break; case 1://<typename>_ if (debugmode) std::cout<<"(s1) start\n"; str2=ReadIdent(&p, sftext); state=2; if (debugmode) std::cout<<"(s1): '"<<str2<<"' ident for typename '"<<str1<<"'\n"; break; case 2://<typename>_<ident>_ if (debugmode) std::cout<<"(s2) start\n"; if (strcmp(p->data.sCurrText,"(")==0) { // function if (debugmode) std::cout<<"(s2): '"<<str1<<" "<<str2<<"()' is function\n"; state=4; }else { // variable if (debugmode) std::cout<<"(s2): '"<<str1<<" "<<str2<<"' is variable\n"; p=p->prev; state=3; } break; case 3://<typename>_<ident>=, <typename>_<ident>; if (debugmode) std::cout<<"(s3) start\n"; if (strcmp(p->data.sCurrText,"=")==0) { p=p->next; str3=ReadToSymbol(p,';',false); if (debugmode) std::cout<<"(s3): init '"<<str2<<"' variable with '"<<str3<<"'\n"; // CPRTreeNode* C=MakeCPRTreeNode(tntDeclareVar,NULL,NULL,NULL); // tp=new ag::tree<CPRTreeNode*>(currparent,C); // FillCPRTreeNode(C,tntDeclareVar,str1,str2,str3); CPRTreeNode* C=MakeCPRTreeNode(tntDeclareVar,str1,str2,str3); tp=new ag::tree<CPRTreeNode*>(currparent,C); }else tp=new ag::tree<CPRTreeNode*>(currparent,MakeCPRTreeNode(tntDeclareVar,str1,str2,NULL)); state=0; break; case 4://<typename>_<ident>( if (debugmode) std::cout<<"(s4) start\n"; if (debugmode) aTree->drawtree_con(&std::cout); pfc=FindText2InTree(currparent,str2); newnode=(pfc==NULL); if (!newnode) { // n=pfc->data; // n->tntType=tntFunction; currparent->delchild(pfc); } if (debugmode) aTree->drawtree_con(&std::cout); n=MakeCPRTreeNode(tntFunction,str1,str2); n->r1=new ag::list<CPRTextDataType>; while ((strcmp(p->data.sCurrText,")")!=0)&&(p!=NULL)) { if (!IsTypename(p)) { if ((strcmp(p->data.sCurrText,".")==0)&&(strcmp(p->next->data.sCurrText,".")==0)&&(strcmp(p->next->next->data.sCurrText,".")==0)) { lm=((ag::list<CPRTextDataType>*)(n->r1))->add_tail(*dt); lm->data.str1="..."; lm->data.str2="..."; lm->data.str3=NULL; p=p->next->next->next; continue; } else { if (debugmode) std::cout<<"(s4) ERROR "<<p->data.sCurrText<<" is not typename\n"; state=0; break; } } lm=((ag::list<CPRTextDataType>*)(n->r1))->add_tail(*dt); str1=ReadTypename(p); lm->data.str1=str1; p=p->next; str2=ReadIdent(&p, sftext); lm->data.str2=str2; p=p->next; k=0; k+=(strcmp(p->data.sCurrText,"[")==0)?1:0; k+=(strcmp(p->data.sCurrText,"]")==0)?-1:0; //p=p->next; if (k>0) { str3=new char[1]; str3[0]=0; }else str3=NULL; if(k==1)strcat(str3,"["); if(k==-1)strcat(str3,"]"); if (k>0) p=p->next; while ((k>0)&&(p!=NULL)) { k+=(strcmp(p->data.sCurrText,"[")==0)?1:0; if(strcmp(p->data.sCurrText,"[")==0)strcat(str3,"["); k+=(strcmp(p->data.sCurrText,"]")==0)?-1:0; if(strcmp(p->data.sCurrText,"]")==0)strcat(str3,"]"); if(k>0) strcat(str3,p->data.sCurrText); p=p->next; }; lm->data.str3=str3; if (strcmp(p->data.sCurrText,",")==0) p=p->next; //if (debugmode) std::cout<<"(s4): function parameter '"<<str1<<" "<<str2<<"'\n"; } for(ag::list<CPRTextDataType>::member I=(*((ag::list<CPRTextDataType>*)(n->r1))).head;I!=NULL;I=I->next) { if (debugmode) std::cout<<"(s4): function parameter '"<<I->data.str1<<" "<<I->data.str2; if(I->data.str3!=NULL)if (debugmode) std::cout<<" "<<I->data.str3; if (debugmode) std::cout<<"'\n"; } p=p->next; if (strcmp(p->data.sCurrText,"{")==0) { tp=new ag::tree<CPRTreeNode*>(currparent,n); if (debugmode) aTree->drawtree_con(&std::cout); if (debugmode) std::cout<<"(s4): function start: new level. level down..\n"; currparent=tp; } if (strcmp(p->data.sCurrText,";")==0) { if (outside) { outside=false; n->tntType=tntOutside; n->r2=coh; tp=new ag::tree<CPRTreeNode*>(currparent,n); if (debugmode) aTree->drawtree_con(&std::cout); } else { ((ag::list<CPRTextDataType>*)(n->r1))->delall(); ag::list<CPRTextDataType>::member kx; for(ag::list<CPRTextDataType>::member I=(*((ag::list<CPRTextDataType>*)(n->r1))).tail;I!=NULL;) { kx=I->prev; delete I; I=kx; } delete n->r1; delete n; delete tp; } if (debugmode) std::cout<<"(s4): it was forward declaration of function\n"; } state=0; break; case 5: break; } //if (debugmode) std::cout << p->data.sCurrText << ": " << p->data.petCurrType << "; "; } }
void CPRApplication::PreprocessDefineConsts(char** saveto, char* fText, char* workdir) { // обработка дефайн-констант char* sText=new char[strlen(fText)+1]; strcpy(sText,fText); sText[strlen(fText)]=0; ag::list<CPRTokenInfo>* pTok=new ag::list<CPRTokenInfo>; ParseIt(pTok,sText,true,true); ag::list<StartEndStruct> StartEndList; ag::list<StartEndStruct> ToErase; StartEndStruct ses; CPRDefine dfn; ag::list<CPRTokenInfo>* Tk=new ag::list<CPRTokenInfo>; //ag::list<CPRDefine> sDefinesL; int iSt; for(ag::list<CPRTokenInfo>::member p=pTok->head;(p!=NULL);p=p->next) { if (p->data.petCurrType==petEOF) break; if (p->data.sCurrText[0]=='#') { iSt=p->data.iStartPos; do p=p->next; while (p->data.sCurrText[0]==' '); if (strcmp(p->data.sCurrText,"pragma")==0) { sText[iSt]=' '; ReadToEOLN(&p,sText); } if (strcmp(p->data.sCurrText,"define")==0) { do p=p->next; while (p->data.sCurrText[0]==' '); char* ident; ident=ReadIdent(&p,sText); if (p->data.sCurrText[0]=='(') dfn.dt=cdtMacro; else dfn.dt=cdtConst; if (dfn.dt==cdtConst) { dfn.params=NULL; dfn.name=ident; while (p->data.sCurrText[0]==' ') p=p->next; if (p->data.sCurrText[0]!='\n') { dfn.expr=ReadToEOLN(&p,sText); }else dfn.expr=NULL; } if (dfn.dt==cdtMacro) { // } bool replace=false; for(ag::list<CPRDefine>::member m=sDefines.head;m!=NULL;m=m->next) { if(strcmp(m->data.name,ident)==0) { m->data.dt=dfn.dt; m->data.params=dfn.params; m->data.expr=dfn.expr; replace=true; break; } } if (!replace) sDefines.add_tail(dfn); } if (strcmp(p->data.sCurrText,"undef")==0) { do p=p->next; while (p->data.sCurrText[0]==' '); std::string ident; while(sIdentSymbs%p->data.sCurrText[0]) { ident+=p->data.sCurrText; p=p->next; } for(ag::list<CPRDefine>::member m=sDefines.head;m!=NULL;m=m->next) { if(strcmp(m->data.name,ident.c_str())==0) { sDefines.del(m); break; } } } } ag::list<CPRTokenInfo>::member Tkm; ag::list<CPRDefine>::member b; //if (debugmode) std::cout<<">>"; /*for(ag::list<CPRDefine>::member kms=sDefines.head;kms!=NULL;kms=kms->next) if (debugmode) std::cout<<kms->data.name<<"\n"; */ for(ag::list<CPRDefine>::member m=sDefines.head;m!=NULL;m=m->next) { Tk->delall(); ParseIt(Tk,m->data.name,true,true); Tkm=Tk->head; ses.start=p->data.iStartPos; while((strcmp(Tkm->data.sCurrText,p->data.sCurrText)==0)) { Tkm=Tkm->next; p=p->next; if (Tkm==NULL) { //Нашли! ses.end=p->prev->data.iFinishPos; char* j=new char[strlen(m->data.expr)+1]; strcpy(j,m->data.expr); j[strlen(m->data.expr)]=0; ses.data=j; if (ses.data!=NULL) StartEndList.add_tail(ses); break; } } } } char* k; std::string res; int last=0; for(ag::list<StartEndStruct>::member p=StartEndList.head;(p!=NULL);p=p->next) { k=new char[p->data.start+1]; strncpy(k,sText+last,p->data.start-last); // if (debugmode) std::cout<<": "<<k<<"\n"; k[(p->data.start)-last]=0; res+=k; delete[] k; if (p->data.data!=NULL) res+=(char*)(p->data.data); last=p->data.end; } k=new char[strlen(sText)-last+1]; strncpy(k,sText+last,strlen(sText)-last); // if (debugmode) std::cout<<p->data.start<<' '<<p->data.end<<": "<<k; k[strlen(sText)-last]=0; res+=k; // delete[] k; k=new char[res.size()+1]; strcpy(k,res.c_str()); k[res.size()]=0; pTok->delall(); ToErase.delall(); ParseIt(pTok,k,true,true); for(ag::list<CPRTokenInfo>::member p=pTok->head;(p!=NULL)&&(p->data.petCurrType!=petEOF);p=p->next) { if (p->data.sCurrText[0]=='#') { iSt=p->data.iStartPos; do p=p->next; while (p->data.sCurrText[0]==' '); if (strcmp(p->data.sCurrText,"define")==0) { ReadToEOLN(&p,k); ses.start=iSt; ses.end=p->data.iFinishPos; ses.data=NULL; ToErase.add_tail(ses); } if (strcmp(p->data.sCurrText,"undef")==0) { ReadToEOLN(&p,k); ses.start=iSt; ses.end=p->data.iFinishPos; ses.data=NULL; ToErase.add_tail(ses); } } } res=""; char* y; last=0; for(ag::list<StartEndStruct>::member p=ToErase.head;(p!=NULL);p=p->next) { y=new char[p->data.start+1]; strncpy(y,k+last,p->data.start-last); // if (debugmode) std::cout<<": "<<k<<"\n"; y[(p->data.start)-last]=0; res+=y; delete[] y; if (p->data.data!=NULL) res+=(char*)(p->data.data); last=p->data.end; } y=new char[strlen(k)-last+1]; strncpy(y,k+last,strlen(k)-last); // if (debugmode) std::cout<<p->data.start<<' '<<p->data.end<<": "<<k; y[strlen(k)-last]=0; res+=y; delete[] y; //if (debugmode) std::cout<<res; y=new char[res.size()+1]; strcpy(y,res.c_str()); y[res.size()]=0; ((saveto!=NULL)?*saveto:sPText) = y; }
void CPRApplication::PreprocessIfDefs(char** saveto, char* sText, char* workdir) { // обработка: define, ifdef, ifndef, endif, elif //ag::tree<> pPpcsTree; ag::list<CPRTokenInfo>* pTok=new ag::list<CPRTokenInfo>; ag::list<StartEndStruct> StartEndList; CPRDefine dfn; ag::stack<DefStackElement> DefStack; ParseIt(pTok,sText,true,true); DefStackElement dse; dse.iPos=0; dse.Processing=true; DefStack.add_tail(dse); for(ag::list<CPRTokenInfo>::member p=pTok->head;(p!=NULL)&&(p->data.petCurrType!=petEOF);p=p->next) { if (p->data.sCurrText[0]=='#') { do p=p->next; while (p->data.sCurrText[0]==' '); if (DefStack.empty()||(DefStack.tail->data.Processing)) { if (strcmp(p->data.sCurrText,"define")==0) { do p=p->next; while (p->data.sCurrText[0]==' '); char* ident; ident=ReadIdent(&p,sText); if (p->data.sCurrText[0]=='(') dfn.dt=cdtMacro; else dfn.dt=cdtConst; if (dfn.dt==cdtConst) { dfn.params=NULL; dfn.name=ident; while (p->data.sCurrText[0]==' ') p=p->next; if (p->data.sCurrText[0]!='\n') { dfn.expr=ReadToEOLN(&p,sText); }else dfn.expr=NULL; } if (dfn.dt==cdtMacro) { // } bool replace=false; for(ag::list<CPRDefine>::member m=sDefines.head;m!=NULL;m=m->next) { if(strcmp(m->data.name,ident)==0) { m->data.dt=dfn.dt; m->data.params=dfn.params; m->data.expr=dfn.expr; replace=true; break; } } if (!replace) sDefines.add_tail(dfn); } if (strcmp(p->data.sCurrText,"undef")==0) { do p=p->next; while (p->data.sCurrText[0]==' '); std::string ident; while(sIdentSymbs%p->data.sCurrText[0]) { ident+=p->data.sCurrText; p=p->next; } for(ag::list<CPRDefine>::member m=sDefines.head;m!=NULL;m=m->next) { if(strcmp(m->data.name,ident.c_str())==0) { sDefines.del(m); break; } } } if ((strcmp(p->data.sCurrText,"ifdef")==0)||(strcmp(p->data.sCurrText,"ifndef")==0)) { //if (StartEndList.count()==1) {StartEndList.tail->data.end=p->data.iStartPos;}; StartEndStruct ses; ses.start=DefStack.tail->data.iPos; ses.end=p->prev->data.iStartPos; StartEndList.add_tail(ses); do p=p->next; while (p->data.sCurrText[0]==' '); char* ident; ident=ReadIdent(&p,sText); bool def=false; for(ag::list<CPRDefine>::member m=sDefines.head;m!=NULL;m=m->next) { if(strcmp(m->data.name,ident)==0) { def=true; break; } } DefStackElement dse; dse.iPos = p->data.iStartPos; if (strcmp(p->data.sCurrText,"ifdef")==0) dse.Processing=def; else dse.Processing=!def; DefStack.push(dse); } } if (strcmp(p->data.sCurrText,"else")==0) { DefStack.tail->data.Processing=!DefStack.tail->data.Processing; if (DefStack.tail->data.Processing) { DefStack.tail->data.iPos=p->data.iFinishPos; StartEndStruct ses; }else { StartEndStruct ses; ses.start=DefStack.tail->data.iPos; ses.end=p->prev->data.iStartPos; StartEndList.add_tail(ses); } do p=p->next; while (p->data.sCurrText[0]==' '); } if (strcmp(p->data.sCurrText,"endif")==0) { if (DefStack.tail->data.Processing) { StartEndStruct ses; ses.start=DefStack.tail->data.iPos; ses.end=p->prev->data.iStartPos; StartEndList.add_tail(ses); } do p=p->next; while (p->data.sCurrText[0]==' '); DefStack.pop(); DefStack.tail->data.iPos=p->prev->data.iFinishPos; } } } StartEndStruct ses; ses.start=DefStack.tail->data.iPos; ses.end=strlen(sText)-1; StartEndList.add_tail(ses); DefStack.pop(); if (!DefStack.empty()) throw "The count of #ifdef's and #endif's is not equall"; std::string res; char* k; res=""; for(ag::list<StartEndStruct>::member p=StartEndList.head;(p!=NULL);p=p->next) { k=new char[p->data.end-p->data.start+1]; strncpy(k,sText+p->data.start,p->data.end-p->data.start); k[p->data.end-p->data.start]=0; res+=k; delete[] k; } k=new char[res.size()+1]; strcpy(k,res.c_str()); k[res.size()]=0; ((saveto!=NULL)?*saveto:sPText) = k; }