static void append_char(int c) { if (yyleng >= MAXTEXTLEN - 1) { end_text(); clear_text(); } yytext[yyleng++] = c; }
void m_textout_f(const MFONT *font, const char *text, float x, float y, MCOLOR color) { bool end = !text_draw_on; if (font == game_font) { start_text(); x *= (screenScaleX/textScaleX); y *= (screenScaleY/textScaleY); } al_draw_text(font, color, x, y, 0, text); if (font == game_font && end) { end_text(); } }
void htmlcxx::HTML::ParserSax::parse(_Iterator &begin, _Iterator &end, std::forward_iterator_tag) { typedef _Iterator iterator; // std::cerr << "Parsing forward_iterator" << std::endl; mCdata = false; mpLiteral = 0; mCurrentOffset = 0; this->beginParsing(); //开始解析 // DEBUGP("Parsed text\n"); /* 这个while循环是最外层的循环,其循环的依据是begin和end两个游标,这两个游标始终指向了待解析的文本串的起始端和结束端。 */ while (begin != end) { *begin; // This is for the multi_pass to release the buffer iterator c(begin); /* 该while循环是次外层的循环,每次结束都即为解析出一个节点。 */ while (c != end) { // For some tags, the text inside it is considered literal and is // only closed for its </TAG> counterpart /* 在这个循环的判断条件中,mpLiteral默认初始值为0,在运行后面的ParseHtmlTag()方法时候会更改它的值, 如果不为零,则说明当前的tagName应当为以下这个数组的str属性其中之一。 */ while (mpLiteral) { //DEBUGP("Treating literal %s\n", mpLiteral); //向后不断查找,直到找到了文件末尾或’<’才停止,此刻说明解析完毕或者解析到了某个tag标签 while (c != end && *c != '<') ++c; if (c == end) //如果成立说明解析完毕 { if (c != begin) this->parseContent(begin, c);//此时最后一个解析的标签末尾和文档末尾之间可能还有一段内容需要解析 goto DONE;//转到结束阶段 } iterator end_text(c);//申请一个新游标end_text,初始值赋入c,为后面的代码记录下当前’<’符号的位置。 ++c;//将c游标前进一步 if (*c == '/')//判断’<’后面紧跟的是否为’/’符号 { ++c; //前进一步,指向tagName的起始位置 const char *l = mpLiteral; /* 逐字节将mpLiteral和tagName进行比较. 跳出最后一个while循环时,c和l应当指向的是mpLiteral和tagName从起始位置开始的最小公共子串的结束位置, 如果匹配成功则l应当指向字符串的最后一个位置+1,即为空。 */ while (*l && ::tolower(*c) == *l) { ++c; ++l; } // FIXME: Mozilla stops when it sees a /plaintext. Check // other browsers and decide what to do if (!*l && strcmp(mpLiteral, "plaintext")) { // matched all and is not tag plaintext //说明不是plaintext标签,且此时l指针为空 while (isspace(*c)) ++c; //跳过空格字符 if (*c == '>') //直到找到标签结束位置 { ++c; if (begin != end_text) this->parseContent(begin, end_text); //处理这段标签之前的那段“文本” mpLiteral = 0;//更改循环进入条件 c = end_text;//修改游标值 begin = c; //修改游标值 break;//跳出循环,此时说明已经找到了对应tagName的</tagName>标签 } } } else if (*c == '!')//在寻找过程中遇到注释的情况,也需要做出相应处理。 { // we may find a comment and we should support it iterator e(c); ++e; if (e != end && *e == '-' && ++e != end && *e == '-') { //DEBUGP("Parsing comment\n"); ++e; c = this->skipHtmlComment(e, end); } //if (begin != end_text) //this->parseContent(begin, end_text, end); //this->parseComment(end_text, c, end); // continue from the end of the comment //begin = c; } } if (*c == '<') //判断是否是一个标签的开始 { iterator d(c); //申请一个新游标d,初始为这个’<’的位置 ++d; //将其后移一位 if (d != end)//如果不是文档的结尾 { if (isalpha(*d)) //判断是否为英文字母 { // beginning of tag if (begin != c) //如果标签之前还有一段文本 this->parseContent(begin, c); //DEBUGP("Parsing beginning of tag\n"); d = this->skipHtmlTag(d, end);//找到Tag标签的结束位置 this->parseHtmlTag(c, d); //对Tag标签的起始位置和结束位置之间的这段标签内容适用parseHtmltag(X,X)进行处理。 // continue from the end of the tag c = d; //将游标移动到标签之后的位置 begin = c; break;//成功解析出一个节点,跳出循环 } if (*d == '/') { if (begin != c)//如果标签之前还有一段文本 this->parseContent(begin, c); iterator e(d); //申请一个新标签e,初始化为d ++e;//将其后移一位 if (e != end && isalpha(*e)) //说明此时e指向的是结尾型标签的起始处 { // end of tag // DEBUGP("Parsing end of tag\n"); d = this->skipHtmlTag(d, end);//寻找标签结束位置 this->parseHtmlTag(c, d);//对这段位置之间的标签进行处理 } else { // not a conforming end of tag, treat as comment // as Mozilla does //不是一个标准的结束型标签,和Mozilla采用一样的处理方式 //DEBUGP("Non conforming end of tag\n"); d = this->skipHtmlTag(d, end); //将游标移动到tag标签之后继续 this->parseComment(c, d); //解析出一个节点,跳出循环 } // continue from the end of the tag c = d; begin = c; break; } if (*d == '!') { // comment //说明是注释标签 if (begin != c)//如果此标签之前还有一段文本 this->parseContent(begin, c); iterator e(d); //申请一个游标e,初始化为d ++e; if (e != end && *e == '-' && ++e != end && *e == '-') { // DEBUGP("Parsing comment\n"); ++e; d = this->skipHtmlComment(e, end);//查找到标签结尾 } else { d = this->skipHtmlTag(d, end); //也可能注释直到文档结束 } this->parseComment(c, d);//将这段文本作为注释进行处理 // continue from the end of the comment c = d;//移动游标至标签结尾处 begin = c; break;//成功解析出一个标签,跳出循环 } if (*d == '?' || *d == '%') { // something like <?xml or <%VBSCRIPT //处理一些诸如<?xml 或 <%VBSCRIPT之类的特殊标签 if (begin != c) this->parseContent(begin, c); d = this->skipHtmlTag(d, end); this->parseComment(c, d); // continue from the end of the comment c = d; begin = c; break; } } } c++; } // There may be some text in the end of the document //在所有标签都处理完后,可能在文档末尾还有一些文本要进行处理 if (begin != c) { this->parseContent(begin, c); begin = c; } } //作为GOTO代码的位置,即为解析结束后执行的收尾工作 DONE: this->endParsing(); return; }
static int id_token(void) { extern symptr lookup(char *, int); extern symptr install(char *, int, int, int, Int); extern int local_declare(char *); extern int lookup_local(char *); int i; symptr sp; char *tempyytext; char *tempagentname; char aname[80]; int context; void *tempoid; context = basecontext; tempagentname = agentName; while (isalnum(nextc) || nextc == '_') { input(); } end_text1(); /* printf("yytext %s", yytext); */ if ((i = keyword_token(yytext))) { /* keyword ? */ if (i==EVAL) inEVAL = 1; end_text(); return i; /* return the lexeme */ } if (nextc == ':') { if (peek() == ':') { strcpy(aname, yytext); tempagentname = aname; input(); input(); end_text(); clear_text(); while (isalnum(nextc) || nextc == '_') { input(); } end_text1(); } } if (inauto || inpara) { /* declaring local variables ? */ end_text(); yylval.narg = local_declare(yytext); return LOCAL; } else { /* in statements */ if ((i = lookup_local(yytext))) { /* local variable ? */ end_text(); if (i < 0) { /* it is an argument */ yylval.narg = -i; return ARG; } else { /* it is a local variable */ yylval.narg = i; return LOCAL; } } else { if (builtin_ft_check(yytext) == 0) { /* Don't append (pre or post) an agent name if: 1) if a built-in function, 2) if we're in the general context (no >> syntax etc used), 3) the definitions are from a Scout window definition, 4) similarly, if the definitions are from a Donald 'within' definition, 5) if the name already has a ~ prefix [Ash, with Patrick] */ /* printf("yytext1 = %s %s %i %i %i\n", yytext, agentName, appAgentName, append_agentName, append_NoAgentName); */ if (*tempagentname != 0 && appAgentName > 0 && append_agentName > 0 && append_NoAgentName > 0) { /*tempyytext = yytext; new_yytext[0] = '\0'; if (yytext[0] == '_' && inPrefix) { strcat(new_yytext, "_"); tempyytext++; } if (inPrefix) strcat(new_yytext, agentName); else strcat(new_yytext, tempyytext); strcat(new_yytext, "_"); *//* New double underbar for DOSTE context [Nick] */ /*if (inPrefix) strcat(new_yytext, tempyytext); else strcat(new_yytext, agentName); strcpy(yytext, new_yytext); yyleng = strlen(yytext);*/ /* printf("agentName = %s \n", agentName); */ /* printf("yytext = %s \n", yytext); */ /* Make a context from agent name [Nick] */ context = doste_context(tempagentname); } } end_text(); /* must be global [Ash] */ if ((sp = lookup(yytext, context)) == 0) { /* doesn't already exist [Ash] */ sp = install(yytext,context, VAR, UNDEF, 0); /* printf("new_yytext = %s", yytext); */ } #ifdef DISTRIB if (!strcmp(sp->name, "higherPriority")) setHighPrior=1; #endif /* DISTRIB */ yylval.sym = sp; return sp->stype; } } }
static int number_token(void) { int i; double r; int m, n, e, is_float; char *format; int is_hex; uDatum u; is_float = m = n = e = FALSE; while (isdigit(nextc)) { input(); m = TRUE; } if (nextc == '.') { input(); is_float = TRUE; } while (isdigit(nextc)) { input(); n = TRUE; } if (is_float && !m && !n) /* a single dot */ return '.'; if (nextc == 'E' || nextc == 'e') { input(); is_float = TRUE; if (nextc == '+' || nextc == '-') input(); while (isdigit(nextc)) { input(); e = TRUE; } if (!e) error("Floating-point format error"); } if (is_float) { /* floating point */ end_text(); sscanf(yytext, "%lf", &r); u.r = r; yylval.dp = makedatum(REAL, u); return CONSTANT; } else if (*yytext == '0') {/* octal or hexdecimal */ is_hex = nextc == 'x' || nextc == 'X'; format = is_hex ? "%x" : "%o"; if (is_hex) { do { input(); /* read the 'x' */ } while (isxdigit(nextc)); } end_text(); sscanf((is_hex ? yytext + 2 : yytext), format, &i); u.i = i; yylval.dp = makedatum(INTEGER, u); return CONSTANT; } else { /* decimal */ end_text(); u.i = atoi(yytext); yylval.dp = makedatum(INTEGER, u); return CONSTANT; } }
int yylex(void) { char *s; uDatum u; #ifdef DISTRIB extern Int *higherPriority; #endif /* DISTRIB */ /* initial for a token */ clear_text(); if (bof) { bof = 0; if (nextc == '%') { /* comment line */ skip_percent_comment();/* return next token */ end_text(); clear_text(); } /* printf("bof \n"); */ if (nextc == '>' || nextc == '<') getAgentName(); } restart: while (isspace(nextc) && (nextc != '\n') && (nextc != '\r')) { /* skip blanks */ input(); } if ((nextc == '\n') || (nextc == '\r')) { input(); if (nextc == '%') { /* comment line */ skip_percent_comment();/* return next token */ end_text(); clear_text(); } /* printf("restart\n"); */ if (nextc == '>' || nextc == '<') getAgentName(); goto restart; } end_text(); clear_text(); if (nextc == 0) { /* EOF */ #ifdef DISTRIB if (setHighPrior) { *higherPriority=0; setHighPrior = 0; } #endif return 0; /* don't do input() so next token is EOF */ } #ifdef TTYEDEN prompt = promptsemi; #endif if (isdigit(nextc) || nextc == '.') /* a number or a dot */ return number_token(); if (isalpha(nextc) || nextc == '_') /* a keyword or an identifier */ { append_agentName = 1; return id_token(); } /*if (nextc == '^') { input(); append_agentName = 1; return context_token(); }*/ if (nextc == '\'') { while (input(), nextc != '\'') { if (nextc == '\\') input(); else if (nextc == 0) error("unexpected end-of-file in character constant"); } input(); /* read the quote */ /* mustn't alter the following two lines */ end_text(); /* accept the text */ last_char = '\0'; /* delete the last quote */ backslash(yytext + 1); /* resolve the backslashs */ if (yytext[2]) /* more than one char */ error("single char expected"); u.i = yytext[1]; yylval.dp = makedatum(MYCHAR, u); return CONSTANT; } if (nextc == '\"') { #ifdef TTYEDEN prompt = promptchar; #endif while (input(), nextc != '\"') { if (nextc == '\\') input(); else if (nextc == 0) error("unexpected end-of-file in string constant"); } input(); /* read the quote */ /* mustn't alter the following two lines */ end_text(); /* accept the text */ last_char = '\0'; /* delete the last quote */ backslash(yytext + 1); /* resolve the backslashs */ s = (char *) emalloc(strlen(yytext)); strcpy(s, yytext + 1); u.s = s; yylval.dp = makedatum(STRING, u); return CONSTANT; } input(); /* accept the char, must be the 1st char */ switch (*yytext) { /* the 1st char */ case '@': yylval.dp = makedatum(UNDEF, u); /* bug fix Ash + Carters */ RETURN_TOKEN(CONSTANT); break; case '~': /* for agency --sun */ if (isalpha(nextc) || nextc == '_') { clear_text(); append_agentName = 0; return id_token(); } break; case '$': while (isdigit(nextc)) input(); if (yyleng == 1) RETURN_TOKEN('$'); yylval.narg = atoi(yytext + 1); RETURN_TOKEN(ARG); case '/': #ifdef TTYEDEN prompt = promptcomment; #endif if (nextc == '*') { /* nested comment */ skip_comment(); /* return next token */ end_text(); clear_text(); #ifdef TTYEDEN prompt = prompt1; #endif goto restart; } break; case '#': if (nextc == '#') { skip_one_line_comment(); end_text(); clear_text(); #ifdef TTYEDEN prompt = prompt1; #endif goto restart; } break; } return (multi_symbol_token()); }