//----------------------------------------------------------------- static HRESULT ScanAttribute( const CH * pchStart, const CH * pchEnd, HATT * pAtt) { if(pchStart == NULL) return E_INVALIDARG; const CH * pch; int cch; const CH * pchScan = pchStart; HRESULT hr; if (pAtt) memset(pAtt, 0, sizeof(HATT)); SKIPWHITE_FAIL switch (*pchScan) { case _CH('>'): return S_FALSE; // end of tag -- no attribute case _CH('/'): // End of empty element (e.g. "<foo ... />"). No more attributes. return S_FALSE; case _CH('-'): // comment if (pAtt) return ScanComment(pchScan, pchEnd, &pAtt->pchValue, &pAtt->cchValue); else return ScanComment(pchScan, pchEnd, 0, 0); break; } // scan Name hr = ScanName(pchScan, pchEnd, &pch, &cch); if (FAILED(hr)) return hr; if (pAtt) { pAtt->pchName = pch; pAtt->cchName = cch; } pchScan = pch + cch; SKIPWHITE_FAIL if (*pchScan != _CH('=')) return hr; pchScan++; SKIPWHITE_FAIL hr = ScanValue(pchScan, pchEnd, &pch, &cch); if (SUCCEEDED(hr) && pAtt) { pAtt->pchValue = pch; pAtt->cchValue = cch; } return hr; }
static void ScanCodeBlock(void) { int startline = yyline; /* keutzer char c; */ int c; if(curCdBlock==NULL) { curCdBlock = CodeGetBlock(); curCdBlock = CodeMarkLine(curCdBlock,yyline); } while((c=getc(fin))!=EOF) { if (c=='}') return; else if (c=='$') ScanTreeReference(); else curCdBlock = CodeStoreChar(curCdBlock, c); if (c=='\n') yyline++; if (c=='"') ScanString(getput); else if (c=='\'') ScanChar(); else if (c=='/') { if ((c=getc(fin))=='*') { curCdBlock = CodeStoreChar(curCdBlock, '*'); ScanComment(getput); } else ungetc(c, fin); } else if (c=='{') { ScanCodeBlock(); curCdBlock = CodeStoreChar (curCdBlock, '}'); } } yyerror2("{ on line %d has no closing }", startline); nerrors++; }
//----------------------------------------------------------------- static void ScanItem (const CH * pchStart, const CH * pchEnd, HTOK * pk) { if(pchStart == NULL || pk == NULL) { VSASSERT(false,""); return; } HRESULT hr; pk->id = hi_Unknown; pk->pch = (CH*)pchStart; pk->cch = 0; pk->bEnd = false; if (pchStart >= pchEnd) { pk->id = hi_Eof; return; } const CH * pchScan = pchStart; switch (*pchScan) { // case _CH(0): // pk->id = hi_Eof; // break; // // case _CH('\n'): // case _CH('\r'): // pchScan = AdvanceLineBreak((CH*)pchScan); // pk->id = hi_Eol; // break; case _CH('<'): { const CH * pchName; int cch; pchScan++; pk->id = hi_Error; switch (*pchScan) { case _CH('!'): pk->id = hi_Error; pchScan++; while (_CH('>') != *pchScan) { const CH * pch; int cch; SKIPWHITE_RET if (IsAAlpha(*pchScan)) hr = ScanName(pchScan, pchEnd, &pch, &cch); else { switch(*pchScan) { case CH('\''): case CH('"'): hr = ScanValue(pchScan, pchEnd, &pch, &cch); break; case CH('-'): hr = ScanComment(pchScan, pchEnd, &pch, &cch); break; default: hr = S_OK; pch = pchScan; cch = 1; break; } } pchScan = pch + cch; if (FAILED(hr) || (pchScan >= pchEnd)) return; } pk->id = hi_TagSpecial; break; case _CH('%'): // ASP 'tag' pk->id = hi_TagSpecial; do { do { pchScan++; } while ((pchScan < pchEnd) && (_CH('>') != *pchScan)); } while ((pchScan < pchEnd) && (*(pchScan-1) != _CH('%'))); break; case _CH('/'): pk->bEnd = true; pchScan++; break; case _CH('?'): // pk->id = hi_TagSpecial; pchScan++; while ((pchScan < pchEnd) && (_CH('>') != *pchScan)) pchScan++; break; } if (pk->id != hi_TagSpecial) { pk->id = hi_Error; SKIPWHITE_RET if (!IsAAlpha(*pchScan)) return; pchName = pchScan; while ((pchScan < pchEnd) && IsAAlNum(*pchScan)) pchScan++; if (pchScan >= pchEnd) return; cch = (int)(pchScan - pchName); if (cch <= cchMaxTag && cch > 0) { CH * pszName = (CH*)_alloca((cch+1)*CBCH ); strcchcopy(pszName, cch+1, pchName); pk->id = LookupElement(pszName); } else return; if (!pk->bEnd) { // scan attributes and comments for(;;) { HATT hatt; HRESULT hr = ScanAttribute(pchScan, pchEnd, &hatt); if (FAILED(hr)) { pk->id = hi_Error; return; } if (S_FALSE == hr) break; pchScan = hatt.pchValue ? hatt.pchValue + hatt.cchValue : hatt.pchName + hatt.cchName; } } } // Skip over whitespace and, if this is an empty element, the closing '/' (e.g. "<foo ... />") while ((pchScan < pchEnd) && ((*pchScan <= 32) || (*pchScan == _CH('/')))) pchScan++; if ((pchScan >= pchEnd) || (_CH('>') != *pchScan)) pk->id = hi_Error; pchScan++; } break; // case _CH('&'): // pk->id = hi_Entity; // if (!ScanEntity(pchScan, &pk->ch, &pchScan)) // goto L_Text; // break; default: //L_Text: pk->id = hi_Text; for (bool f = true; f && (pchScan < pchEnd); ) { switch (*pchScan) { // case _CH(0): // case _CH('\n'): // case _CH('\r'): // case _CH('&'): case _CH('<'): f = false; break; default: pchScan++; break; } } break; }
int yylex(void) { register c; register char *cp; yylval.y_nodep = (struct node *) NULL; cp = token_buffer; while((c=getc(fin))!=EOF) { switch(c) { case ' ': case '\t': case '\f': continue; case '@': case '[': case ']': case ';': case ':': case '(': case ')': case ',': case '=': case '*': if(debug_flag&DB_LEX) { putc(c,stderr); putc('\n', stderr); } *cp++ = c; *cp = '\0'; return(c); case '{': ScanCodeBlock(); yylval.y_code = curCdBlock; curCdBlock = NULL; *cp++ = '{'; *cp = '}'; return(CBLOCK); case '\n': yyline++; continue; case '/': if ((c=getc(fin))=='*') { ScanComment(get); continue; } else { ungetc(c, fin); c = '/'; } /* FALL THRU */ default: if (isdigit(c)) { int errs = 0; do { if(cp > &token_buffer[MAXIDSIZE]) { token_buffer[MAXIDSIZE] = '\0'; yyerror("number too long"); errs++; } else *cp++ = c; c = getc(fin); } while (isdigit(c)); if(isalpha(c)) yyerror2("illegal digit '%c'", c); ungetc(c, fin); if(errs) return(ERROR); yylval.y_int = atoi(token_buffer); return(NUMBER); } if (isalpha(c)) { SymbolEntry *sp; int errs = 0; do { if(cp > &token_buffer[MAXIDSIZE]) { token_buffer[MAXIDSIZE] = '\0'; yyerror("ID too long"); errs++; } else *cp++ = c; c = getc(fin); } while (isalpha(c)||isdigit(c)||c=='_'); ungetc(c, fin); if(errs) return(ERROR); *cp = '\0'; sp = SymbolLookup (token_buffer); if (sp==NULL) { /* undefined */ yylval.y_symp = SymbolAllocate(token_buffer); } else { /* already defined */ if (sp->attr == A_KEYWORD) return (sp->sd.keyword); yylval.y_symp = sp; } if(debug_flag&DB_LEX) fprintf(stderr, "ID\n"); return(ID); } yyerror2("illegal character (\\%03o)", c); } } strcpy(token_buffer, "EOF"); return(0); }