In general I am sympathetic to these musings.  I also believe clarity is
very important. But I am compelled to add a few observations.

First, my experience has been that the maintenance of hand-coded finite
state machines is difficult.  There are wonderful tools for building (and
rebuilding) FSMs but I don't know of any that are available for HLASM.  So
while FSMs are wonderful for purposes of tokenizing and parsing, I have
abandoned using FSMs when coding in HLASM.  Maybe you have (macro based?)
techniques for building HLASM FSMs or have other experience with them that I
don't have.

Second, I believe there are only two valid reasons to write production code
in HLASM.  One is performance.  The other is access to OS or hardware
services that cannot be easily done in a higher level language. This is
especially true for z/OS.  Otherwise HLLs have an advantage in
maintainability and portability.

A tokenizer/parser generally does not need access to low-level services.  So
if performance is not an issue, I would rather write a tokenizer/parser in
C.  I might even use lex and yacc to build the FSMs.  Or I might write an
easily understood recursive descent parser.  And using METAL-C (or an
equivalent), I can integrate it into a larger mostly-HLASM code base.

But if performance is an issue, then I do need to pay attention to the
instructions that I use.  Fixed-length TRT performs well over the range of
about 8-256 characters.  But as has been discussed ad-nauseam, EX of TRT is
an extremely slow combination on the z10, especially for the short
variable-length searches typically encountered in tokenizing.  The newer
variable-length TR* instructions are not always available or perform well.
Being aware of the cache on the TRT table can be critical.  SRST is easy to
use and fast for finding a specific character (such as the next blank) in a
variable length string but has limited usefulness in tokenizers.
Performance issues may dictate that the code needs to be written using more
complex constructs than EX+TRT - otherwise HLLs should be considered.

Related to the above is my observation that because coding HLASM is so
low-level, it seems to cause the coder to think at the same level.  Often
the easier-to-code algorithm is chosen instead of a more efficient one.
Choosing a more efficient algorithm will almost always yield better
performance than micro-optimizing a poor algorithm.  Yet it seems many HLASM
programmers focus on the second.  I can't count the number of well-coded
bubble sorts I have replaced.

David

On Wed, 6 Oct 2010 12:02:56 +0000, john gilmore wrote:
>This is one of my ruminations, and if you find them boring you may safely
skip the rest of this post.
>
>The subject of this thread in all of its particularity is not of much
interest, but it is of great interest if it is viewed more abstractly.  This
time, moreover, it is easy to generalize.
>
>Most of the posts dealt with blanks, x'40' in EBCDIC and x'20' in  ASCII,
but repetitions of nuls, x'00' in both, are more important in some few
contexts.
>
>The limitation to 16 characters,  one instance and 15 repetitions of it, is
artificial.
>
>Finally, the limitation to a single character is stultifying: many
apparently different but in fact conceptually identical problems require
that repetitions of any of a subset of characters be identified.
>
>Consider the two PL/I statements, useful because they are cointext-sensitive:
>
>declare transac3 file record sequential buffered ;
>
>open file(transac3) input      ;
>
>In  both we want to break out the tokens, 'declare', 'transac3', 'file',
'record', 'sequential', 'buffered', ';' in the first and 'open', 'file',
'(', 'transac3', ')', 'input', ';' in the second.  Here, as Robin has
already pointed out,  a TRT is better than a CLC[L].
>
>Indeed, well-written texical breakout routines consist of little more than
a small finite-state-machine and a set of TRT tables.  In particular, they
do not process inputs one character at a time (as the computer science 101
illustrations always do).
>
>There is a sense in which this is well known.  The current PROP in its
discussion of the TRT instruction says
>
>TRANSLATE AND TEST may be used to scan the first operand for characters
with special meaning. The second operand, or list, is set up with all-zero
function bytes for those characters to be skipped over and with nonzero
function bytes for the characters to be detected.
>
>For my example it is thus possible to both stop on [any of] a blank, a left
parenthesis, a right parenthesis, or a semicolon and to distinguish them
(without further testing) after stopping.
>
>Why use a TRT, which requires a table of, usually, 256 bytes, when
something more compact can be put together for the special case of 16 blanks
(or nuls)?  The answer can be boiled down to a single word,  reusability.
>
>Efficiency is a vexed question, and I cannot consider it here in any really
satisfactory way.  No one wants to write inefficient or inelegant code, but
preoccupation with the relative efficiencies of alternative single
instructions, both of which consume only nanoseconds, is a mug's game.
Worse, the avoidance of single millicode-based instructions, their
replacement by a notionally and temporarily more efficient sequence of
hardware-based ones, is, I think, perverse.
>
>Enough!  I have already offended just about everyone.
>
>John Gilmore Ashland, MA 01721-1817 USA

Reply via email to