Stacking states on dated stacks to reinstate Of Stack & State: first rate?

I have accomplished the first major portion of the code I set out to write last
Christmas. My milestone for Quadrare Lexema, first quarter 2016, is available
at MediaFire here:

http://www.mediafire.com/download/26qa4xnidxaoq46/mlptk-2016q1-typeset-full.zip

It's a bit larger than my other snapshots this year, because I included another
full PDF typesetting of my software (which, today, runs into hundreds of pages)
and two audio recordings evoking my most beautiful childhood memories. These
added a few Mbytes. I'll remove them in the next edition.
(No, really; Tuna Loaf truly does encode smaller as a PCM .WAV than an MP3.)

Don't bother downloading this one unless you really want to see how QL's shaping
up or need a preformatted typesetting of progress since the prospectus. There is
nothing much new: all my work in the first quarter has been in Quadrare Lexema &
these updates, and the command line interpreter upgrade isn't yet operational.

My source code is, as usual, free of charge and Public Domain.
Some of the graphics and frills don't belong to me, and I plan to remove them
(either at some unspecified future time or upon any such notification/demand),
but please restrict yourself to my signed code if copying & pasting for profit.

Today's edition of MLPTK includes an upgraded QL. I haven't had time to overhaul
yet, but I did manage to shoehorn in a somewhat improved parser mechanism. This
should make things less of a nightmare for those of you presently experimenting
with the beta version of QL, which is at least a _stable_ beta by now.

