Revision 568589

Go back to digest for 6th August 2006

Features in Development Tools

Jakob Petsovits committed changes in /branches/work/kdevelop-pg/src:

Implement backtracking for kdevelop-pg.
(Also known as LL(k) for poor people ;)

The new backtracking construct "try/rollback" is able
to replace all your hand-adapted lookahead hacks.
Use it for conflicts that require arbitrary-length LL(k) lookahead.
Don't use it when you can determine the upcoming rule with
simple [: LA(2).kind == Token_BLAH :] checks.


Old solution
(with lookahead_is_conflicting_item_1() being defined somewhere else):

(
[: lookahead_is_conflicting_item_1() == true :]
var1=conflicting_item_1
|
var2=conflicting_item_2
)

New solution:

try/rollback(var1=conflicting_item_1) catch(var2=conflicting_item_2)


It works this way:
- try to derive conflicting_item_1
- if there are no parsing errors, proceed.
- if there are any errors, go back to the token where
conflicting_item_1 started, and derive conflicting_item_2.
On errors, conflicting_item_1 is not assigned to var1.

Note that if you have multiple annotated items inside the try block
("try/rollback(var1=item1 var2=item2) catch(...)")
and there are parsing errors in item2, then the item1 node is still
assigned to var1. So, it's best to only have single items inside
a try block.

This commit also renames recover(...) to try/recover(...),
as there are many similarities to try/rollback.

If the grammar is using either try/recover or try/rollback constructs,
you now have to provide custom stuff for parser state management:
- a struct named parser_state containing all the variables
that may change during parsing. (It can also be an empty struct.)
- two parser class methods:
* copy_current_state() returns a new parser_state object, or 0
* restore_state() restores the variables in the given
parser_state object back to the parser class.

This is required for a clean rollback or recovery, for parsers
that change some state variables in code segments.
(Like the ltCounter variable in the Java and C# parser.)

Also, the yy_expected_token() and yy_expected_symbol() methods
must now return void instead of bool.

Sorry for the long commit message :]

File Changes

Modified 19 files
  • /branches/work/kdevelop-pg/src
  •   /kdev-pg-ast.h
  •   /kdev-pg-clone-tree.cpp
  •   /kdev-pg-clone-tree.h
  •   /kdev-pg-code-gen.cpp
  •   /kdev-pg-code-gen.h
  •   /kdev-pg-default-visitor.cpp
  •   /kdev-pg-default-visitor.h
  •   /kdev-pg-first.cpp
  •   /kdev-pg-first.h
  •   /kdev-pg-follow.cpp
  •   /kdev-pg-follow.h
  •   /kdev-pg-lexer.ll
  •   /kdev-pg-parser.yy
  •   /kdev-pg-pretty-printer.cpp
  •   /kdev-pg-pretty-printer.h
  •   /kdev-pg-visitor.cpp
  •   /kdev-pg-visitor.h
  •   /kdev-pg.cpp
  •   /kdev-pg.h
19 files changed in total