Skip to content

Commit

Permalink
Better "unexpected kw" handling in ternary parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
pfitzseb committed Aug 25, 2022
1 parent 291da24 commit 424be21
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
15 changes: 8 additions & 7 deletions src/kinds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,10 @@ const _kind_names =
"baremodule"
"begin"
"break"
"catch"
"const"
"continue"
"do"
"else"
"elseif"
"end"
"export"
"finally"
"for"
"function"
"global"
Expand All @@ -51,6 +46,13 @@ const _kind_names =
"try"
"using"
"while"
"BEGIN_BLOCK_CONTINUATION_KEYWORDS"
"catch"
"finally"
"else"
"elseif"
"end"
"END_BLOCK_CONTINUATION_KEYWORDS"
"BEGIN_CONTEXTUAL_KEYWORDS"
# contextual keywords
"abstract"
Expand Down Expand Up @@ -1045,6 +1047,7 @@ end
is_contextual_keyword(k::Kind) = K"BEGIN_CONTEXTUAL_KEYWORDS" < k < K"END_CONTEXTUAL_KEYWORDS"
is_error(k::Kind) = K"BEGIN_ERRORS" < k < K"END_ERRORS"
is_keyword(k::Kind) = K"BEGIN_KEYWORDS" < k < K"END_KEYWORDS"
is_block_continuation_keyword(k::Kind) = K"BEGIN_BLOCK_CONTINUATION_KEYWORDS" < k < K"END_BLOCK_CONTINUATION_KEYWORDS"
is_literal(k::Kind) = K"BEGIN_LITERAL" < k < K"END_LITERAL"
is_operator(k::Kind) = K"BEGIN_OPS" < k < K"END_OPS"
is_word_operator(k::Kind) = (k == K"in" || k == K"isa" || k == K"where")
Expand Down Expand Up @@ -1098,5 +1101,3 @@ end
function is_whitespace(x)
kind(x) in (K"Whitespace", K"NewlineWs")
end


14 changes: 12 additions & 2 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,18 @@ function parse_cond(ps::ParseState)
t = peek_token(ps)
if !preceding_whitespace(t)
# a ? b :c ==> (if a [ ] [?] [ ] b [ ] [:] (error-t) c)
bump_invisible(ps, K"error", TRIVIA_FLAG,
error="space required after `:` in `?` expression")
bump_invisible(ps, K"error", TRIVIA_FLAG, error="space required after `:` in `?` expression")
end
if is_block_continuation_keyword(kind(t))
# a "continuaton keyword" is likely to belong to the surrounding code, so
# we abort early

# if true; x ? true elseif true end ==> (if true (block (if x true (error-t) (error-t))) (elseif true (block)))
# if true; x ? true end ==> (if true (block (if x true (error-t) (error-t))))
# if true; x ? true : elseif true end ==> (if true (block (if x true (error-t))) (elseif true (block)))
bump_invisible(ps, K"error", TRIVIA_FLAG, error="unexpected `$(kind(t))`")
emit(ps, mark, K"if")
return
end
parse_eq_star(ps)
emit(ps, mark, K"if")
Expand Down
3 changes: 3 additions & 0 deletions test/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ tests = [
"if a xx elseif b yy end" => "(if a (block xx) (elseif b (block yy)))"
"if a xx else if b yy end" => "(if a (block xx) (error-t) (elseif b (block yy)))"
"if a xx else yy end" => "(if a (block xx) (block yy))"
"if true; x ? true elseif true end" => "(if true (block (if x true (error-t) (error-t))) (elseif true (block)))"
"if true; x ? true end" => "(if true (block (if x true (error-t))))"
"if true; x ? true : elseif true end" => "(if true (block (if x true (error-t))) (elseif true (block)))"
],
JuliaSyntax.parse_const_local_global => [
"global x" => "(global x)"
Expand Down

0 comments on commit 424be21

Please sign in to comment.