Merge pull request #6968 from ssenthilnathan3/fix/ternary-comment-parsing

Fix parser failing on comments inside ternary expressions
This commit is contained in:
gingerBill
2026-07-08 10:56:05 +01:00
committed by GitHub
3 changed files with 87 additions and 2 deletions

View File

@@ -381,6 +381,9 @@ advance_token :: proc(p: ^Parser) -> tokenizer.Token {
#partial switch p.curr_tok.kind {
case .Comment:
consume_comment_groups(p, prev)
if p.curr_tok.kind == .Semicolon && p.expr_level > 0 && p.curr_tok.text == "\n" {
advance_token(p)
}
case .Semicolon:
if p.expr_level > 0 && p.curr_tok.text == "\n" {
advance_token(p)
@@ -3622,7 +3625,9 @@ parse_binary_expr :: proc(p: ^Parser, lhs: bool, prec_in: int) -> ^ast.Expr {
case .If, .When:
if p.prev_tok.pos.line < op.pos.line {
// NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
break loop
if p.expr_level <= 0 {
break loop
}
}
}

View File

@@ -1529,6 +1529,9 @@ gb_internal Token advance_token(AstFile *f) {
switch (f->curr_token.kind) {
case Token_Comment:
consume_comment_groups(f, prev);
if (f->curr_token.kind == Token_Semicolon && ignore_newlines(f) && f->curr_token.string == "\n") {
advance_token(f);
}
break;
case Token_Semicolon:
if (ignore_newlines(f) && f->curr_token.string == "\n") {
@@ -3582,7 +3585,9 @@ gb_internal Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
case Token_when:
if (prev.pos.line < op.pos.line) {
// NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
goto loop_end;
if (f->expr_level <= 0) {
goto loop_end;
}
}
break;
}

View File

@@ -131,3 +131,78 @@ my_func :: proc (cond: bool, a: string, b: string) -> string {
testing.expect(t, ok, "bad parse")
testing.expect(t, file.syntax_error_count == 0, "should contain zero errors")
}
@test
test_parse_multiline_ternary_infix_with_comment :: proc(t: ^testing.T) {
context.allocator = context.temp_allocator
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
file := ast.File{
fullpath = "test.odin",
src = `
package main
my_func :: proc (cond: bool, a: string, b: string) -> string {
out := (
cond
? a // This is a comment!
: b
)
return out
}
`,
}
p := parser.default_parser()
p.err = proc(pos: tokenizer.Pos, format: string, args: ..any) {
message := fmt.tprintf(format, ..args)
log.errorf("%s(%d:%d): %s", pos.file, pos.line, pos.column, message)
}
p.warn = proc(pos: tokenizer.Pos, format: string, args: ..any) {
message := fmt.tprintf(format, ..args)
log.warnf("%s(%d:%d): %s", pos.file, pos.line, pos.column, message)
}
ok := parser.parse_file(&p, &file)
testing.expect(t, ok, "bad parse")
testing.expect(t, file.syntax_error_count == 0, "should contain zero errors")
}
@test
test_parse_ternary_if_statements_with_comment :: proc(t: ^testing.T) {
context.allocator = context.temp_allocator
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
file := ast.File{
fullpath = "test.odin",
src = `
package main
my_func :: proc (cond: bool, a: string, b: string) -> string {
out := (
cond
if a // This is a comment!
else b
)
return out
}
`,
}
p := parser.default_parser()
p.err = proc(pos: tokenizer.Pos, format: string, args: ..any) {
message := fmt.tprintf(format, ..args)
log.errorf("%s(%d:%d): %s", pos.file, pos.line, pos.column, message)
}
p.warn = proc(pos: tokenizer.Pos, format: string, args: ..any) {
message := fmt.tprintf(format, ..args)
log.warnf("%s(%d:%d): %s", pos.file, pos.line, pos.column, message)
}
ok := parser.parse_file(&p, &file)
testing.expect(t, ok, "bad parse")
testing.expect(t, file.syntax_error_count == 0, "should contain zero errors")
}