Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions handrolled_parser/core.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ fn State::loc_start_with(state : Self, start : Position) -> Location {
{ start, end: state.parsed_position }
}

///|
fn State::empty_loc(state : Self) -> Location {
{ start: state.parsed_position, end: state.parsed_position }
}

///|
fn State::peek_location(state : Self) -> Location {
let (_, start, end) = state.peek()
Expand Down
6 changes: 3 additions & 3 deletions handrolled_parser/parse_expr_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ test {
"loc": {
"file": "",
"start": { "line": 2, "column": 4 },
"end": { "line": 2, "column": 8 },
"end": { "line": 4, "column": 5 },
},
"children": {
"pattern": {
Expand Down Expand Up @@ -318,7 +318,7 @@ test {
"loc": {
"file": "",
"start": { "line": 2, "column": 9 },
"end": { "line": 2, "column": 8 },
"end": { "line": 4, "column": 5 },
},
"children": {
"expr": {
Expand Down Expand Up @@ -432,7 +432,7 @@ test {
"loc": {
"file": "",
"start": { "line": 2, "column": 9 },
"end": { "line": 2, "column": 8 },
"end": { "line": 4, "column": 5 },
},
"children": {},
},
Expand Down
9 changes: 6 additions & 3 deletions handrolled_parser/parser.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,10 @@ fn State::parse_fun_decl(
)
|> @list.from_array
})
let params_loc = self.loc_start_with(param_loc_start)
let params_loc = match decl_params {
Some(_) => self.loc_start_with(param_loc_start)
None => self.empty_loc()
}
let (return_type, error_type) = self.parse_func_return_type()
let loc = self.loc_start_with(spos)
{
Expand Down Expand Up @@ -4259,8 +4262,8 @@ fn State::parse_simple_expr(
self.parse_semi_trailing_record()
COLON | COMMA | RBRACE => self.parse_record_expr(type_name=None)
_ => {
let loc = self.loc_start_with(spos)
let expr = self.parse_block_expr()
let loc = self.loc_start_with(spos)
Group(expr~, group=Brace, loc~)
}
}
Expand All @@ -4276,8 +4279,8 @@ fn State::parse_simple_expr(
| BYTES(_)
| STRING(_) if self.peek_token(nth=2) is COLON => self.parse_map_expr()
_ => {
let loc = self.loc_start_with(spos)
let expr = self.parse_block_expr()
let loc = self.loc_start_with(spos)
Group(expr~, group=Brace, loc~)
}
}
Expand Down
60 changes: 60 additions & 0 deletions test/sync_test/loc_regression_test.mbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
///|
let loc_regression_source =
#| let global: Int = {
#| 1
#| }
#|
#| fn init {
#| let _ = global
#| }

///|
fn parse_loc_regression(
parser : @parser.Parser,
) -> (@syntax.Impls, @basic.Location, @basic.Location, Json) raise Error {
let (impls, diagnostics) = @parser.parse_string(
loc_regression_source,
name="loc_regression.mbt",
parser~,
)
if !diagnostics.is_empty() {
fail(diagnostics.to_string())
}
let mut brace_group_loc = None
let mut params_loc = None
for impl_ in impls {
match impl_ {
TopLetDef(expr=Group(group=Brace, loc~, ..), ..) =>
brace_group_loc = Some(loc)
TopFuncDef(fun_decl~, ..) => params_loc = Some(fun_decl.params_loc)
_ => ()
}
}
let json = @basic.show_loc.protect(@basic.String, fn() {
impls.map(impl_ => impl_.json_repr()).to_json()
})
match (brace_group_loc, params_loc) {
(Some(brace_group_loc), Some(params_loc)) =>
(impls, brace_group_loc, params_loc, json)
_ => fail("failed to find loc regression fixtures in parsed AST")
}
}

///|
test "loc parity for brace group and empty fn params" {
let (_, hand_group_loc, hand_params_loc, hand_json) = parse_loc_regression(
@parser.Handrolled,
)
let (_, yacc_group_loc, yacc_params_loc, yacc_json) = parse_loc_regression(
@parser.MoonYacc,
)
inspect(hand_group_loc, content="loc_regression.mbt-1:20-3:3")
inspect(hand_params_loc, content="loc_regression.mbt-5:9-5:9")
inspect(yacc_group_loc, content="loc_regression.mbt-1:20-3:3")
inspect(yacc_params_loc, content="loc_regression.mbt-5:9-5:9")
if hand_json != yacc_json {
fail(
"loc-sensitive AST mismatch between handrolled and yacc parsers.\nhandrolled:\n\{hand_json.stringify(indent=2)}\n\nyacc:\n\{yacc_json.stringify(indent=2)}",
)
}
}
Loading