Of particular interest are MLPTK's text-mode console, which I employed to debug
Quadrare Lexema in alpha, and which is now stable/maintenance (doesn't crash);
and QL itself, now a stable Beta (doesn't crash much).
My tentative additions to the Bison parser's "left/right" associativity model &
their demonstration in the Command Line Interpretation Translator's library file
are of most interest to experienced programmers. When I've finished writing the
manuscript in its native language, I'll write an additional reference sheet in
English for the novitiate. (See the old AFURACC supplemental schematic reference
for an idea of what this shall look like.)

I've altered QL's schematic slightly, to permit the programmer (that's you!) to
encode a minor degree of context in your grammar, and my code is so easy to read
& alter that you can really have a field day with this thing if you've the mind.

Several of my foregoing briefs, which cover some of these already; consider also
the Blargument rule, which is what makes the CLIT so fascinating. Utilizing QL's
mechanism to unshift multiple tokens back onto the input stream when executing a
reduction (which is really remarkably clever; because, IIRC, Bison can't unshift
multiple tokens during a reduction deferment, so multiple-symbol productions are
very difficult to achieve by using the industry-standard technology), Blargument
consumes 1 less token than it "actually" does by unshifting the trailing token.
Because of how I wrote QL, the parser differentiates its input stream (virtually
or actually) each time a reduction produces symbols; so, even when a deferred
reduction pushes symbols back onto the input stream, these don't interfere with
any of the other deferred reductions (which exist as though the input stream was
not modified by anything that didn't happen during their "timeline").

In addition, my upgrade to QL's programming interface permits differentiation at
any point within the input stream. Although somewhat wobbly, this serves to show
how it's possible for even a deferred computation to polymorph the code - before
the parser has even arrived there, & without affecting any of the other quanta.
Or at least it will, if I can figure out how to apply it before the next time I
overhaul the code; otherwise, I think I'll drop it from the schematic, because
this input stream metaphor should probably be optimized due to large inputs.

The old Capsule Parser generator is still there, via the ::toTheLimit() method,
and the upgraded Ettercap Parser is generated by ::hattenArDin().

Here is an abridged comparison & contrast:
1. Stack nodes are generic; their place taken by hard-coded transition methods.
   Some alterations to stack node constructor argument vector, algorithm.
   There is more hard code and less heuristics. Actually, the whole parser could
   be generated as static code, and I hope to implement that sometime this year.
2. Input is now a linked list; previously an Array.
   Arrays of tokens are preprocessed to generate this list, which functions as
   a stream buffer with a sequential-access read head.
3. The input stream links forward and the parse stack links backward.
4. Stack extrema now interface with the input stream differentially; that is,
   the input stream itself is differentiated (obviating recursion), instead of
   the recursive virtual differentiation that occurred before.
5. Differentiation of the input stream occurs actually, not virtually, and can
   be programmed at any point in the input stream (although it's such a pain).

Here's an illustration of the extremum-to-read-head interface juncture:

                    -> [ EXTREMUM A ] -> [ READ HEAD A ] -> [ DIFFERENTIAL A ]
                   /                                               v
 -> [ PARSE STACK ] -> [ EXTREMUM B ] -> [ READ HEAD B ] -> [ INPUT BUFFER ] ->
                   \                                               ^
                    -> [ EXTREMUM C ] -> [ READ HEAD C ] -> [ DIFFERENTIAL C ]

Actually it is a little more complicated than that, but that is the basic idea.
As you can see, my parser models a Turing machine that sort of unravels itself
at the interface between what it has already seen and what it presently sees.
Then it zips itself back up when reduce/reduce conflicts resolve themselves.
I imagine it like a strand of DNA that is reconstituting itself in karyokinesis.

The extrema A through C are, actually, probably exactly the same extremum.
However, when the next parse iteration steps forward to the location within the
input stream that is pointed-to by the read head, the parse stack branches; so,
it's easiest to imagine that the extrema have already branched at the point of
interface, because if they haven't branched yet then they are about to.

Here's an illustration of timeline differentiation within the input stream:

                        -> [ DIFFERENTIAL A ] -.       -> [ DIFFERENTIAL C ]
                       /                   v---¯     /                       \
    -> [ READ HEAD(S) ] -> [ UNMODIFIED INPUT ] -> [ TOKEN W ] -> [ TOKEN Z ] ->
                       \                   ^-----------------------------------.
                        -> [ DIFFERENTIAL B ] -> [ DIFFERENTIAL B CONTINUES ] -¯

The parser selects differentials based on either of two criteria: the read head,
which points at the "beginning" of the input stream buffer as it is perceived by
the extremum in that timeline; or a timeline identifier ("thread ID") that tells
the algorithm when it should, for example, jump from token W to differential C
and therefore skip token Z. Thus, multiple inputs are "the same program."
Again: parser state becomes unzipped at differential points, then re-zips itself
after the differentiated timelines have resolved themselves by eliminating those
who encounter a parse error until only one possible timeline remains.

So your code can polymorph itself. In fact, it can polymorph itself as much as
you want it to, because the parser returns ambiguous parses as long as they have
produced the origin symbol during its finalization phase. However, I haven't yet
tested this and it probably causes more difficulty than it alleviates.

However, if you've experimented with AFURACC, you might be disappointed to see
that I have failed to write an interface for you to polymorph the grammar at run
time using QL. Probably that's possible to do, but the scaffold (as it is at the
moment) is rigid and inflexible. I want to work it into a future revision; but,
because a heuristic parser is more-or-less sine qua non to the whole idea of a
polymorphic parser, I'm pretty sure I'll stick to just polymorphing the code.

As I work to reduce the time complexity of the parser algorithm, similarity to
the Free Software Foundation's compiler-compiler, GNU Bison, becomes pronounced.
I'm trying to add some new ideas, but Bison is pretty much perfect as it is, so
I haven't had much luck - things that aren't Bison seem to break or complicate.
I still haven't heard anything from the FSF about this, so I guess it's OK?

However, the scaffold seems stable, so I'll work on the command-line interpreter
for a while and formalize its grammar. After that, probably yet another improved
static code generator, and if that doesn't malfunction I'll try video games IDK.

I intend to complete the formal commandline grammar within second quarter 2016.
Goals: command substitution, javascript substitution (a la 'csh'), environment
variables and shell parameter expansion, and shell arithmetic.
Additionally, if there's time, better loops and a shell scripting language.
Advertisements

Be careful what you say. The U.S.A. is not as free a country as you have been led to believe.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s