-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
langkit/parsers.py: support Cut in Opt subparser
Improve error recovery of incomplete code parsing by allowing Cut parser in Opt ones. TN: S201-022
- Loading branch information
Showing
8 changed files
with
620 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
testsuite/tests/grammar/multiple_cuts/expected_concrete_syntax.lkt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import lexer_example | ||
|
||
@with_lexer(foo_lexer) | ||
grammar foo_grammar { | ||
@main_rule stmt_rule <- list*(or(def | var | dot | comma)) | ||
id <- Id(@identifier) | ||
def <- Def( | ||
"def" | ||
/ id ?pick("(" / id ")") ?pick("{" / id "}") | ||
) | ||
var <- Var( | ||
"var" / id ?pick("(" / list+(id, ",") ")") | ||
) | ||
dot <- Dot( | ||
"." id ?pick("(" / id ")") ?pick("{" / id "}") | ||
) | ||
comma <- Comma(?pick("(" / id ")") "," id id) | ||
} | ||
|
||
@abstract class FooNode implements Node[FooNode] { | ||
} | ||
|
||
class Comma : FooNode { | ||
@parse_field id1: Id | ||
@parse_field id2: Id | ||
@parse_field id3: Id | ||
} | ||
|
||
class Def : FooNode { | ||
@parse_field id1: Id | ||
@parse_field id2: Id | ||
@parse_field id3: Id | ||
} | ||
|
||
class Dot : FooNode { | ||
@parse_field id1: Id | ||
@parse_field id2: Id | ||
@parse_field id3: Id | ||
} | ||
|
||
class Id : FooNode implements TokenNode { | ||
} | ||
|
||
class Var : FooNode { | ||
@parse_field id: Id | ||
@parse_field ids: ASTList[FooNode, Id] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import libfoolang | ||
|
||
|
||
inputs = [ | ||
('complete case 1', "def a"), | ||
('complete case 2', "def a (b)"), | ||
('complete case 3', "def a (b) {c}"), | ||
('complete case 4', "var a"), | ||
('complete case 5', "var a (b)"), | ||
('complete case 6', "var a (b, c, d)"), | ||
('complete case 7', ". a (b)"), | ||
('complete case 8', ". a (b) {c}"), | ||
('complete case 9', ", a b"), | ||
('complete case 10', "(a) , b c"), | ||
# The def and var rules check that incomplete results are produced | ||
# regarding the presence of several cut parsers. | ||
('incomplete case 1', "def"), | ||
('incomplete case 2', "def a (b"), | ||
('incomplete case 3', "def a (b) {c"), | ||
('incomplete case 4', "def a ("), | ||
('incomplete case 5', "def a (b) {"), | ||
('incomplete case 6', "def a ( {"), | ||
('incomplete case 7', "def a (b {c"), | ||
('incomplete case 8', "var"), | ||
('incomplete case 9', "var a ("), | ||
('incomplete case 10', "var a ()"), | ||
('incomplete case 11', "var a (b, c, d"), | ||
# The dot rule checks that an incomplete result is produced if only the | ||
# optional part can set the no_backtracing variable. | ||
('incomplete case 12', ". a (b"), | ||
('incomplete case 13', ". a (b) {"), | ||
('incomplete case 14', ". a ( {"), | ||
# The comma rule is similar to the dot one but the optional part is at the | ||
# beginning of the rule. | ||
('incomplete case 15', ", b"), | ||
('incomplete case 16', "(a) , b"), | ||
('incomplete case 17', "(a , b"), | ||
] | ||
|
||
ctx = libfoolang.AnalysisContext() | ||
|
||
for name, text in inputs: | ||
print(f"=== {name}: {text} ===") | ||
print() | ||
u = ctx.get_from_buffer("buffer", buffer=text) | ||
|
||
for d in u.diagnostics: | ||
print(d) | ||
u.root.dump() | ||
print() |
Oops, something went wrong.