⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cweave.w

📁 模拟器提供了一个简单易用的平台
💻 W
📖 第 1 页 / 共 5 页
字号:
line by putting a |'%'| just before the last character.@<Print warning message...@>={  printf("\n! Line had to be broken (output l. %d):\n",out_line);@.Line had to be broken@>  term_write(out_buf+1, out_ptr-out_buf-1);  new_line; mark_harmless;  flush_buffer(out_ptr-1,1,1); return;}@ Here is a macro that outputs a section number in decimal notation.The number to be converted by |out_section| is known to be less than|def_flag|, so it cannot have more than five decimal digits.  Ifthe section is changed, we output `\.{\\*}' just after the number.@cvoidout_section(n)sixteen_bits n;{  char s[6];  sprintf(s,"%d",n); out_str(s);  if(changed_section[n]) out_str ("\\*");@.\\*@>}@ The |out_name| procedure is used to output an identifier or indexentry, enclosing it in braces.@cvoidout_name(p,quote_xalpha)name_pointer p;boolean quote_xalpha;{  char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */  out('{');  for (k=p->byte_start; k<k_end; k++) {    if (isxalpha(*k) && quote_xalpha) out('\\');@.\\\$@>@.\\\_@>    out(*k);  }  out('}');}@* Routines that copy \TEX/ material.During phase two, we use subroutines |copy_limbo|, |copy_TeX|, and|copy_comment| in place of the analogous |skip_limbo|, |skip_TeX|, and|skip_comment| that were used in phase one. (Well, |copy_comment|was actually written in such a way that it functions as |skip_comment|in phase one.)The |copy_limbo| routine, for example, takes \TEX/ material that is notpart of any section and transcribes it almost verbatim to the output file.The use of `\.{@@}' signs is severely restricted in such material:`\.{@@@@}' pairs are replaced by singletons; `\.{@@l}' and `\.{@@q}' and`\.{@@s}' are interpreted.@cvoidcopy_limbo(){  char c;  while (1) {    if (loc>limit && (finish_line(), get_line()==0)) return;    *(limit+1)='@@';    while (*loc!='@@') out(*(loc++));    if (loc++<=limit) {      c=*loc++;      if (ccode[(eight_bits)c]==new_section) break;      switch (ccode[(eight_bits)c]) {        case translit_code: out_str("\\ATL"); break;@.\\ATL@>        case '@@': out('@@'); break;        case noop: skip_restricted(); break;        case format_code: if (get_next()==identifier) get_next();          if (loc>=limit) get_line(); /* avoid blank lines in output */          break; /* the operands of \.{@@s} are ignored on this pass */        default: err_print("! Double @@ should be used in limbo");@.Double @@ should be used...@>        out('@@');      }    }  }}@ The |copy_TeX| routine processes the \TEX/ code at the beginning of asection; for example, the words you are now reading were copied in thisway. It returns the next control code or `\.{\v}' found in the input.We don't copy spaces or tab marks into the beginning of a line. Thismakes the test for empty lines in |finish_line| work.@ @f copy_TeX TeX@ceight_bitscopy_TeX(){  char c; /* current character being copied */  while (1) {    if (loc>limit && (finish_line(), get_line()==0)) return(new_section);    *(limit+1)='@@';    while ((c=*(loc++))!='|' && c!='@@') {      out(c);      if (out_ptr==out_buf+1 && (xisspace(c))) out_ptr--;    }    if (c=='|') return('|');    if (loc<=limit) return(ccode[(eight_bits)*(loc++)]);  }}@ The |copy_comment| function issues a warning if more braces are opened thanclosed, and in the case of a more serious error it supplies enoughbraces to keep \TEX/ from complaining about unbalanced braces.Instead of copying the \TEX/ materialinto the output buffer, this function copies it into the token memory(in phase two only).The abbreviation |app_tok(t)| is used to append token |t| to the currenttoken list, and it also makes sure that it is possible to append at leastone further token without overflow.@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;}@<Predec...@>=int copy_comment();@ @cint copy_comment(is_long_comment,bal) /* copies \TEX/ code in comments */boolean is_long_comment; /* is this a traditional \CEE/ comment? */int bal; /* brace balance */{  char c; /* current character being copied */  while (1) {    if (loc>limit) {      if (is_long_comment) {        if (get_line()==0) {          err_print("! Input ended in mid-comment");@.Input ended in mid-comment@>          loc=buffer+1; goto done;        }      }      else {        if (bal>1) err_print("! Missing } in comment");@.Missing \} in comment@>        goto done;      }    }    c=*(loc++);    if (c=='|') return(bal);    if (is_long_comment) @<Check for end of comment@>;    if (phase==2) {      if (ishigh(c)) app_tok(quoted_char);      app_tok(c);    }    @<Copy special things when |c=='@@', '\\'|@>;    if (c=='{') bal++;    else if (c=='}') {      if(bal>1) bal--;      else {err_print("! Extra } in comment");@.Extra \} in comment@>        if (phase==2) tok_ptr--;      }    }  }done:@<Clear |bal| and |return|@>;}@ @<Check for end of comment@>=if (c=='*' && *loc=='/') {  loc++;  if (bal>1) err_print("! Missing } in comment");@.Missing \} in comment@>  goto done;}@ @<Copy special things when |c=='@@'...@>=if (c=='@@') {  if (*(loc++)!='@@') {    err_print("! Illegal use of @@ in comment");@.Illegal use of @@...@>    loc-=2; if (phase==2) *(tok_ptr-1)=' '; goto done;  }}else if (c=='\\' && *loc!='@@')  if (phase==2) app_tok(*(loc++)) else loc++;@ We outputenough right braces to keep \TEX/ happy.@<Clear |bal|...@>=if (phase==2) while (bal-- >0) app_tok('}');return(0);@** Parsing.The most intricate part of \.{CWEAVE} is its mechanism for converting\CEE/-like code into \TEX/ code, and we might as well plunge into thisaspect of the program now. A ``bottom up'' approach is used to parse the\CEE/-like material, since \.{CWEAVE} must deal with fragmentaryconstructions whose overall ``part of speech'' is not known.At the lowest level, the input is represented as a sequence of entitiesthat we shall call {\it scraps}, where each scrap of information consistsof two parts, its {\it category} and its {\it translation}. The categoryis essentially a syntactic class, and the translation is a token list thatrepresents \TEX/ code. Rules of syntax and semantics tell us how tocombine adjacent scraps into larger ones, and if we are lucky an entire\CEE/ text that starts out as hundreds of small scraps will jointogether into one gigantic scrap whose translation is the desired \TEX/code. If we are unlucky, we will be left with several scraps that don'tcombine; their translations will simply be output, one by one.The combination rules are given as context-sensitive productions that areapplied from left to right. Suppose that we are currently working on thesequence of scraps $s_1\,s_2\ldots s_n$. We try first to find the longestproduction that applies to an initial substring $s_1\,s_2\ldots\,$; but ifno such productions exist, we try to find the longest productionapplicable to the next substring $s_2\,s_3\ldots\,$; and if that fails, wetry to match $s_3\,s_4\ldots\,$, etc.A production applies if the category codes have a given pattern. Forexample, one of the productions (see rule~3) is$$\hbox{|exp| }\left\{\matrix{\hbox{|binop|}\cr\hbox{|ubinop|}}\right\}\hbox{ |exp| }\RA\hbox{ |exp|}$$and it means that three consecutive scraps whose respective categories are|exp|, |binop| (or |ubinop|),and |exp| are converted to one scrap whose categoryis |exp|.  The translations of the originalscraps are simply concatenated.  The case of$$\hbox{|exp| |comma| |exp| $\RA$ |exp|} \hskip4emE_1C\,\\{opt}9\,E_2$$(rule 4) is only slightly more complicated:Here the resulting |exp| translationconsists not only of the three original translations, but also of thetokens |opt| and 9 between the translations of the|comma| and the following |exp|.In the \TEX/ file, this will specify an optional line break after thecomma, with penalty 90.At each opportunity the longest possible production is applied.  Forexample, if the current sequence of scraps is |int_like| |cast||lbrace|, rule 31 is applied; but if the sequence is |int_like| |cast|followed by anything other than |lbrace|, rule 32 takes effect.Translation rules such as `$E_1C\,\\{opt}9\,E_2$' above use subscriptsto distinguish between translations of scraps whose categories have thesame initial letter; these subscripts are assigned from left to right.@ Here is a list of the category codes that scraps can have.(A few others, like |int_like|, have already been defined; the|cat_name| array contains a complete list.)@d exp 1 /* denotes an expression, including perhaps a single identifier */@d unop 2 /* denotes a unary operator */@d binop 3 /* denotes a binary operator */@d ubinop 4  /* denotes an operator that can be unary or binary, depending on context */@d cast 5 /* denotes a cast */@d question 6 /* denotes a question mark and possibly the expressions flanking it */@d lbrace 7 /* denotes a left brace */@d rbrace 8 /* denotes a right brace */@d decl_head 9 /* denotes an incomplete declaration */@d comma 10 /* denotes a comma */@d lpar 11 /* denotes a left parenthesis or left bracket */@d rpar 12 /* denotes a right parenthesis or right bracket */@d prelangle 13 /* denotes `$<$' before we know what it is */@d prerangle 14 /* denotes `$>$' before we know what it is */@d langle 15 /* denotes `$<$' when it's used as angle bracket in a template */@d colcol 18 /* denotes `::' */@d base 19 /* denotes a colon that introduces a base specifier */@d decl 20 /* denotes a complete declaration */@d struct_head 21 /* denotes the beginning of a structure specifier */@d stmt 23 /* denotes a complete statement */@d function 24 /* denotes a complete function */@d fn_decl 25 /* denotes a function declarator */@d semi 27 /* denotes a semicolon */@d colon 28 /* denotes a colon */@d tag 29 /* denotes a statement label */@d if_head 30 /* denotes the beginning of a compound conditional */@d else_head 31 /* denotes a prefix for a compound statement */@d if_clause 32 /* pending \.{if} together with a condition */@d lproc 35 /* begins a preprocessor command */@d rproc 36 /* ends a preprocessor command */@d insert 37 /* a scrap that gets combined with its neighbor */@d section_scrap 38 /* section name */@d dead 39 /* scrap that won't combine */@d ftemplate 59 /* \\{make\_pair} */@d new_exp 60 /* \&{new} and a following type identifier */@d begin_arg 61 /* \.{@@[} */@d end_arg 62 /* \.{@@]} */@<Glo...@>=char cat_name[256][12];eight_bits cat_index;@ @<Set in...@>=    for (cat_index=0;cat_index<255;cat_index++)      strcpy(cat_name[cat_index],"UNKNOWN");@.UNKNOWN@>    strcpy(cat_name[exp],"exp");    strcpy(cat_name[unop],"unop");    strcpy(cat_name[binop],"binop");    strcpy(cat_name[ubinop],"ubinop");    strcpy(cat_name[cast],"cast");    strcpy(cat_name[question],"?");    strcpy(cat_name[lbrace],"{"@q}@>);    strcpy(cat_name[rbrace],@q{@>"}");    strcpy(cat_name[decl_head],"decl_head");    strcpy(cat_name[comma],",");    strcpy(cat_name[lpar],"(");    strcpy(cat_name[rpar],")");    strcpy(cat_name[prelangle],"<");    strcpy(cat_name[prerangle],">");    strcpy(cat_name[langle],"\\<");    strcpy(cat_name[colcol],"::");    strcpy(cat_name[base],"\\:");    strcpy(cat_name[decl],"decl");    strcpy(cat_name[struct_head],"struct_head");    strcpy(cat_name[alfop],"alfop");    strcpy(cat_name[stmt],"stmt");    strcpy(cat_name[function],"function");    strcpy(cat_name[fn_decl],"fn_decl");    strcpy(cat_name[else_like],"else_like");    strcpy(cat_name[semi],";");    strcpy(cat_name[colon],":");    strcpy(cat_name[tag],"tag");    strcpy(cat_name[if_head],"if_head");    strcpy(cat_name[else_head],"else_head");    strcpy(cat_name[if_clause],"if()");    strcpy(cat_name[lproc],"#{"@q}@>);    strcpy(cat_name[rproc],@q{@>"#}");    strcpy(cat_name[insert],"insert");    strcpy(cat_name[section_scrap],"section");    strcpy(cat_name[dead],"@@d");    strcpy(cat_name[public_like],"public");    strcpy(cat_name[operator_like],"operator");    strcpy(cat_name[new_like],"new");    strcpy(cat_name[catch_like],"catch");    strcpy(cat_name[for_like],"for");    strcpy(cat_name[do_like],"do");    strcpy(cat_name[if_like],"if");    strcpy(cat_name[delete_like],"delete");    strcpy(cat_name[raw_ubin],"ubinop?");    strcpy(cat_name[const_like],"const");    strcpy(cat_name[raw_int],"raw");    strcpy(cat_name[int_like],"int");    strcpy(cat_name[case_like],"case");    strcpy(cat_name[sizeof_like],"sizeof");    strcpy(cat_name[struct_like],"struct");    strcpy(cat_name[typedef_like],"typedef");    strcpy(cat_name[define_like],"define");    strcpy(cat_name[template_like],"template");    strcpy(cat_name[ftemplate],"ftemplate");    strcpy(cat_name[new_exp],"new_exp");    strcpy(cat_name[begin_arg],"@@["@q]@>);    strcpy(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -