/* построение описания блока УДК в промежуточном линейном XML-формате */ main(X) :- prefix := ""+X, table := newHash(), f := newFileReader("lns"+X+".txt"), lines := newVector([]), step(readLine(^f)), output := newFileWriter("ql"+X+".xml"), write(^output, ""), write(^output, ""), putLines(0), write(^output, ""), close(^output) ; step(null) :- !, []; step(Str) :- write("."), evalString(Str), step(readLine(^f)) ; checkCode(Vect, -1) :- !, true; checkCode(Vect, Ind) :- check(vGet(Vect, Ind)), checkCode(Vect, Ind-1); check(X) :- X>=45, X<=57; /* evalString классифицирует элементы УДК, добавляя классифицированные элементы в вектор lines */ evalString(Str) :- ( startsWith(Str, "->", 0), !, Str1 = subString(Str, 2, sLength(Str)), vAdd(^lines, [reference1, sTrim(Str1)]) ## sIndexOf(Str, "->") >= 0, wrap(Str, "->", Fst, Snd), vAdd(^lines, [reference2, sTrim(Fst), sTrim(Snd)]) ), !; evalString(Str) :- startsWith(Str, ^prefix, 0), !, ( sIndexOf(Str, " ") = -1, !, vAdd(^lines, [lonely, Str]) ## sIndexOf(Str, "$=") >> 0, !, wrap(Str, "$=", Fst, Snd), vAdd(^lines, [equals, sTrim(Fst), sTrim(Snd)]) ## wrap(Str, " ", Fst, Snd), ( V = sToU(Fst), checkCode(V, vLength(V)-1), !, vAdd(^lines, [standard, Fst, Snd]) ## true ) ## true ), !; evalString(Str) :- startsWith(Str, "Искл", 0), !, vAdd(^lines, [depricated, Str]) ; evalString(Str) :- /* write(Str), */ true; putLines(null) :- !, null; putLines(N) :- N >= vLength(^lines), !, close(^output), null; putLines(N) :- El = vGet(^lines, N), /* checkInTable(El), */ ( El = [standard, Str1, Str2], !, Res = putStandard(Str1, Str2, N+1) ## El = [lonely, Str], !, Res = putStandard(Str, "", N+1) ## El = [equals, Str1, Str2], !, Res = putStandard(Str1, "$= "+Str2, N+1) ), !, putLines(Res) ; putLines(N) :- El = vGet(^lines, N), write(El), write("???"+nl()), putLines(N+1) ; putStandard(Code, Descr, N) :- Refs = newVector([]), ( N << vLength(^lines), vGet(^lines, N) = [depricated, Str], Status = "depricated", vAdd(Refs, _Str;), N1 = N+1 ## Status = "valid", N1 = N ), N2 = putRefs(Refs, N1), putItem(Status, Code, Descr, Refs), N2 ; putItem(Status, Code, Descr, Refs) :- Item = _Code; _Code+" "+Descr; _Descr; _Refs; , write(^output, Item), write(^output, nl()), fail ; putItem(_, _, _, _) :- true ; putRefs(_, N) :- N >= vLength(^lines), !, null ; putRefs(Vector, N) :- El = vGet(^lines, N), ( El = [reference1, Str], !, vAdd(Vector, _"см. "+Str;) ## El = [reference2, Str1, Str2], !, vAdd(Vector, _Str1+" см. "+Str2;) ), putRefs(Vector, N+1) ; putRefs(_, N) :- N ; /* записывает построчно в файл вместе со квалификаторами */ writeLines(F, N) :- N = vLength(^lines), !, close(F); writeLines(F, N) :- El = vGet(^lines, N), ( El = [reference1, Str], !, write(F, "r1 "+Str+nl()) ## El = [reference2, Str1, Str2], !, write(F, "r2 "+Str1+"///"+Str2+nl()) ## El = [lonely, Str], !, write(F, "ln "+Str+nl()) ## El = [depricated, Str], !, write(F, "dp "+Str+nl()) ## El = [standard, Str1, Str2], !, write(F, "st "+Str1+"///"+Str2+nl()) ## El = [equals, Str1, Str2], !, write(F, "eq "+Str1+"///"+Str2+nl()) ), writeLines(F, N+1); /* общая функция, находит первое вхождение подстроки Ch в строку Str и разрезает строку по этому символу. Первая часть - в аргументе First вторая часть - результат функции */ wrap(Str, Ch, First, RestStr) :- Ix = sIndexOf(Str, Ch), First = sNorm(subString(Str, 0, Ix)), RestStr = subString(Str, Ix+sLength(Ch), sLength(Str)), RestStr ; /* то же, что и wrap, но отрезает пробелы с концов */ wrapNorm(Str, Ch, First) :- Rest = wrap(Str, Ch, F), First=sTrim(F), Rest; checkInTable([standard, Str| _]) :- !, hGet(^table, Str) = null, hPut(^table, Str, Str) ; checkInTable(X) :- true; t(X) :- trace("level", X);