<% '============================================================== ' THIS FILE CONTAINS ONLY TWO PROCEDURES compile_schema and ' parse_s_ml_header '-------------------------------------------------------------- sub compile_schema(sml_schema_f) dim short3 'need to mark end of parcuts poor programming: 'no need for so many pieces of schema text dim wwwtemp1,wwwtemp2,wwwtempi '=== ugly programming, get rid dim j,k, s, ws, wss, wi, wii dim EndPos 'to parse long-shortcuts denoting multiline 'texts '------------------------------------------ this_version ="2" 'SET VERSION '------------------------------------------ '------------------------------------------------- 'define accessible variables: path_info = request.ServerVariables("PATH_INFO") wi = instrrev(path_info, "/") if wi <> 0 then this_page = mid(path_info,wi+1) else this_page = path_info end if '------------------------------------------------- '------------------------------------------ for j = 0 to elim for k = 0 to tlim sub_el_cut(j,k) = "" 'parameter shortcut = parcut = "" next for k = 0 to 127 tar(k,j)=0 'prepare target elements 'called by control k in scope j next next '------------------------------------------ 'variable "short" is a schema itself: '"what an ugly programming..." short = read_file ( sml_schema_f ) short = short & ve & ve '-------------------------------------------------- 've & ve is required 'comments may be put before this line 'comments can be empty; i = instr(short, ve & ve ) short = mid(short, i) '-------------------------------------------------- '-------------------------------------------------- 'VITAL STATMENT: UGLY PROGRAMMING: NextB 'skips this line and 'will and must be pointed precisely 'to \\short-ml 'or to next block. 'set_debug 'very good statement. recommended. '-------------------------------------------------- '-------------------------------------------------- 'HEADER: 'this ugly parse ... returns beginnig of schema: short = mid(short,parse_s_ml_header(1,short,true)) '-------------------------------------------------- element(0) = 0 '================================================================ for i = 1 to elim ' LOOP VIA S T A T E S L I S T '---------------------------------------------------------------- NextL 'the first line is always skipped 'so can have a comment. s = ThisT 'empty line terminates first block: if s = "" then exit for do while left(s,1) = "'" NextL s=ThisT if s = "" then exit for loop 'parse CONSTRUCT_ if right(s,1) = "_" then extended(i) = true s = left(s,len(s)-1) else extended(i) = false end if 'Upper case means tagable=true: if lcase(s) <> s then tagable(i) = true else tagable(i) = false end if s = lcase(s) 'fill out list of elements: element(i) = s 'ws = "some" foreign(i) = false halftag(i) = false abbr(i) = false 'true means that in result text 'will be a comment <!nest_level> for 'nest level in subelements tree. mark(i) = false '------------------------------------------------------------ if left(s,1) = SML_E_key then 'SML_E_key=="^"== 'long_shotrcut_control '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - element(i) = SML_E_key 'desing drawback; SML_E_long(i) = true SML_E_i = SML_E_i + 1 if SML_E_i > SML_E_m then stope "no space for long shortcuts" 'stack long_shortcut: SML_E_scut(SML_E_i) = s ws = NextT if left(ws,1) = """" then 'this is not a second token. 'This is a multiline text. SML_E_value(SML_E_i) = CutQuotedString( _ 1, _ short, _ """", true, true, true, EndPos) 'explanations: ' StartSearchPos, SourceS, Mark, _ ' RecognizeDoubleQuouters, _ ' ReduceDoubleQuoters, StripQMarks, EndPos) short = mid(short,EndPos) else 'take saved_the_rest_of_line SML_E_value(SML_E_i) = saved_the_rest_of_line wi = instr(short, vl) if wi = 0 then wi = len(short) + 1 short = mid(short,wi) 'to simulate end-of-line parsing; end if '---------------------------------- '------------------------------------------------------------ else '==case not long_shotrcut_control '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SML_E_long(i) = false ws = NextT 'take second token from line '=============================================== do while ws <> "" and left(ws,1) <> "'" 'parse rest of line 'starting from second token; 'comment terminates parsing; '----------------------------------------------- if ws = "m" then mark(i) = true ' tells translator to mark nesting level in comment if ws = "a" then abbr(i) = true if ws = "foreign" then foreign(i) = true if ws = "halftag" then halftag(i) = true ws = NextT loop if deb then printl "state " & i & " is " & _ element(i) & vt & " extended=" & extended(i) & vt _ & "tagable=" & tagable(i) & vt & " mark=`" & _ mark(i) & "`" & vt & _ " foreign=" & foreign(i) & vt & " halftag=" & _ halftag(i) & vt & " abbrev=" & abbr(i) end if 'long_shotrcut_control '---------------------------------------------- 'ef line parsing '=============================================== next 'copy (why?) number of long shortcuts: SML_E_L = SML_E_i 'adding real tags=brothers-elements '''''''''''''''''' 'copy tagable elements with 'changing from low-case-element-name to 'upper-caase-element-name j = i for k=1 to i-1 if tagable(k) then 'raise the case of element: element(j) = Ucase(element(k)) ' add brothers-elements with upper case (tags) extended(j) = extended(k) ' keep property of parent element if deb then printl " state " & j & " is " & element(j) if j >= elim then stope "elements quantity exceeds limit =" & elim j = j + 1 end if next enumb = j - 1 '-minus one. ' end adding real tags '''''''''''''''''' ' make the rest element empty '''''''''''''''''' for k=j to enumb element(k) = "" next '------------------------------------------------------------------------------------- ' ef S T A T E S L I S T '===================================================================================== 'find state indices: icommon = get_i("#common") iistart = get_i("#start") ibody = get_i("body") '''''''' ELEMENT NOT LONG SHORTCUTS ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' shortcuts for elements/states ' NextB stands for Next Block NextB : if deb then printl vbcrlf & ThisL do NextL if ThisT = "" then exit do ' seems empty string terminates this block; ws = ThisT ' this is a control char; no, now all shortcut; wii = get_i(lcase(NextT)) ' scope wi = get_i(lcase(NextT)) ' index of shortcut(ted) element if wi = 0 or wii = 0 then stope "script needs work: element or " & _ "scope in string (" & i & ") `" & _ ThisL & "` is not found" end if k = asc(left(ws,1)) ' SML_E: now, it can be longer than one ... if k > 127 then stope "shortcut control char code > 127 ... " tar(k,wii) = wi ' tar(control, scope) = target 'wis:? any_scut(wi) = ws if deb then printl "Element `" & element(wi) & "` " & vt & " has a shortcut `" & chr(k) & "`" & vt & " in scope `" & element(wii) & "` " loop '''''''' END ELEMENT SHORTCUTS ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '====================================================================================================== ' PARCUTE PARSING ' format of line: parcut value type child; ' comma separates skipped token. '====================================================================================================== do '=1 taggroups loop NextB : if deb then printl vbcrlf & vbcrlf & _ "next block (taggroup-tagcuts) is starting ... " NextL ' this line must be a header start 'hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh do while ThisT <> "" '=2 elements in header loop 'header can have many elements 'for each element the same parcuts must be set. '=================================================================================================== s = ThisT ' must be current element in the header list j=get_i(s) ' j is element (actually index) if j=0 then _ stope "index of element `" & s & _ "` shortcut is not found; this " & _ "shortcut may not listed above in schema ... " short2 = short ' memorize source from the current element ' in the header list. i = instr(short, "\\tagcuts") '''''''''''''''''''''''''''' 'find parcuts (= shortcuts for parameters of the element); short = mid(short,i) 'get closer to parcuts; NextL 'next line gives the first parcut; if deb then printl ve & _ "element(" & j & ")=" & _ element(j) & "; about to add partcuts to it ... " 'assign tagcuts; 'find a position to fill out ... if deb then printl "looking for the first free position k in array for parcuts ... " for k = 1 to tlim if deb then printl "" & k & " occupied by `" & sub_el_cut(j,k) & "`" if sub_el_cut(j,k) = "" then exit for next 'LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL ' LOOP VIA LINES IN TAGCUTS(PARCUTS) BLOCK '====================================================================================== if deb then printl k & " - is a first free position; adding ... " do while ThisT <> "" '=4 ' collect parcuts wwwtemp1 = ThisT sub_el_cut(j,k) = wwwtemp1 ' must be optimized or indexed ... ' this is a shortcut like for `size= ..` wi = len(wwwtemp1) short = mid(short,wi+1) wwwtemp1 = short wwwtemp2 = NextT short = wwwtemp1 ' end of use wwwtemp1 if left(wwwtemp2,1) = "`" then ' second token is a string ` .... ` ' this is an entire string in "`" marks; take it wwwtempi = instr(short,"`") wi = instr(wwwtempi+1,short,"`") if wi = 0 then stope "no termination char ` for tag element ... stopping ... " subelement(j,k) = mid(short,wwwtempi+1,wi-wwwtempi-1) short=mid(short,wi) else subelement(j,k) = NextT if ThisT = "," then subelement(j,k) = "" end if subeltype(j,k)= NextT ' 0 - numbers, 1,2,3, 9 - string length if ThisT = "," then subeltype(j,k) = "" ws = NextT if ThisT = "," then ws = "" 'for child-elements: enext(j,k) = get_i(lcase(ws)) ' transform state to the next if ' this shortcut is inside the tag NextL if deb then printl sub_el_cut(j,k) & vt & subelement(j,k) & vt & _ subeltype(j,k) & vt & enext(j,k) k = k + 1 if k > tlim then exit do '====================================================================================== loop '=4 ef IN PARCUTS BLOCK 'LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL short3 = short 'poorily done short = short2 NextL 'header list must be tailored by empty line; 'otherwise, elements and parcuts will stick together ... '=================================================================================================== loop ' =2 loop vial elements in taggroup (header) 'hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh short = short3 ' poorily done; '===================================================================================================== ' LOOP VIA ALL TAGGROUPS IN SCHEMA: loop while instr(short, "\\taggroup") > 0 ' no need for special termination token 'mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm end sub '============================================= ' quits if beh missed ' if not missed eoh is required ' INPUT: ' hso - header source ' start - whe beo must be ' take_defaults - accept defaults ' before anything found ' '--------------------------------------------- function parse_s_ml_header( _ start,hso,take_defaults) dim i,j,k,wi,s const beh = "\\short-ml" const eoh = "\\end of header" if take_defaults then xescape = "\" xself = "." xtend = "." 'marks end of parcuts tag_div = "," 'substitutor for space in tag if IndentFlag = "" then 'default value: IndentFlag = ve & " " end if end if i = instr(start,hso,beh) if i <> start then 'no header is found: 'this sets start of 'schema and retursn it parse_s_ml_header = start exit function end if k = instr(start,hso, vl & eoh) if k=0 then stope "Missed " & eoh & "." k = instr(k,hso,ve) if k=0 then stope "Header must end with CRLF." 'return next position after the header: parse_s_ml_header = k+2 'find escaper: k = instr(start,hso, vl & "escaper=") if k > 0 then xescape=mid(hso,k+9,1) if deb then printl "escaper=`" & xescape & "`" end if 'find xself k = instr(start,hso,vl & "escapee=") if k > 0 then xself =mid(hso,k+9,1) if deb then printl "escapee=`" & xself & "`" end if 'find "parsend" k = instr(start,hso,vl & "tag end=") if k > 0 then xtend =mid(hso,k+8,1) if deb then printl "parcuts end = `" & xself & "`" end if k = instr(start,hso,vl & "indent=") if k > 0 then wi = instr(k+1,hso,vl) IndentFlag = replace(mid(hso,k+8,wi-k-8), vr, "") if IndentFlag <> "" then IndentFlag = ve & IndentFlag end if end if if deb then printl "Indent=`" & IndentFlag & "`" '--------------------------------------------- end function 'parse_s_ml_header '============================================= %>