meta data for this page
  •  

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
lookbehind [2020/10/22 02:41] – [Summary] revuskycontextual_predicates [2023/03/03 14:23] (current) revusky
Line 1: Line 1:
-====== Lookbehind Predicates ======+====== Contextual Predicates ======
  
-A //lookbehind predicate// allows you to add conditions at [[choice points]] based on scanning back in the call/lookahead stack. Note that this is a completely new feature in JavaCC 21 that does not exist in the legacy JavaCC tool.+A //contextual predicate// allows you to add conditions at [[choice points]] based on scanning back in the call/lookahead stack. We are not aware of any other parser generator tool that has this feature.
  
 The easiest way to describe this is with some actual examples. The easiest way to describe this is with some actual examples.
Line 7: Line 7:
 ==== Specifying that a production is non-reentrant ==== ==== Specifying that a production is non-reentrant ====
  
-Probably the most typical usage will be to guarantee that a production is not //re-entrant//, i.e. that it is not allowed to nest recursively. This can now be expressed very cleanly with a //lookbehind predicate// as follows:+Probably the most typical usage will be to guarantee that a production is not //re-entrant//, i.e. that it is not allowed to nest recursively. This can now be expressed very cleanly with a //contextual predicate// as follows:
  
 <code> <code>
Line 19: Line 19:
 ==== Scanning Forward vs. Backward, Ellipsis and Wild-card  ==== ==== Scanning Forward vs. Backward, Ellipsis and Wild-card  ====
  
-Note that the elements in a //lookbehind predicate// are separated either with a backslash "\" or a forward slash "/". The previous example used a backslash and that means that we scan backwards from the current production up towards the root; a forward slash means that we are scanning forward from the root. +Note that the elements in a //contextual predicate// are separated either with a backslash "\" or a forward slash "/". The previous example used a backslash and that means that we scan backwards from the current production up towards the root; a forward slash means that we are scanning forward from the root. 
  
 In the above example, the ellipsis "..." that follows the backslash means that there can be an arbitrary number of intervening productions in the call stack. The //wild-card// or simply //dot// means that we match the occurrence (exactly one!) of any production. If, for example, we wrote: In the above example, the ellipsis "..." that follows the backslash means that there can be an arbitrary number of intervening productions in the call stack. The //wild-card// or simply //dot// means that we match the occurrence (exactly one!) of any production. If, for example, we wrote:
Line 67: Line 67:
 ==== Summary ==== ==== Summary ====
  
-A //lookbehind predicate// starts optionally with a tilde "~" to indicate negation. The first character after the tilde (or simply the first character if there is no tilde) must be either a backslash or a forward slash. The backslash indicates that we are scanning backwards from the current production and the forward slash means that we are scanning forward from the current production.+A //contextual predicate// starts optionally with a tilde "~" to indicate negation. The first character after the tilde (or simply the first character if there is no tilde) must be either a backslash or a forward slash. The backslash indicates that we are scanning backwards from the current production and the forward slash means that we are scanning forward from the current production.
  
 An ellipsis "..." means that we can have an arbitrary number (including zero) of intervening productions. A dot "." means that we have exactly one production of any type.  An ellipsis "..." means that we can have an arbitrary number (including zero) of intervening productions. A dot "." means that we have exactly one production of any type. 
Line 89: Line 89:
 NB. If you have a ''SCAN'' statement that does not specify either numerical or syntactic lookahead, then the generated code will scan ahead an //unlimited// number of tokens. (Unless the expansion to be parsed is constrained by an [[up to here]] marker.) This is a key characteristic of the newer [[scan statement]]. NB. If you have a ''SCAN'' statement that does not specify either numerical or syntactic lookahead, then the generated code will scan ahead an //unlimited// number of tokens. (Unless the expansion to be parsed is constrained by an [[up to here]] marker.) This is a key characteristic of the newer [[scan statement]].
  
-Note also that //lookbehind predicates//, like syntactic lookahead in JavaCC 21, can be nested arbitrarily and work in an arbitrarily nested scanahead routine.+Note also that //contextual predicates//, like syntactic lookahead in CongoCC, can be nested arbitrarily and work in an arbitrarily nested scanahead routine.