Files
whitakers-words/parse.adb
2012-05-31 16:45:42 -05:00

1193 lines
45 KiB
Ada

with TEXT_IO;
with STRINGS_PACKAGE; use STRINGS_PACKAGE;
with LATIN_FILE_NAMES; use LATIN_FILE_NAMES;
with WORD_PARAMETERS; use WORD_PARAMETERS;
with DEVELOPER_PARAMETERS; use DEVELOPER_PARAMETERS;
with INFLECTIONS_PACKAGE; use INFLECTIONS_PACKAGE;
with DICTIONARY_PACKAGE; use DICTIONARY_PACKAGE;
with ADDONS_PACKAGE; use ADDONS_PACKAGE;
with WORD_SUPPORT_PACKAGE; use WORD_SUPPORT_PACKAGE;
with PREFACE;
with WORD_PACKAGE; use WORD_PACKAGE;
with LIST_PACKAGE; use LIST_PACKAGE;
with TRICKS_PACKAGE; use TRICKS_PACKAGE;
with CONFIG; use CONFIG;
with PREFACE;
with PUT_STAT;
with ENGLISH_SUPPORT_PACKAGE; use ENGLISH_SUPPORT_PACKAGE;
with SEARCH_ENGLISH;
pragma Elaborate(WORD_PARAMETERS);
procedure PARSE(COMMAND_LINE : STRING := "") is
use INFLECTIONS_PACKAGE.INTEGER_IO;
use INFLECTION_RECORD_IO;
use TEXT_IO;
STORAGE_ERROR_COUNT : INTEGER := 0;
J, K, L : INTEGER := 0;
LINE, BLANK_LINE : STRING(1..2500) := (others => ' ');
--INPUT : TEXT_IO.FILE_TYPE;
PA : PARSE_ARRAY(1..100) := (others => NULL_PARSE_RECORD);
SYNCOPE_MAX : constant := 20;
NO_SYNCOPE : BOOLEAN := FALSE;
TRICKS_MAX : constant := 40;
SYPA : PARSE_ARRAY(1..SYNCOPE_MAX) := (others => NULL_PARSE_RECORD);
TRPA : PARSE_ARRAY(1..TRICKS_MAX) := (others => NULL_PARSE_RECORD);
PA_LAST, SYPA_LAST, TRPA_LAST : INTEGER := 0;
procedure PARSE_LINE(INPUT_LINE : STRING) is
L : INTEGER := TRIM(INPUT_LINE)'LAST;
--LINE : STRING(1..2500) := (others => ' ');
W : STRING(1..L) := (others => ' ');
begin
WORD_NUMBER := 0;
LINE(1..L) := TRIM(INPUT_LINE);
-- Someday I ought to be interested in punctuation and numbers, but not now
ELIMINATE_NOT_LETTERS:
begin
for I in 1..L loop
if ((LINE(I) in 'A'..'Z') or
(LINE(I) = '-') or -- For the comment
(LINE(I) = '.') or -- Catch period later
(LINE(I) in 'a'..'z')) then
null;
else
LINE(I) := ' ';
end if;
end loop;
end ELIMINATE_NOT_LETTERS;
J := 1;
K := 0;
OVER_LINE:
while J <= L loop
-- Skip over leading and intervening blanks, looking for comments
-- Punctuation, numbers, and special characters were cleared above
for I in K+1..L loop
exit when LINE(J) in 'A'..'Z';
exit when LINE(J) in 'a'..'z';
if I < L and then
LINE(I..I+1) = "--" then
exit OVER_LINE; -- the rest of the line is comment
end if;
J := I + 1;
end loop;
exit when J > L; -- Kludge
FOLLOWS_PERIOD := FALSE;
if FOLLOWED_BY_PERIOD then
FOLLOWED_BY_PERIOD := FALSE;
FOLLOWS_PERIOD := TRUE;
end if;
CAPITALIZED := FALSE;
ALL_CAPS := FALSE;
-- Extract the word
for I in J..L loop
-- Although I have removed punctuation above, it may not always be so
if LINE(I) = '.' then
FOLLOWED_BY_PERIOD := TRUE;
exit;
end if;
-- exit when (LINE(I) = ' ' or LINE(I) = ',' or LINE(I) = '-'
-- or LINE(I) = ';' or LINE(I) = ':'
-- or LINE(I) = '(' or LINE(I) = '[' or LINE(I) = '{' or LINE(I) = '<'
-- or LINE(I) = ')' or LINE(I) = ']' or LINE(I) = '}' or LINE(I) = '>'
-- or (CHARACTER'POS(LINE(I)) < 32) or (CHARACTER'POS(LINE(I)) > 127) );
exit when ((LINE(I) not in 'A'..'Z') and (LINE(I) not in 'a'..'z'));
W(I) := LINE(I);
K := I;
end loop;
if W(J) in 'A'..'Z' and then
K - J >= 1 and then
W(J+1) in 'a'..'z' then
CAPITALIZED := TRUE;
end if;
ALL_CAPS := TRUE;
for I in J..K loop
if W(I) = LOWER_CASE(W(I)) then
ALL_CAPS := FALSE;
exit;
end if;
end loop;
for I in J..K-1 loop -- Kludge for QVAE
if W(I) = 'Q' and then W(I+1) = 'V' then
W(I+1) := 'U';
end if;
end loop;
if LANGUAGE = ENGLISH_TO_LATIN then
PARSE_LINE_ENGLISH_TO_LATIN:
-- Since we do only one English word per line
declare
INPUT_WORD : constant STRING := W(J..K);
POFS : PART_OF_SPEECH_TYPE := X;
begin
-- Extract from the rest of the line
-- Should do AUX here !!!!!!!!!!!!!!!!!!!!!!!!
EXTRACT_POFS:
begin
PART_OF_SPEECH_TYPE_IO.GET(LINE(K+1..L), POFS, L);
--TEXT_IO.PUT_LINE("In EXTRACT " & LINE(K+1..L));
exception
when others =>
POFS := X;
end EXTRACT_POFS;
--PART_OF_SPEECH_TYPE_IO.PUT(POFS);
--TEXT_IO.NEW_LINE;
SEARCH_ENGLISH(INPUT_WORD, POFS);
exit OVER_LINE;
end PARSE_LINE_ENGLISH_TO_LATIN;
elsif LANGUAGE = LATIN_TO_ENGLISH then
PARSE_WORD_LATIN_TO_ENGLISH:
declare
INPUT_WORD : constant STRING := W(J..K);
ENTERING_PA_LAST : INTEGER := 0;
ENTERING_TRPA_LAST : INTEGER := 0;
HAVE_DONE_ENCLITIC : BOOLEAN := FALSE;
procedure PASS(INPUT_WORD : STRING);
procedure ENCLITIC is
SAVE_DO_FIXES : BOOLEAN := WORDS_MODE(DO_FIXES);
SAVE_DO_ONLY_FIXES : BOOLEAN := WORDS_MDEV(DO_ONLY_FIXES);
ENCLITIC_LIMIT : INTEGER := 4;
TRY : constant STRING := LOWER_CASE(INPUT_WORD);
begin
--TEXT_IO.PUT_LINE("Entering ENCLITIC HAVE DONE = " & BOOLEAN'IMAGE(HAVE_DONE_ENCLITIC));
--if WORDS_MODE(TRIM_OUTPUT) and (PA_LAST > 0) then return; end if;
if HAVE_DONE_ENCLITIC then return; end if;
ENTERING_PA_LAST := PA_LAST;
if PA_LAST > 0 then ENCLITIC_LIMIT := 1; end if;
LOOP_OVER_ENCLITIC_TACKONS:
for I in 1..ENCLITIC_LIMIT loop -- If have parse, only do que of que, ne, ve, (est)
REMOVE_A_TACKON:
declare
LESS : constant STRING :=
SUBTRACT_TACKON(TRY, TACKONS(I));
--SUBTRACT_TACKON(INPUT_WORD, TACKONS(I));
SAVE_PA_LAST : INTEGER := 0;
begin
--TEXT_IO.PUT_LINE("In ENCLITIC LESS/TACKON = " & LESS & "/" & TACKONS(I).TACK);
if LESS /= TRY then -- LESS is less
--WORDS_MODE(DO_FIXES) := FALSE;
WORD_PACKAGE.WORD(LESS, PA, PA_LAST);
--TEXT_IO.PUT_LINE("In ENCLITICS after WORD NO_FIXES LESS = " & LESS & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
if PA_LAST = 0 then
SAVE_PA_LAST := PA_LAST;
TRY_SLURY(LESS, PA, PA_LAST, LINE_NUMBER, WORD_NUMBER);
if SAVE_PA_LAST /= 0 then
if (PA_LAST - 1) - SAVE_PA_LAST = SAVE_PA_LAST then
PA_LAST := SAVE_PA_LAST;
end if;
end if;
end if;
-- Do not SYNCOPE if there is a verb TO_BE or compound already there
-- I do this here and below, it might be combined but it workd now
for I in 1..PA_LAST loop
--PARSE_RECORD_IO.PUT(PA(I)); TEXT_IO.NEW_LINE;
if PA(I).IR.QUAL.POFS = V and then
PA(I).IR.QUAL.V.CON = (5, 1) then
NO_SYNCOPE := TRUE;
end if;
end loop;
--TEXT_IO.PUT_LINE("In ENCLITICS after SLURY LESS = " & LESS & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
SYPA_LAST := 0;
if WORDS_MDEV(DO_SYNCOPE) and not NO_SYNCOPE then
SYNCOPE(LESS, SYPA, SYPA_LAST); -- Want SYNCOPE second to make cleaner LIST
--TEXT_IO.PUT_LINE("In ENCLITIC after SYNCOPE LESS = " & LESS & " SYPA_LAST = " & INTEGER'IMAGE(SYPA_LAST));
PA_LAST := PA_LAST + SYPA_LAST; -- Make syncope another array to avoid PA_LAST = 0 problems
PA(1..PA_LAST) := PA(1..PA_LAST-SYPA_LAST) & SYPA(1..SYPA_LAST); -- Add SYPA to PA
SYPA(1..SYNCOPE_MAX) := (1..SYNCOPE_MAX => NULL_PARSE_RECORD); -- Clean up so it does not repeat
SYPA_LAST := 0;
end if;
NO_SYNCOPE := FALSE;
-- Restore FIXES
--WORDS_MODE(DO_FIXES) := SAVE_DO_FIXES;
WORDS_MDEV(DO_ONLY_FIXES) := TRUE;
WORD(INPUT_WORD, PA, PA_LAST);
--TEXT_IO.PUT_LINE("In ENCLITICS after ONLY_FIXES LESS = " & LESS & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
WORDS_MDEV(DO_ONLY_FIXES) := SAVE_DO_ONLY_FIXES;
if PA_LAST > ENTERING_PA_LAST then -- have a possible word
PA_LAST := PA_LAST + 1;
PA(ENTERING_PA_LAST+2..PA_LAST) :=
PA(ENTERING_PA_LAST+1..PA_LAST-1);
PA(ENTERING_PA_LAST+1) := (TACKONS(I).TACK,
((TACKON, NULL_TACKON_RECORD), 0, NULL_ENDING_RECORD, X, X),
ADDONS, DICT_IO.COUNT(TACKONS(I).MNPC));
HAVE_DONE_ENCLITIC := TRUE;
end if;
exit LOOP_OVER_ENCLITIC_TACKONS;
end if;
end REMOVE_A_TACKON;
end loop LOOP_OVER_ENCLITIC_TACKONS;
end ENCLITIC;
procedure TRICKS_ENCLITIC is
TRY : constant STRING := LOWER_CASE(INPUT_WORD);
begin
--TEXT_IO.PUT_LINE("Entering TRICKS_ENCLITIC PA_LAST = " & INTEGER'IMAGE(PA_LAST));
--if WORDS_MODE(TRIM_OUTPUT) and (PA_LAST > 0) then return; end if;
if HAVE_DONE_ENCLITIC then return; end if;
ENTERING_TRPA_LAST := TRPA_LAST;
LOOP_OVER_ENCLITIC_TACKONS:
for I in 1..4 loop -- que, ne, ve, (est)
REMOVE_A_TACKON:
declare
LESS : constant STRING :=
--SUBTRACT_TACKON(LOWER_CASE(INPUT_WORD), TACKONS(I));
SUBTRACT_TACKON(TRY, TACKONS(I));
begin
--TEXT_IO.PUT_LINE("In TRICKS_ENCLITIC LESS/TACKON = " & LESS & "/" & TACKONS(I).TACK);
if LESS /= TRY then -- LESS is less
--PASS(LESS);
TRY_TRICKS(LESS, TRPA, TRPA_LAST, LINE_NUMBER, WORD_NUMBER);
--TEXT_IO.PUT_LINE("In TRICKS_ENCLITICS after TRY_TRICKS LESS = " & LESS & " TRPA_LAST = " & INTEGER'IMAGE(TRPA_LAST));
if TRPA_LAST > ENTERING_TRPA_LAST then -- have a possible word
TRPA_LAST := TRPA_LAST + 1;
TRPA(ENTERING_TRPA_LAST+2..trPA_LAST) :=
TRPA(ENTERING_TRPA_LAST+1..TRPA_LAST-1);
TRPA(ENTERING_TRPA_LAST+1) := (TACKONS(I).TACK,
((TACKON, NULL_TACKON_RECORD), 0, NULL_ENDING_RECORD, X, X),
ADDONS, DICT_IO.COUNT(TACKONS(I).MNPC));
end if;
exit LOOP_OVER_ENCLITIC_TACKONS;
end if;
end REMOVE_A_TACKON;
end loop LOOP_OVER_ENCLITIC_TACKONS;
end TRICKS_ENCLITIC;
procedure PASS(INPUT_WORD : STRING) is
-- This is the core logic of the program, everything else is details
SAVE_PA_LAST : INTEGER := 0;
SAVE_DO_FIXES : BOOLEAN := WORDS_MODE(DO_FIXES);
SAVE_DO_ONLY_FIXES : BOOLEAN := WORDS_MDEV(DO_ONLY_FIXES);
SAVE_DO_TRICKS : BOOLEAN := WORDS_MODE(DO_TRICKS);
begin
--TEXT_IO.PUT_LINE("Entering PASS with >" & INPUT_WORD);
-- Do straight WORDS without FIXES/TRICKS, is the word in the dictionary
WORDS_MODE(DO_FIXES) := FALSE;
ROMAN_NUMERALS(INPUT_WORD, PA, PA_LAST);
WORD(INPUT_WORD, PA, PA_LAST);
--TEXT_IO.PUT_LINE("SLURY- PA_LAST = " & INTEGER'IMAGE(PA_LAST));
--for JK in 1..PA_LAST loop
-- f PARSE_RECORD_IO.PUT(PA(JK)); TEXT_IO.NEW_LINE;
--end loop;
if PA_LAST = 0 then
TRY_SLURY(INPUT_WORD, PA, PA_LAST, LINE_NUMBER, WORD_NUMBER);
end if;
-- Do not SYNCOPE if there is a verb TO_BE or compound already there
for I in 1..PA_LAST loop
--PARSE_RECORD_IO.PUT(PA(I)); TEXT_IO.NEW_LINE;
if PA(I).IR.QUAL.POFS = V and then
PA(I).IR.QUAL.V.CON = (5, 1) then
NO_SYNCOPE := TRUE;
end if;
end loop;
-- -- WITH THE DICTIONARY BETTER, LET US FORGET THIS - a and c DONE, e and i STILL BUT NOT MANY
-- SAVE_PA_LAST := PA_LAST;
-- -- BIG PROBLEM HERE
-- -- If I do SLURY everytime, then each case where there is an aps- and abs- in dictionary
-- -- will show up twice, straight and SLURY, in the ourout - For either input
-- -- But if I only do SLURY if there is no hit, then some incomplete pairs will not
-- -- fully express (illuxit has two entries, inluxit has only one of them) (inritas)
-- -- So I will do SLURY and if it produces only 2 more PR (XXX and GEN), kill it, otherwise use it only
-- -- Still have a problem if there are other intervening results, not slurried.
-- -- Or if there is syncope
-- TRY_SLURY(INPUT_WORD, PA, PA_LAST, LINE_NUMBER, WORD_NUMBER);
----TEXT_IO.PUT_LINE("SLURY+ PA_LAST = " & INTEGER'IMAGE(PA_LAST));
-- if SAVE_PA_LAST /= 0 then
-- if (PA_LAST - 2) = SAVE_PA_LAST then
-- PA_LAST := SAVE_PA_LAST;
-- XXX_MEANING := NULL_MEANING_TYPE;
----TEXT_IO.PUT_LINE("SLURY! PA_LAST = " & INTEGER'IMAGE(PA_LAST));
-- end if;
-- end if;
----TEXT_IO.PUT_LINE("1 PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
-- Pure SYNCOPE
SYPA_LAST := 0;
if WORDS_MDEV(DO_SYNCOPE) and not NO_SYNCOPE then
SYNCOPE(INPUT_WORD, SYPA, SYPA_LAST);
PA_LAST := PA_LAST + SYPA_LAST; -- Make syncope another array to avoid PA-LAST = 0 problems
PA(1..PA_LAST) := PA(1..PA_LAST-SYPA_LAST) & SYPA(1..SYPA_LAST); -- Add SYPA to PA
SYPA(1..SYNCOPE_MAX) := (1..SYNCOPE_MAX => NULL_PARSE_RECORD); -- Clean up so it does not repeat
SYPA_LAST := 0;
end if;
NO_SYNCOPE := FALSE;
--TEXT_IO.PUT_LINE("2 PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
-- There may be a vaild simple parse, if so it is most probable
-- But I have to allow for the possibility that -que is answer, not colloque V
ENCLITIC;
-- Restore FIXES
WORDS_MODE(DO_FIXES) := SAVE_DO_FIXES;
--TEXT_IO.PUT_LINE("3 PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
-- Now with only fixes
if PA_LAST = 0 and then
WORDS_MODE(DO_FIXES) then
WORDS_MDEV(DO_ONLY_FIXES) := TRUE;
--TEXT_IO.PUT_LINE("3a PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
WORD(INPUT_WORD, PA, PA_LAST);
--TEXT_IO.PUT_LINE("3b PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
SYPA_LAST := 0;
if WORDS_MDEV(DO_SYNCOPE) and not NO_SYNCOPE then
SYNCOPE(INPUT_WORD, SYPA, SYPA_LAST);
--TEXT_IO.PUT_LINE("3c PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
PA_LAST := PA_LAST + SYPA_LAST; -- Make syncope another array to avoid PA-LAST = 0 problems
PA(1..PA_LAST) := PA(1..PA_LAST-SYPA_LAST) & SYPA(1..SYPA_LAST); -- Add SYPA to PA
SYPA(1..SYNCOPE_MAX) := (1..SYNCOPE_MAX => NULL_PARSE_RECORD); -- Clean up so it does not repeat
SYPA_LAST := 0;
end if;
NO_SYNCOPE := FALSE;
--TEXT_IO.PUT_LINE("4 PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
ENCLITIC;
--TEXT_IO.PUT_LINE("5 PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
WORDS_MDEV(DO_ONLY_FIXES) := SAVE_DO_ONLY_FIXES;
end if;
--TEXT_IO.PUT_LINE("6 PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
-- ROMAN_NUMERALS(INPUT_WORD, PA, PA_LAST);
-- If Pure WORDS and ENCLITICS found something OK, otherwise proceed
-- if PA_LAST = 0 or -- If no go, try syncope, fixes
-- (not WORDS_MODE(TRIM_OUTPUT)) or
-- WORDS_MDEV(DO_FIXES_ANYWAY) then
--
--
-- -- If SYNCOPE does it, then OK, otherwise proceed
-- -- Do not try FIXES (aud+i+i) on audii since SYNCOPE worked
-- -- Now try FIXES
-- if PA_LAST = 0 or (not WORDS_MODE(TRIM_OUTPUT)) or
-- WORDS_MDEV(DO_FIXES_ANYWAY) then
-- --TRY_SLURY(INPUT_WORD, PA, PA_LAST, LINE_NUMBER, WORD_NUMBER);
-- if PA_LAST = 0 then
-- WORD(INPUT_WORD, PA, PA_LAST);
-- SYPA_LAST := 0;
-- -- SYNCOPE after TRICK
-- SYNCOPE(INPUT_WORD, SYPA, SYPA_LAST); -- Want SYNCOPE second to make cleaner LIST
-- end if;
-- end if;
-- PA_LAST := PA_LAST + SYPA_LAST; -- Make syncope another array to avoid PA_LAST = 0 problems
-- PA(1..PA_LAST) := PA(1..PA_LAST-SYPA_LAST) & SYPA(1..SYPA_LAST); -- Add SYPA to PA
-- SYPA(1..SYNCOPE_MAX) := (1..SYNCOPE_MAX => NULL_PARSE_RECORD); -- Clean up so it does not repeat
-- SYPA_LAST := 0;
--
--
-- end if; -- on A_LAST = 0
end PASS;
begin -- PARSE
XXX_MEANING := NULL_MEANING_TYPE;
PASS_BLOCK:
begin
PA_LAST := 0;
WORD_NUMBER := WORD_NUMBER + 1;
PASS(INPUT_WORD);
end PASS_BLOCK;
--TEXT_IO.PUT_LINE("After PASS_BLOCK for " & INPUT_WORD & " PA_LAST = " & INTEGER'IMAGE(PA_LAST));
--if (PA_LAST = 0) or DO_TRICKS_ANYWAY then -- WORD failed, try to modify the word
if (PA_LAST = 0) and then
not (WORDS_MODE(IGNORE_UNKNOWN_NAMES) and CAPITALIZED) then
-- WORD failed, try to modify the word
--TEXT_IO.PUT_LINE("WORDS fail me");
if WORDS_MODE(DO_TRICKS) then
--TEXT_IO.PUT_LINE("DO_TRICKS PA_LAST TRPA_LAST " & INTEGER'IMAGE(PA_LAST) & " " & INTEGER'IMAGE(TRPA_LAST));
WORDS_MODE(DO_TRICKS) := FALSE; -- Turn it off so wont be circular
TRY_TRICKS(INPUT_WORD, TRPA, TRPA_LAST, LINE_NUMBER, WORD_NUMBER);
--TEXT_IO.PUT_LINE("DONE_TRICKS PA_LAST TRPA_LAST " & INTEGER'IMAGE(PA_LAST) & " " & INTEGER'IMAGE(TRPA_LAST));
if TRPA_LAST = 0 then
TRICKS_ENCLITIC;
end if;
WORDS_MODE(DO_TRICKS) := TRUE; -- Turn it back on
end if;
PA_LAST := PA_LAST + TRPA_LAST; -- Make TRICKS another array to avoid PA-LAST = 0 problems
PA(1..PA_LAST) := PA(1..PA_LAST-TRPA_LAST) & TRPA(1..TRPA_LAST); -- Add SYPA to PA
TRPA(1..TRICKS_MAX) := (1..TRICKS_MAX => NULL_PARSE_RECORD); -- Clean up so it does not repeat
TRPA_LAST := 0;
end if;
--TEXT_IO.PUT_LINE("After TRICKS " & INTEGER'IMAGE(PA_LAST));
--======================================================================
-- At this point we have done what we can with individual words
-- Now see if there is something we can do with word combinations
-- For this we have to look ahead
if PA_LAST > 0 then -- But PA may be killed by ALLOW in LIST_STEMS
if WORDS_MODE(DO_COMPOUNDS) and
not (CONFIGURATION = ONLY_MEANINGS) then
COMPOUNDS_WITH_SUM:
declare
NW : STRING(1..2500) := (others => ' ');
NK : INTEGER := 0;
COMPOUND_TENSE : INFLECTIONS_PACKAGE.TENSE_TYPE := X;
COMPOUND_TVM : INFLECTIONS_PACKAGE.TENSE_VOICE_MOOD_RECORD;
PPL_ON : BOOLEAN := FALSE;
SUM_INFO : VERB_RECORD := ((5, 1),
(X, ACTIVE, X),
0,
X);
-- ESSE_INFO : VERB_RECORD := ((5, 1),
-- (PRES, ACTIVE, INF),
-- 0,
-- X);
PPL_INFO : VPAR_RECORD := ((0, 0),
X,
X,
X,
(X, X, X));
SUPINE_INFO : SUPINE_RECORD := ((0, 0),
X,
X,
X);
procedure LOOK_AHEAD is
J : INTEGER := 0;
begin
for I in K+2..L loop
-- Although I have removed punctuation above, it may not always be so
exit when (LINE(I) = ' ' or LINE(I) = ',' or LINE(I) = '-'
or LINE(I) = ';' or LINE(I) = ':' or LINE(I) = '.'
or LINE(I) = '(' or LINE(I) = '[' or LINE(I) = '{' or LINE(I) = '<'
or LINE(I) = ')' or LINE(I) = ']' or LINE(I) = '}' or LINE(I) = '>');
J := J + 1;
NW(J) := LINE(I);
NK := I;
end loop;
end LOOK_AHEAD;
function NEXT_WORD return STRING is
begin
return TRIM(NW);
end NEXT_WORD;
function IS_SUM(T : STRING) return BOOLEAN is
SA : constant array (MOOD_TYPE range IND..SUB,
TENSE_TYPE range PRES..FUTP,
NUMBER_TYPE range S..P,
PERSON_TYPE range 1..3)
of STRING(1..9) :=
(
( -- IND
(("sum ", "es ", "est "), ("sumus ", "estis ", "sunt ")),
(("eram ", "eras ", "erat "), ("eramus ", "eratis ", "erant ")),
(("ero ", "eris ", "erit "), ("erimus ", "eritis ", "erunt ")),
(("fui ", "fuisti ", "fuit "), ("fuimus ", "fuistis ", "fuerunt ")),
(("fueram ", "fueras ", "fuerat "), ("fueramus ", "fueratis ", "fuerant ")),
(("fuero ", "fueris ", "fuerit "), ("fuerimus ", "fueritis ", "fuerunt "))
),
( -- SUB
(("sim ", "sis ", "sit "), ("simus ", "sitis ", "sint ")),
(("essem ", "esses ", "esset "), ("essemus ", "essetis ", "essent ")),
(("zzz ", "zzz ", "zzz "), ("zzz ", "zzz ", "zzz ")),
(("fuerim ", "fueris ", "fuerit "), ("fuerimus ", "fueritis ", "fuerint ")),
(("fuissem ", "fuisses ", "fuisset "), ("fuissemus", "fuissetis", "fuissent ")),
(("zzz ", "zzz ", "zzz "), ("zzz ", "zzz ", "zzz "))
)
);
begin
if T = "" then
return FALSE;
elsif T(T'FIRST) /= 's' and
T(T'FIRST) /= 'e' and
T(T'FIRST) /= 'f' then
return FALSE;
end if;
for L in MOOD_TYPE range IND..SUB loop
for K in TENSE_TYPE range PRES..FUTP loop
for J in NUMBER_TYPE range S..P loop
for I in PERSON_TYPE range 1..3 loop
if TRIM(T) = TRIM(SA(L, K, J, I)) then
SUM_INFO := ((5, 1), (K, ACTIVE, L), I, J);
return TRUE; -- Only one of the forms can agree
end if;
end loop;
end loop;
end loop;
end loop;
return FALSE;
end IS_SUM;
function IS_ESSE(T : STRING) return BOOLEAN is
begin
return TRIM(T) = "esse";
end IS_ESSE;
function IS_FUISSE(T : STRING) return BOOLEAN is
begin
return TRIM(T) = "fuisse";
end IS_FUISSE;
function IS_IRI(T : STRING) return BOOLEAN is
begin
return TRIM(T) = "iri";
end IS_IRI;
begin
-- Look ahead for sum
LOOK_AHEAD;
if IS_SUM(NEXT_WORD) then -- On NEXT_WORD = sum, esse, iri
for I in 1..PA_LAST loop -- Check for PPL
if PA(I).IR.QUAL.POFS = VPAR and then
PA(I).IR.QUAL.VPAR.CS = NOM and then
PA(I).IR.QUAL.VPAR.NUMBER = SUM_INFO.NUMBER and then
( (PA(I).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (PERF, PASSIVE, PPL)) or
(PA(I).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, ACTIVE, PPL)) or
(PA(I).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, PASSIVE, PPL)) ) then
-- There is at least one hit, fix PA, and advance J over the sum
K := NK;
end if;
end loop;
if K = NK then -- There was a PPL hit
CLEAR_PAS_NOM_PPL:
declare
J : INTEGER := PA_LAST;
begin
while J >= 1 loop -- Sweep backwards to kill empty suffixes
if ((PA(J).IR.QUAL.POFS = PREFIX) and then (PPL_ON)) then
null;
elsif ((PA(J).IR.QUAL.POFS = SUFFIX) and then (PPL_ON)) then
null;
elsif ((PA(J).IR.QUAL.POFS = TACKON) and then (PPL_ON)) then
null;
elsif PA(J).IR.QUAL.POFS = VPAR and then
PA(J).IR.QUAL.VPAR.CS = NOM and then
PA(J).IR.QUAL.VPAR.NUMBER = SUM_INFO.NUMBER then
if PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (PERF, PASSIVE, PPL) then
PPL_ON := TRUE;
case SUM_INFO.TENSE_VOICE_MOOD.TENSE is -- Allows PERF for sum
when PRES | PERF => COMPOUND_TENSE := PERF;
when IMPF | PLUP => COMPOUND_TENSE := PLUP;
when FUT => COMPOUND_TENSE := FUTP;
when others => COMPOUND_TENSE := X;
end case;
COMPOUND_TVM := (COMPOUND_TENSE, PASSIVE, SUM_INFO.TENSE_VOICE_MOOD.MOOD);
PPL_INFO := (PA(J).IR.QUAL.VPAR.CON, -- In this case, there is 1
PA(J).IR.QUAL.VPAR.CS, -- although several different
PA(J).IR.QUAL.VPAR.NUMBER,-- dictionary entries may fit
PA(J).IR.QUAL.VPAR.GENDER,-- all have same PPL_INFO
PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD);
PPP_MEANING :=
HEAD("PERF PASSIVE PPL + verb TO_BE => PASSIVE perfect system",
MAX_MEANING_SIZE);
elsif PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, ACTIVE, PPL) then
PPL_ON := TRUE;
COMPOUND_TENSE := SUM_INFO.TENSE_VOICE_MOOD.TENSE;
COMPOUND_TVM := (COMPOUND_TENSE, ACTIVE, SUM_INFO.TENSE_VOICE_MOOD.MOOD);
PPL_INFO := (PA(J).IR.QUAL.VPAR.CON, -- In this case, there is 1
PA(J).IR.QUAL.VPAR.CS, -- although several different
PA(J).IR.QUAL.VPAR.NUMBER,-- dictionary entries may fit
PA(J).IR.QUAL.VPAR.GENDER,-- all have same PPL_INFO
PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD);
PPP_MEANING := HEAD(
"FUT ACTIVE PPL + verb TO_BE => ACTIVE Periphrastic - about to, going to",
MAX_MEANING_SIZE);
elsif PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, PASSIVE, PPL) then
PPL_ON := TRUE;
COMPOUND_TENSE := SUM_INFO.TENSE_VOICE_MOOD.TENSE;
COMPOUND_TVM := (COMPOUND_TENSE, PASSIVE, SUM_INFO.TENSE_VOICE_MOOD.MOOD);
PPL_INFO := (PA(J).IR.QUAL.VPAR.CON, -- In this case, there is 1
PA(J).IR.QUAL.VPAR.CS, -- although several different
PA(J).IR.QUAL.VPAR.NUMBER,-- dictionary entries may fit
PA(J).IR.QUAL.VPAR.GENDER,-- all have same PPL_INFO
PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD);
PPP_MEANING := HEAD(
"FUT PASSIVE PPL + verb TO_BE => PASSIVE Periphrastic - should/ought/had to",
MAX_MEANING_SIZE);
end if;
else
PA(J..PA_LAST-1) := PA(J+1..PA_LAST);
PA_LAST := PA_LAST - 1;
PPL_ON := FALSE;
end if;
J := J - 1;
end loop;
end CLEAR_PAS_NOM_PPL;
PA_LAST := PA_LAST + 1;
PA(PA_LAST) :=
(HEAD("PPL+" & NEXT_WORD, MAX_STEM_SIZE),
((V,
(PPL_INFO.CON,
COMPOUND_TVM,
SUM_INFO.PERSON,
SUM_INFO.NUMBER)
), 0, NULL_ENDING_RECORD, X, A),
PPP, NULL_MNPC);
end if;
elsif IS_ESSE(NEXT_WORD) or IS_FUISSE(NEXT_WORD) then -- On NEXT_WORD
for I in 1..PA_LAST loop -- Check for PPL
if PA(I).IR.QUAL.POFS = VPAR and then
(((PA(I).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (PERF, PASSIVE, PPL)) and
IS_ESSE(NEXT_WORD)) or
((PA(I).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, ACTIVE, PPL)) or
(PA(I).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, PASSIVE, PPL))) ) then
-- There is at least one hit, fix PA, and advance J over the sum
K := NK;
end if;
end loop;
if K = NK then -- There was a PPL hit
CLEAR_PAS_PPL:
declare
J : INTEGER := PA_LAST;
begin
while J >= 1 loop -- Sweep backwards to kill empty suffixes
if ((PA(J).IR.QUAL.POFS = PREFIX) and then (PPL_ON)) then
null;
elsif ((PA(J).IR.QUAL.POFS = SUFFIX) and then (PPL_ON)) then
null;
elsif ((PA(J).IR.QUAL.POFS = TACKON) and then (PPL_ON)) then
null;
elsif PA(J).IR.QUAL.POFS = VPAR then
if PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (PERF, PASSIVE, PPL) then
PPL_ON := TRUE;
COMPOUND_TVM := (PERF, PASSIVE, INF);
PPL_INFO := (PA(J).IR.QUAL.VPAR.CON, -- In this case, there is 1
PA(J).IR.QUAL.VPAR.CS, -- although several different
PA(J).IR.QUAL.VPAR.NUMBER,-- dictionary entries may fit
PA(J).IR.QUAL.VPAR.GENDER,-- all have same PPL_INFO
PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD);
PPP_MEANING :=
HEAD("PERF PASSIVE PPL + esse => PERF PASSIVE INF",
MAX_MEANING_SIZE);
elsif PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, ACTIVE, PPL) then
PPL_ON := TRUE;
PPL_INFO := (PA(J).IR.QUAL.VPAR.CON, -- In this case, there is 1
PA(J).IR.QUAL.VPAR.CS, -- although several different
PA(J).IR.QUAL.VPAR.NUMBER,-- dictionary entries may fit
PA(J).IR.QUAL.VPAR.GENDER,-- all have same PPL_INFO
PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD);
if IS_ESSE(NEXT_WORD) then
COMPOUND_TVM := (FUT, ACTIVE, INF);
PPP_MEANING := HEAD(
"FUT ACTIVE PPL + esse => PRES Periphastic/FUT ACTIVE INF - be about/going to",
MAX_MEANING_SIZE);
-- also peri COMPOUND_TVM := (PRES, ACTIVE, INF);
else -- fuisse
COMPOUND_TVM := (PERF, ACTIVE, INF);
PPP_MEANING := HEAD(
"FUT ACT PPL+fuisse => PERF ACT INF Periphrastic - to have been about/going to",
MAX_MEANING_SIZE);
end if;
elsif PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD = (FUT, PASSIVE, PPL) then
PPL_ON := TRUE;
PPL_INFO := (PA(J).IR.QUAL.VPAR.CON, -- In this case, there is 1
PA(J).IR.QUAL.VPAR.CS, -- although several different
PA(J).IR.QUAL.VPAR.NUMBER,-- dictionary entries may fit
PA(J).IR.QUAL.VPAR.GENDER,-- all have same PPL_INFO
PA(J).IR.QUAL.VPAR.TENSE_VOICE_MOOD);
if IS_ESSE(NEXT_WORD) then
COMPOUND_TVM := (PRES, PASSIVE, INF);
PPP_MEANING := HEAD(
"FUT PASSIVE PPL + esse => PRES PASSIVE INF",
MAX_MEANING_SIZE);
-- also peri COMPOUND_TVM := (PRES, ACTIVE, INF);
else -- fuisse
COMPOUND_TVM := (PERF, PASSIVE, INF);
PPP_MEANING := HEAD(
"FUT PASSIVE PPL + fuisse => PERF PASSIVE INF Periphrastic - about to, going to",
MAX_MEANING_SIZE);
end if;
end if;
else
PA(J..PA_LAST-1) := PA(J+1..PA_LAST);
PA_LAST := PA_LAST - 1;
PPL_ON := FALSE;
end if;
J := J - 1;
end loop;
end CLEAR_PAS_PPL;
PA_LAST := PA_LAST + 1;
PA(PA_LAST) :=
(HEAD("PPL+" & NEXT_WORD, MAX_STEM_SIZE),
((V,
(PPL_INFO.CON,
COMPOUND_TVM,
0,
X)
), 0, NULL_ENDING_RECORD, X, A),
PPP, NULL_MNPC);
end if;
elsif IS_IRI(NEXT_WORD) then -- On NEXT_WORD = sum, esse, iri
-- Look ahead for sum
for J in 1..PA_LAST loop -- Check for SUPINE
if PA(J).IR.QUAL.POFS = SUPINE and then
PA(J).IR.QUAL.SUPINE.CS = ACC then
-- There is at least one hit, fix PA, and advance J over the iri
K := NK;
end if;
end loop;
if K = NK then -- There was a SUPINE hit
CLEAR_PAS_SUPINE:
declare
J : INTEGER := PA_LAST;
begin
while J >= 1 loop -- Sweep backwards to kill empty suffixes
if ((PA(J).IR.QUAL.POFS = PREFIX) and then (PPL_ON)) then
null;
elsif ((PA(J).IR.QUAL.POFS = SUFFIX) and then (PPL_ON)) then
null;
elsif ((PA(J).IR.QUAL.POFS = TACKON) and then (PPL_ON)) then
null;
elsif PA(J).IR.QUAL.POFS = SUPINE and then
PA(J).IR.QUAL.SUPINE.CS = ACC then
PPL_ON := TRUE;
SUPINE_INFO := (PA(J).IR.QUAL.SUPINE.CON,
PA(J).IR.QUAL.SUPINE.CS,
PA(J).IR.QUAL.SUPINE.NUMBER,
PA(J).IR.QUAL.SUPINE.GENDER);
PA_LAST := PA_LAST + 1;
PA(PA_LAST) :=
(HEAD("SUPINE + iri", MAX_STEM_SIZE),
((V,
(SUPINE_INFO.CON,
(FUT, PASSIVE, INF),
0,
X)
), 0, NULL_ENDING_RECORD, X, A),
PPP, NULL_MNPC);
PPP_MEANING := HEAD(
"SUPINE + iri => FUT PASSIVE INF - to be about/going/ready to be ~",
MAX_MEANING_SIZE);
K := NK;
else
PA(J..PA_LAST-1) := PA(J+1..PA_LAST);
PA_LAST := PA_LAST - 1;
PPL_ON := FALSE;
end if;
J := J -1;
end loop;
end CLEAR_PAS_SUPINE;
end if;
end if; -- On NEXT_WORD = sum, esse, iri
end COMPOUNDS_WITH_SUM;
end if; -- On WORDS_MODE(DO_COMPOUNDS)
--========================================================================
end if;
--TEXT_IO.PUT_LINE("Before LISTing STEMS (PA_LAST > 0 to start) PA_LAST = " &
--INTEGER'IMAGE(PA_LAST));
if WORDS_MODE(WRITE_OUTPUT_TO_FILE) then
LIST_STEMS(OUTPUT, INPUT_WORD, INPUT_LINE, PA, PA_LAST);
else
LIST_STEMS(CURRENT_OUTPUT, INPUT_WORD, INPUT_LINE, PA, PA_LAST);
end if;
--TEXT_IO.PUT_LINE("After LISTing STEMS (PA_LAST > 0 to start) PA_LAST = " &
--INTEGER'IMAGE(PA_LAST));
PA_LAST := 0;
exception
when others =>
PUT_STAT("Exception at "
& HEAD(INTEGER'IMAGE(LINE_NUMBER), 8) & HEAD(INTEGER'IMAGE(WORD_NUMBER), 4)
& " " & HEAD(INPUT_WORD, 28) & " " & INPUT_LINE);
raise;
end PARSE_WORD_LATIN_TO_ENGLISH;
end if;
----------------------------------------------------------------------
----------------------------------------------------------------------
J := K + 1; -- In case it is end of line and we don't look for ' '
exit when WORDS_MDEV(DO_ONLY_INITIAL_WORD);
end loop OVER_LINE; -- Loop on line
exception
-- Have STORAGE_ERROR check in WORD too ?????????????
when STORAGE_ERROR => -- I want to again, at least twice
if WORDS_MDEV(DO_PEARSE_CODES) then
TEXT_IO.PUT("00 ");
end if;
TEXT_IO.PUT_LINE( -- ERROR_FILE,
"STORAGE_ERROR Exception in WORDS, try again");
STORAGE_ERROR_COUNT := STORAGE_ERROR_COUNT + 1;
if STORAGE_ERROR_COUNT >= 4 then raise; end if;
PA_LAST := 0;
when GIVE_UP =>
PA_LAST := 0;
raise;
when others => -- I want to try to get on with the next line
TEXT_IO.PUT_LINE( -- ERROR_FILE,
"Exception in PARSE_LINE processing " & INPUT_LINE);
if WORDS_MODE(WRITE_UNKNOWNS_TO_FILE) then
if WORDS_MDEV(DO_PEARSE_CODES) then
TEXT_IO.PUT(UNKNOWNS, "00 ");
end if;
TEXT_IO.PUT(UNKNOWNS, INPUT_LINE(J..K));
TEXT_IO.SET_COL(UNKNOWNS, 30);
INFLECTIONS_PACKAGE.INTEGER_IO.PUT(UNKNOWNS, LINE_NUMBER, 5);
INFLECTIONS_PACKAGE.INTEGER_IO.PUT(UNKNOWNS, WORD_NUMBER, 3);
TEXT_IO.PUT_LINE(UNKNOWNS, " ======== ERROR ");
end if;
PA_LAST := 0;
end PARSE_LINE;
--procedure CHANGE_LANGUAGE(C : CHARACTER) is
--begin
-- if UPPER_CASE(C) = 'L' then
-- LANGUAGE := LATIN_TO_ENGLISH;
-- PREFACE.PUT_LINE("Language changed to " & LANGUAGE_TYPE'IMAGE(LANGUAGE));
-- elsif UPPER_CASE(C) = 'E' then
-- if ENGLISH_DICTIONARY_AVAILABLE(GENERAL) then
-- LANGUAGE:= ENGLISH_TO_LATIN;
-- PREFACE.PUT_LINE("Language changed to " & LANGUAGE_TYPE'IMAGE(LANGUAGE));
-- PREFACE.PUT_LINE("Input a single English word (+ part of speech - N, ADJ, V, PREP, ...)");
-- else
-- PREFACE.PUT_LINE("No English dictionary available");
-- end if;
-- else
-- PREFACE.PUT_LINE("Bad LANGAUGE input - no change, remains " & LANGUAGE_TYPE'IMAGE(LANGUAGE));
-- end if;
--exception
-- when others =>
-- PREFACE.PUT_LINE("Bad LANGAUGE input - no change, remains " & LANGUAGE_TYPE'IMAGE(LANGUAGE));
--end CHANGE_LANGUAGE;
--
--
begin -- PARSE
-- All Rights Reserved - William Armstrong Whitaker
-- INITIALIZE_WORD_PARAMETERS;
-- INITIALIZE_DEVELOPER_PARAMETERS;
-- INITIALIZE_WORD_PACKAGE;
--
if METHOD = COMMAND_LINE_INPUT then
if TRIM(COMMAND_LINE) /= "" then
PARSE_LINE(COMMAND_LINE);
end if;
else
PREFACE.PUT_LINE(
"Copyright (c) 1993-2006 - Free for any use - Version 1.97FC");
PREFACE.PUT_LINE(
"For updates and latest version check http://www.erols.com/whitaker/words.htm");
PREFACE.PUT_LINE(
"Comments? William Whitaker, Box 51225 Midland TX 79710 USA - whitaker@erols.com");
PREFACE.NEW_LINE;
PREFACE.PUT_LINE(
"Input a word or line of Latin and ENTER to get the forms and meanings");
PREFACE.PUT_LINE(" Or input " & START_FILE_CHARACTER &
" and the name of a file containing words or lines");
PREFACE.PUT_LINE(" Or input " & CHANGE_PARAMETERS_CHARACTER &
" to change parameters and mode of the program");
PREFACE.PUT_LINE(" Or input " & HELP_CHARACTER &
" to get help wherever available on individual parameters");
PREFACE.PUT_LINE(
"Two empty lines (just a RETURN/ENTER) from the keyboard exits the program");
if ENGLISH_DICTIONARY_AVAILABLE(GENERAL) then
PREFACE.PUT_LINE("English-to-Latin available");
PREFACE.PUT_LINE(
CHANGE_LANGUAGE_CHARACTER & "E changes to English-to-Latin, " &
CHANGE_LANGUAGE_CHARACTER & "L changes back [tilde E]");
end if;
if CONFIGURATION = ONLY_MEANINGS then
PREFACE.PUT_LINE(
"THIS VERSION IS HARDCODED TO GIVE DICTIONARY FORM AND MEANINGS ONLY");
PREFACE.PUT_LINE(
"IT CANNOT BE MODIFIED BY CHANGING THE DO_MEANINGS_ONLY PARAMETER");
end if;
GET_INPUT_LINES:
loop
GET_INPUT_LINE:
begin -- Block to manipulate file of lines
if (NAME(CURRENT_INPUT) = NAME(STANDARD_INPUT)) then
SCROLL_LINE_NUMBER := INTEGER(TEXT_IO.LINE(TEXT_IO.STANDARD_OUTPUT));
PREFACE.NEW_LINE;
PREFACE.PUT("=>");
end if;
LINE := BLANK_LINE;
GET_LINE(LINE, L);
if (L = 0) or else (TRIM(LINE(1..L)) = "") then
--LINE_NUMBER := LINE_NUMBER + 1; -- Count blank lines
if (NAME(CURRENT_INPUT) = NAME(STANDARD_INPUT)) then -- INPUT is keyboard
PREFACE.PUT("Blank exits =>");
GET_LINE(LINE, L); -- Second try
if (L = 0) or else (TRIM(LINE(1..L)) = "") then -- Two in a row
exit;
end if;
else -- INPUT is file
--LINE_NUMBER := LINE_NUMBER + 1; -- Count blank lines in file
if END_OF_FILE(CURRENT_INPUT) then
SET_INPUT(STANDARD_INPUT);
CLOSE(INPUT);
end if;
end if;
end if;
if (TRIM(LINE(1..L)) /= "") then -- Not a blank line so L(1) (in file input)
if LINE(1) = START_FILE_CHARACTER then -- To begin file of words
if (NAME(CURRENT_INPUT) /= NAME(STANDARD_INPUT)) then
TEXT_IO.PUT_LINE("Cannot have file of words (@FILE) in an @FILE");
else
TEXT_IO.OPEN(INPUT, TEXT_IO.IN_FILE, TRIM(LINE(2..L)));
TEXT_IO.SET_INPUT(INPUT);
end if;
elsif LINE(1) = CHANGE_PARAMETERS_CHARACTER and then
(NAME(CURRENT_INPUT) = NAME(STANDARD_INPUT)) and then
not CONFIG.SUPPRESS_PREFACE then
CHANGE_PARAMETERS;
elsif LINE(1) = CHANGE_LANGUAGE_CHARACTER then
-- (NAME(CURRENT_INPUT) = NAME(STANDARD_INPUT)) and then
-- not CONFIG.SUPPRESS_PREFACE then
--TEXT_IO.PUT_LINE("CHANGE CHARACTER " & TRIM(LINE));
CHANGE_LANGUAGE(LINE(2));
elsif -- CONFIGURATION = DEVELOPER_VERSION and then -- Allow anyone to do it
LINE(1) = CHANGE_DEVELOPER_MODES_CHARACTER and then
(NAME(CURRENT_INPUT) = NAME(STANDARD_INPUT)) and then
not CONFIG.SUPPRESS_PREFACE then
CHANGE_DEVELOPER_MODES;
else
if (NAME(CURRENT_INPUT) /= NAME(STANDARD_INPUT)) then
PREFACE.NEW_LINE;
PREFACE.PUT_LINE(LINE(1..L));
end if;
if WORDS_MODE(WRITE_OUTPUT_TO_FILE) then
if not CONFIG.SUPPRESS_PREFACE then
NEW_LINE(OUTPUT);
TEXT_IO.PUT_LINE(OUTPUT, LINE(1..L));
end if;
end if;
LINE_NUMBER := LINE_NUMBER + 1; -- Count lines to be parsed
PARSE_LINE(LINE(1..L));
end if;
end if;
exception
when NAME_ERROR | USE_ERROR =>
if (NAME(CURRENT_INPUT) /= NAME(STANDARD_INPUT)) then
SET_INPUT(STANDARD_INPUT);
CLOSE(INPUT);
end if;
PUT_LINE("An unknown or unacceptable file name. Try Again");
when END_ERROR => -- The end of the input file resets to CON:
if (NAME(CURRENT_INPUT) /= NAME(STANDARD_INPUT)) then
SET_INPUT(STANDARD_INPUT);
CLOSE(INPUT);
if METHOD = COMMAND_LINE_FILES then raise GIVE_UP; end if;
else
PUT_LINE("Raised END_ERROR, although in STANDARD_INPUT");
PUT_LINE("^Z is inappropriate keyboard input, WORDS should be terminated with a blank line");
raise GIVE_UP;
end if;
when STATUS_ERROR => -- The end of the input file resets to CON:
PUT_LINE("Raised STATUS_ERROR");
end GET_INPUT_LINE; -- end Block to manipulate file of lines
end loop GET_INPUT_LINES; -- Loop on lines
end if; -- On command line input
begin
STEM_IO.OPEN(STEM_FILE(LOCAL), STEM_IO.IN_FILE,
ADD_FILE_NAME_EXTENSION(STEM_FILE_NAME,
"LOCAL"));
-- Failure to OPEN will raise an exception, to be handled below
if STEM_IO.IS_OPEN(STEM_FILE(LOCAL)) then
STEM_IO.DELETE(STEM_FILE(LOCAL));
end if;
exception
when others =>
null; -- If cannot OPEN then it does not exist, so is deleted
end;
-- The rest of this seems like overkill, it might have been done elsewhere
begin
if
DICT_IO.IS_OPEN(DICT_FILE(LOCAL)) then
DICT_IO.DELETE(DICT_FILE(LOCAL));
else
DICT_IO.OPEN(DICT_FILE(LOCAL), DICT_IO.IN_FILE,
ADD_FILE_NAME_EXTENSION(DICT_FILE_NAME,
"LOCAL"));
DICT_IO.DELETE(DICT_FILE(LOCAL));
end if;
exception when others => null; end; -- not there, so don't have to DELETE
begin
if
DICT_IO.IS_OPEN(DICT_FILE(ADDONS)) then
DICT_IO.DELETE(DICT_FILE(ADDONS));
else
DICT_IO.OPEN(DICT_FILE(ADDONS), DICT_IO.IN_FILE,
ADD_FILE_NAME_EXTENSION(DICT_FILE_NAME,
"ADDONS"));
DICT_IO.DELETE(DICT_FILE(ADDONS));
end if;
exception when others => null; end; -- not there, so don't have to DELETE
begin
if
DICT_IO.IS_OPEN(DICT_FILE(UNIQUE)) then
DICT_IO.DELETE(DICT_FILE(UNIQUE));
else
DICT_IO.OPEN(DICT_FILE(UNIQUE), DICT_IO.IN_FILE,
ADD_FILE_NAME_EXTENSION(DICT_FILE_NAME,
"UNIQUE"));
DICT_IO.DELETE(DICT_FILE(UNIQUE));
end if;
exception when others => null; end; -- not there, so don't have to DELETE
exception
when STORAGE_ERROR => -- Have tried at least twice, fail
PREFACE.PUT_LINE("Continuing STORAGE_ERROR Exception in PARSE");
PREFACE.PUT_LINE("If insufficient memory in DOS, try removing TSRs");
when GIVE_UP =>
PREFACE.PUT_LINE("Giving up!");
when others =>
PREFACE.PUT_LINE("Unexpected exception raised in PARSE");
end PARSE;