# Marpa::R3 is Copyright (C) 2017, Jeffrey Kegler. # # This module is free software; you can redistribute it and/or modify it # under the same terms as Perl 5.10.1. For more details, see the full text # of the licenses in the directory LICENSES. # # This program is distributed in the hope that it will be # useful, but it is provided “as is” and without any express # or implied warranties. For details, see the full text of # of the licenses in the directory LICENSES. =head1 Name Marpa::R3::Exhaustion - Parse exhaustion in the SLIF =head1 About this document This page is part of the reference documents for the recognizer objects of Marpa's SLIF (Scanless interface). It contains a detailed discussion of parse exhaustion. =head1 Exhaustion At bottom, B is a simple concept. The recognizer may reach a point where there is simply no way to continue successfully. Regardless of what it reads next, the parse will fail. When this happens, the parse is said to be B. Some users have confused parse exhaustion with parse failure. But other users have confused parse exhaustion with parse success. That is because, for a particular grammar, there can be a strong association between parse exhaustion and parse success, but the strong association can go either way. Grammars can be either exhaustion-loving or exhaustion-hating. B kinds of grammar are very common in practical application. =head1 Hate and love In an B application, parse exhaustion is typically parse failure. C programs, Perl scripts and most programming languages are exhaustion-hating applications. If a C program is well-formed, it is always possible to read more input. The same is true of a Perl program that does not have a C<__DATA__> section. In an B applications parse exhaustion means parse success. A toy example of an exhaustion-loving application is the language consisting of balanced parentheses. When the parentheses come into perfect balance the parse is exhausted, because any further input would unbalance the brackets. And the parse succeeds when the parentheses come into perfect balance. Exhaustion means success. Any language which balances start and end indicators will tend to be exhaustion-loving. HTML and XML, with their start and end tags, can be seen as exhaustion-loving languages. For many languages, it's not strictly love or hate. I mentioned Perl's C<__DATA__> as a complication in a basically exhaustion-hating language. It is possible for a language to be exhaustion-loving at some points and exhaustion-hating at others. We can call those languages B. =head1 Reading methods The methods that may encounter parse exhaustion are those that read input: L, L, L, and L. These are also, and not by coincidence, the event-triggering methods. In this document, we will call them the B. =head1 Synchronous and asynchronous parse exhaustion Intuitively, parse exhaustion is B if it occurs at a location where control would return to the user anyway, and asynchronous otherwise. More precisely, we say that parse exhaustion is B if it occurs at a point when control would normally return from SLIF to the application, due to either =over 4 =item * the parse reaching end of string (EOS), or =item * the occurrence of a parse event other than an exhaustion event. =back Marpa can be set up so that an event occurs on asynchronous exhaustion. Note that in The definition above the occurrence of an exhaustion event does not makes the parse exhaustion synchronous. This wording is chosen to avoid a paradox. If a parse exhaustion event could made exhaustion synchronous, then it B occur, because parse exhaustion events only occur on asynchronous parse exhaustion. But if the parse exhaustion event did not occur, then the parse exhaustion would be asynchronous, so that then a parse exhaustion event B occur. In this document, an B is a location at which parse exhaustion occurs. =head1 Handling parse exhaustion How parse exhaustion is handled depends on the setting of the L grammar setting|Marpa::R3::Scanless::G/"exhaustion">. The value of this may be "C" or "C". ("C" is the default.) Synchronous parse exhaustion is always ignored, regardless of the recognizer setting. No exhaustion event is triggered by synchronous parse exhaustion. If the C setting is "C", asynchronous parse exhaustion is thrown as a fatal error. If the C setting is "C", then an L is triggered, returning control to the application. This is treated by the triggering method as a successful return. Note that the L, and L, always ignore parse exhaustion, regardless of the C grammar setting. This is because these methods read input only at a single location, so that every parse exhaustion is synchronous. =head1 Detecting parse exhaustion The return value of a reading method does not indicate whether exhaustion occurred or not. In most cases, you will either know from the the context whether the parse is exhausted, or you will not care. But what if you do not know and do care? Those applications that want to know whether a parse is exhausted or not can directly query parse exhaustion status with the L method|Marpa::R3::Scanless::R/"exhausted()">. Even when L are enabled, using the C method is the preferred method for detecting exhaustion, because it reports both asynchronous and synchronous parse exhaustion. Exhaustion events only trigger in cases of asynchronous parse exhaustion. =head1 Exhaustion-conflicted Exhaustion-conflicted applications are those which cannot be called exhaustion-loving or exhaustion-hating. This may be because their behavior is a combination of the two. But it may also be because the application's behavior is not known -- for example, while developing an application, it's convenient to assume that it is exhaustion-conflicted. The SLIF's behavior for exhaustion-conflicted applications has to be aimed at a "lowest common denominator". It is also a good idea for a default to be a lowest common denominator and, by default, the SLIF assumes that an application is exhausted-conflicted. In fact, the default behavior on parse exhaustion usually works well enough that it does not need customizing. For a typical application without events, end of parse (EOP) is end of string (EOS). In this case exhaustion before EOS is a fatal error, which is usually what is desired. On return due to EOS, unless the application checks, it will not know whether exhaustion occurred, but usually it does not care. If the application does care, it can L. If the application uses events to signal EOP, the case is much the same. On return due to an event, the application will not know if exhaustion occurred, but usually it will not care. If the application does care, it can L. If the application uses events for other purposes, an event may "hide" exhaustion, so that it is not thrown as an error. Typically, an application will soon attempt to continue the reading of input, and when it does there will be a fatal error. An application which wants to know about exhaustion immediately, either to "fast fail" or for other reasons, can L every time an event triggers. =head2 Exhaustion-loving For an exhaustion-loving application, what was said for exhaustion-conflicted applications applies without change. Applications that consider it important to confirm that exhaustion did occur at EOP can L Some applications go beyond being exhaustion-loving, and want to use exhaustion to signal the EOP. These exhaustion-sensing applications are L. =head2 Exhaustion-hating Exhaustion-hating applications are handled reasonably by the default behavior. Asynchronous exhaustion will be a fatal error. Synchronous exhaustion will cause failure at the next read, unless it happens at EOP. By default, exhaustion at EOP will go unreported but if an application really is exhaustion-hating, the parse will fail, and parse failure will certainly show up when the application tries to evaluate the parse. Exhaustion-hating applications, if they want to be stricter than this, can check for exhaustion explicitly whenever a reading method returns. A possible annoyance is that, depending where it happens, exhaustion may also cause the reading method to throw an exception. Applications which want more orthogonality in their exhaustion handling can enable exhaustion events, which will prevent exceptions being thrown due to parse exhaustion. =head1 Exhaustion-sensing Sometimes an application, rather than read an entire input, wants to find the longest occurrence starting at some location. (Lexers are typically applications of this kind.) Looking for exhaustion is one way to try to implement this kind of "longest acceptable input stream" search. But exhaustion-sensing is not necessarily the best way, or even a good way, to find the "longest parse". Exhaustion may not happen until after last successful parse -- sometimes not until long after it. Completion parse events may be a cleaner way to deal with this. Applications which do want to use parse exhaustion as part of a strategy for finding the EOP can set the L grammar setting|Marpa::R3::Scanless::G/"exhaustion"> to "C", so that a parse event occurs at parse exhaustion. When the event-triggering method returns, the application can then L. =head1 COPYRIGHT AND LICENSE =for Marpa::R3::Display ignore: 1 Marpa::R3 is Copyright (C) 2017, Jeffrey Kegler. This module is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.1. For more details, see the full text of the licenses in the directory LICENSES. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. =for Marpa::R3::Display::End =cut # vim: expandtab shiftwidth=4: