meta data for this page
  •  

Differences

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

Link to this comparison view

Next revision
Previous revision
Last revisionBoth sides next revision
scan_statement [2020/07/24 11:14] – created revuskyscan_statement [2021/02/08 18:16] revusky
Line 1: Line 1:
-==== The new SCAN construct =====+===== The new SCAN Statement =====
  
-JavaCC 21 introduces a new ''SCAN'' statement that is designed to supersede the legacy ''LOOKAHEAD''+JavaCC 21 introduces a new ''SCAN'' statement that is designed to supersede the legacy ''LOOKAHEAD''It is a key part of the [[new_syntax_summary|newer streamlined syntax]]. Like ''LOOKAHEAD'', ''SCAN'' exists to specify conditions at [[choice points]] that override the default resolution mechanism of scanning ahead exactly one token. The new ''SCAN'' construct provides a superset of the functionality of ''LOOKAHEAD'' and tends to more succinct and readable. (Sometimes dramatically so.)
  
-Note that all the older syntax still works and will work for the foreseeable feature. Here is a rundown of the differences between ''SCAN'' and the older ''LOOKAHEAD''.+Note, however, that the older ''LOOKAHEAD'' syntax still works and will work for the foreseeable feature.  
 +Here is a rundown of the differences between ''SCAN'' and the older ''LOOKAHEAD''.
  
 ==== The parameters of SCAN (assuming there are any) are not enclosed in parentheses. ==== ==== The parameters of SCAN (assuming there are any) are not enclosed in parentheses. ====
  
 Thus, where you previously wrote: Thus, where you previously wrote:
- 
  
 <code> <code>
Line 14: Line 14:
 </code> </code>
  
-you can now write:+you would now write:
  
 <code> <code>
Line 23: Line 23:
  
 <code> <code>
-LOOKAHEAD(Foo()) Foo() Bar() +LOOKAHEAD("foo" ("bar"|"baz")) FooBar()
-</code> +
- +
-<code> +
-LOOKAHEAD+
 </code> </code>
  
Line 33: Line 29:
  
 <code> <code>
-SCAN Foo => Foo Bar+SCAN "foo" ("bar"|"baz"=> FooBar
 </code> </code>
  
 Note that the arrow is necessary in the above to separate the lookahead expansion from the expansion to be parsed. You can also write: Note that the arrow is necessary in the above to separate the lookahead expansion from the expansion to be parsed. You can also write:
- 
  
 <code> <code>
 SCAN 3 => Foo SCAN 3 => Foo
 </code> </code>
- 
  
 but the arrow is optional because it is not necessary to disambiguate anything. but the arrow is optional because it is not necessary to disambiguate anything.
- 
  
  
Line 54: Line 47:
  
 <code> <code>
-LOOKAHEAD(Foo() {someCondition()}) FooBar()+LOOKAHEAD(Foo(){someCondition()}) FooBar()
 </code> </code>
  
  
 you now write: you now write:
- 
  
 <code> <code>
Line 97: Line 89:
  
 <code> <code>
-SCAN 0 {someCondition} Foo+SCAN 0 {someCondition} => Foo
 </code> </code>
  
  
-In the legacy lookahead, if you only have semantic lookahead, the number of tokens to be scanned is assumed to be zero, i.e. if the condition succeeds, you automatically go into the following expansion.+In the legacy lookahead, if you only have semantic lookahead, the number of tokens to be scanned is assumed to be zero, i.e. if the condition is true, you automatically go into the following expansion. JavaCC 21 makes the opposite assumption in these spots. Unless you specify otherwise, we assume //unlimited// lookahead.
  
  
-On consideration, I didn’t like that, and decided that, with an explicit ''%%SCAN%%'', the lookahead limit is always infinite, unless you specify otherwise.+==== The SCAN construct also you to use contextual predicates====
  
 +The [[contextual_predicates]] construct allows you to express conditions based on scanning backwards in the lookahead/call stack. This can only be used in conjunction with the newer ''SCAN'' statement, not with the legacy ''LOOKAHEAD'' construct. 
  
 +You can find more information [[contextual_predicates|here]].
  
-==== The SCAN construct also allows the newer LOOKBEHIND construct. ==== +==== Addendum: the SCAN-less SCAN? ====
- +
-This is outlined separately. +
- +
-===== Addendum: the SCAN-less SCAN? =====+
  
 Even the newer SCAN construct has some redundancies. There is no obvious reason to oblige anybody write even: Even the newer SCAN construct has some redundancies. There is no obvious reason to oblige anybody write even:
Line 169: Line 159:
 </code> </code>
  
-In this case, because I think it is so common, we decided to allow this. And, in fact, you can see that this is already used in internal development, for example [[https://github.com/javacc21/javacc21/blob/master/src/main/grammars/JavaCC.javacc#L1028|here]].+In this case, because I think it is so common, we decided to allow this. And, in fact, you can see that this is already used in internal development, for example [[https://github.com/javacc21/javacc21/blob/master/src/main/grammars/JavaCC.javacc#L1950|here]]
 + 
 + 
 +==== Recap ==== 
 + 
 +The new ''SCAN'' instruction in JavaCC 21 totally supersedes the legacy tool's ''LOOKAHEAD''. It allows you to specify in the following order: 
 +  * //numerical// lookahead, i.e. the maximum number of tokens to scan ahead 
 +  * [[semantic lookahead]], i.e. arbitrary java code enclosed in {..} 
 +  * a [[contextual_predicates]] predicate 
 +  * [[syntactic lookahead]] 
 + 
 +Caveats:  
 +  * The ''SCAN'' construct can specify all (or none) of the above, except that //numerical// lookahead and [[syntactic lookahead]] are mutually exclusive.  
 +  * If no numerical or syntactic lookahead is specified, the generated code will scan ahead an //unlimited// number of tokens. This differs from the legacy tool. 
 + 
 +Note that an empty SCAN statement can be simply written alternatively with a lone arrow, i.e. ''=>''.
  
-===== The newer SCAN construct allows you to use the newer "lookbehind" construct  
  
-This is documented separately.