WITH Ada.Text_IO, VStrings; USE Ada.Text_IO, VStrings; PACKAGE BODY English_Lexer IS ------------------------------------------------------------------------ --| Body of English Lexical Scanner --| Author: Michael B. Feldman, The George Washington University --| Last Modified: January 1996 ------------------------------------------------------------------------ TYPE State IS (Start, Build, Finish); TYPE InputClass IS (Letter, CR, AnythingElse); TYPE Action IS (Nothing, StartWord, BumpLine, AddLetter); TYPE LexicalEntry IS RECORD NewState : State; ThisAction : Action; END RECORD; TYPE FSM_Table IS ARRAY (State, InputClass) OF LexicalEntry; FUNCTION Classify (Ch: Character) RETURN InputClass IS BEGIN CASE Ch IS WHEN 'A'..'Z' | 'a'..'z' | '0'..'9' => RETURN Letter; WHEN OTHERS => RETURN AnythingElse; END CASE; END Classify; PROCEDURE GetWord (F : IN File_Type; Word : OUT WordType; Success: OUT Boolean; EOL : OUT Boolean; EOF : OUT Boolean) IS Char : character; ThisClass : InputClass; PresentState : State; ThisEntry : LexicalEntry; NewAction : Action; TempWord : WordType; -- Lexical table for simplified English text. EnglishText : CONSTANT FSM_Table := ( -- entries for current state = Start, current input = ((Build, StartWord), -- Letter (Finish, BumpLine), -- CR (Start, Nothing)), -- AnythingElse -- entries for current state = Build, current input = ((Build, AddLetter), -- Letter (Finish, BumpLine), -- CR (Finish, Nothing)), -- AnythingElse -- entries for current state = Finish, current input = ((Finish, Nothing), -- Letter (Finish, Nothing), -- CR (Finish, Nothing))); -- AnythingElse -- End of lexical table for simple English BEGIN --- body of GetWord EOL := false; EOF := false; PresentState := Start; LOOP IF PresentState = Finish THEN EXIT; END IF; IF End_of_File (F) THEN EOF := true; EXIT; ELSIF End_of_Line (F) THEN Skip_Line (F); ThisClass := CR; ELSE Get (F, Char); Put(Char); ThisClass := Classify (Char); END IF; NewAction := EnglishText (PresentState, ThisClass).ThisAction; CASE NewAction IS WHEN Nothing => NULL; WHEN StartWord => TempWord := TempWord & Char; WHEN AddLetter => TempWord := TempWord & Char; WHEN BumpLine => EOL := true; END CASE; PresentState := EnglishText (PresentState, ThisClass).NewState; END LOOP; Word := TempWord; Success := NOT VStrings.IsEmpty(Word); END GetWord; END English_Lexer;