Reading: On the AdaCore learning site, look over the section on arrays. There are subsections specifically for strings and array slices that are related to this assignment. Also look over Section 1.8 of my tutorial on Ada.
In this lab you will get some practice working with Ada strings (which are just arrays). You'll also get some exposure to the notion of a filter program... a very useful and powerful kind of program.
Switch back to the master branch of the samples repository (be sure to commit outstanding changes to your current branch first), pull any updates from the server, and then create a new branch for this lab.
A filter program is a program that reads its standard input device (typically the console keyboard), processes the text it gets there, and then writes results to its standard output device (typically the console screen). A trivial example is a program that just copies its input to its output. Such a program can form the basis of more interesting programs that do complex processing on the input text.
Load the file filter.adb into GPS and study it. Compile it and try it out in a console. It should echo back any line you type. In Windows use ^Z (Ctrl+Z) to send an end-of-file indication to the program. In Unix-like systems (Linux, macOS) use ^D for end-of-file.
Using a feature of the console called I/O redirection it is easy to make this simple program manipulate text files. Try, for example, having it process its own source code
filter < filter.adb
It can even be used as a simple copy utility.
filter < filter.adb > copy.adb
Here the < symbol redirects the program's input from the named file, and the > symbol redirects the program's output to the named file. It is also possible to direct the output of one program directly into the input of another using the | symbol.
dir | filter
Now modify the program so that it does some interesting processing. Start by having it output the line number at the start of each line. What is a suitable type for representing line numbers? Run the commands above again to see the effect. The program is potentially useful already!
Add a procedure to your program (nested in the declarative part of the main procedure) that reverses a string. In other words it should convert the string "Hello" into "olleH". Here is a possible declaration for the procedure.
procedure Reverse_String(Text : in out String);
Do you see why the parameter mode should be in out?
Modify your program so that each input line is reversed before it is printed (with the line numbers).
Keep in mind that Ada strings are simply arrays of Character values. They behave like ordinary Ada arrays, so this assignment both introduced strings and also gives you a chance to practice with arrays. The first allowed index of the string Text can be written as Text'First. The last allowed index can be written as Text'Last. The length of the string can be written as Text'Length. These are some examples of Ada attributes. The apostrophe in this context is pronounced "tick." When you implement this procedure you will likely need a variable of type Character to temporarily hold a value from the string during the reversing process.
Modify your program again so that each word in the line is reversed individually. For example, a line such as "This is a test" should become "sihT si a tset". Notice that the order of the words is not changed.
For the purposes of this part we will define a "word" as any sequence of letters (upper or lower case) or digits. Punctuation marks (including the underscore character) are not part of a word and should not be reversed. For example "Hello, World!" should become "olleH, dlroW!" Notice that the comma and the exclamation point remain in their original position.
The package Ada.Characters.Handling contains functions for classifying characters. Take a look at the specification of that package as described in the Ada standard. Your code might contain tests similar to:
if Is_Alphanumeric(Text(I)) then ...
This tests if the Ith character of the string is a letter or a digit.
Hint: You can send array slices to the reversing procedure, so you can reuse the work you did in the previous part. You just need to go down the string and work out the lower and upper bounds for each slice. Scan down the text looking for the beginning of a word and the corresponding ending of a word. When you find the proper index range, you can create an array slice with syntax like Text(Lower .. Upper). The slice is basically a sub-array of the original array. If it is written properly, your Reverse_String procedure should work on the slice just fine.
For this lab, post your final filter.adb file to Canvas.
Last Revised: 2022-02-10
© Copyright 2022 by Peter C. Chapin <pchapin@vtc.edu>