Add parser tests

This commit is contained in:
Jonatan Kłosko 2021-09-01 16:59:04 +02:00
parent da75c9ee6b
commit 3f19b87c70
31 changed files with 5509 additions and 0 deletions

101
test/corpus/comment.txt Normal file
View File

@ -0,0 +1,101 @@
=====================================
empty
=====================================
#
---
(source
(comment))
=====================================
single line
=====================================
# single comment
---
(source
(comment))
=====================================
multiple start symbols
=====================================
### multiple "#"
---
(source
(comment))
=====================================
many consecutive lines
=====================================
# many
# consecutive
1
# lines
---
(source
(comment)
(comment)
(integer)
(comment))
=====================================
in the same line as regular code
=====================================
1 # comment
---
(source
(integer)
(comment))
=====================================
matches inside a nested structure
=====================================
[ 1 ## inside a list
, { 2 # and a tuple, too!
, 3 }
]
---
(source
(list
(integer)
(comment)
(tuple
(integer)
(comment)
(integer))))
=====================================
does not match inside a string
=====================================
"# string"
"this is #{interpolation}"
---
(source
(string
(string_start)
(string_content)
(string_end))
(string
(string_start)
(string_content)
(interpolation (identifier))
(string_end)))

580
test/corpus/do_end.txt Normal file
View File

@ -0,0 +1,580 @@
=====================================
call without arguments
=====================================
fun do
a
end
---
(source
(call
(identifier)
(do_block
(identifier))))
=====================================
call with arguments in parentheses
=====================================
fun(a, b) do
c
end
---
(source
(call
(identifier)
(arguments
(identifier)
(identifier))
(do_block
(identifier))))
=====================================
call with arguments without parentheses
=====================================
fun a, b do
c
end
---
(source
(call
(identifier)
(arguments
(identifier)
(identifier))
(do_block
(identifier))))
=====================================
remote call
=====================================
Mod.fun do
a
end
---
(source
(call
(dot
(alias)
(identifier))
(do_block
(identifier))))
=====================================
sticks to the outermost call
=====================================
outer_fun inner_fun arg do
a
end
---
(source
(call
(identifier)
(arguments
(call
(identifier)
(arguments
(identifier)))
(do_block
(identifier))))
=====================================
newline before do
=====================================
fun x
do
x
end
---
(source
(call
(identifier)
(arguments
(identifier))
(do_block
(identifier))))
=====================================
stab clause / no arguments
=====================================
fun do
() -> x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments)
(body
(identifier))))))
=====================================
stab clause / no arguments without parentheses
=====================================
fun do
-> x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(body
(identifier))))))
=====================================
stab clause / one argument
=====================================
fun do
x -> x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments
(identifier))
(body
(identifier))))))
=====================================
stab clause / many arguments
=====================================
fun do
x, y, 1 -> :ok
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments
(identifier)
(identifier)
(integer))
(body
(atom
(atom_literal)))))))
=====================================
stab clause / arguments in parentheses
=====================================
fun do
(x, y) -> :ok
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments
(identifier)
(identifier))
(body
(atom
(atom_literal)))))))
=====================================
stab clause / many clauses
=====================================
fun do
1 -> :yes
2 -> :no
other -> :maybe
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments
(integer))
(body
(atom
(atom_literal))))
(stab_clause
(arguments
(integer))
(body
(atom
(atom_literal))))
(stab_clause
(arguments
(identifier))
(body
(atom
(atom_literal)))))))
=====================================
stab clause / multiline expression
=====================================
fun do
x ->
y
x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments
(integer))
(body
(identifier)
(identifier))))))
=====================================
stab clause / with guard / no arguments
=====================================
fun do
() when node() == :nonode@nohost -> true
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(binary_operator
(arguments)
(binary_operator
(call
(identifier)
(arguments))
(atom
(atom_literal))))
(body
(boolean))))))
=====================================
stab clause / with guard / one argument
=====================================
fun do
x when x == [] -> x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(binary_operator
(arguments
(identifier))
(binary_operator
(identifier)
(list)))
(body
(atom
(atom_literal)))))))
=====================================
stab clause / with guard / multiple arguments
=====================================
fun do
x, y when x == [] -> x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(binary_operator
(arguments
(identifier)
(identifier))
(binary_operator
(identifier)
(list)))
(body
(atom
(atom_literal)))))))
=====================================
stab clause / with guard / arguments in parentheses
=====================================
fun do
(x, y) when y == [] -> y
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(binary_operator
(arguments
(identifier)
(identifier))
(binary_operator
(identifier)
(list)))
(body
(atom
(atom_literal)))))))
=====================================
stab clause / with guard / multiple guards
=====================================
fun do
x when x > 10 when x < 5 -> x
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(binary_operator
(arguments
(identifier))
(binary_operator
(binary_operator
(identifier)
(identifier))
(binary_operator
(identifier)
(identifier))))
(body
(atom
(atom_literal)))))))
=====================================
pattern matching
=====================================
fun do
[h | tail] -> {h, tail}
end
---
(source
(call
(identifier)
(do_block
(stab_clause
(arguments
(list
(binary_operator
(identifier)
(identifier))))
(body
(atom
(atom_literal)))))))
=====================================
child blocks / after
=====================================
fun do
x
after
y
end
---
(source
(call
(identifier)
(do_block
(identifier)
(after_block
(identifier)))))
=====================================
child blocks / catch
=====================================
fun do
x
catch
y
end
---
(source
(call
(identifier)
(do_block
(identifier)
(catch_block
(identifier)))))
=====================================
child blocks / else
=====================================
fun do
x
else
y
end
---
(source
(call
(identifier)
(do_block
(identifier)
(else_block
(identifier)))))
=====================================
child blocks / rescue
=====================================
fun do
x
rescue
y
end
---
(source
(call
(identifier)
(do_block
(identifier)
(rescue_block
(identifier)))))
=====================================
child blocks / duplicated
=====================================
fun do
x
after
y
after
z
end
---
(source
(call
(identifier)
(do_block
(identifier)
(after_block
(identifier))
(after_block
(identifier)))))
=====================================
child blocks / mixed
=====================================
fun do
x
else
y
after
z
end
---
(source
(call
(identifier)
(do_block
(identifier)
(else_block
(identifier))
(after_block
(identifier)))))
=====================================
child blocks / stab clause
=====================================
fun do
x
rescue
y -> y
end
---
(source
(call
(identifier)
(do_block
(identifier)
(rescue_block
(stab_clause
(arguments
(identifier))
(body
(identifier)))))))

View File

@ -0,0 +1,69 @@
=====================================
operator with arity (valid and supported by IEx.Helpers.h)
=====================================
::/2
@ / 1
& / 1
---
(source
(binary_operator
(operator_identifier)
(integer)))
=====================================
map with identifiers
=====================================
%{a}
%{a, b}
---
(source
(map
(map_content
(identifier)))
(map
(map_content
(identifier)
(identifier))))
=====================================
def with remote call
=====================================
def Mod.fun(x), do: 1
---
(source
(call
(identifier)
(arguments
(call
(dot
(alias)
(identifier))
(arguments
(identifier)))
(keywords
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
[error] arrow outside of map
=====================================
a => b
---
(source
(identifier)
(ERROR
(identifier)))

View File

@ -0,0 +1,323 @@
=====================================
no arguments
=====================================
fn() -> 1 end
fn () -> 1 end
---
(source
(anonymous_function
(stab_clause
(arguments)
(body
(integer))))
(anonymous_function
(stab_clause
(body
(integer)))))
=====================================
no arguments without parentheses
=====================================
fn -> 1 end
---
(source
(anonymous_function
(stab_clause
(body
(integer)))))
=====================================
one argument
=====================================
fn(x) -> x end
---
(source
(anonymous_function
(stab_clause
(arguments
(identifier))
(body
(identifier)))))
=====================================
one argument without parentheses
=====================================
fn x -> x end
---
(source
(anonymous_function
(stab_clause
(arguments
(identifier))
(body
(identifier)))))
=====================================
many arguments
=====================================
fn(x, y) -> x + y end
---
(source
(anonymous_function
(stab_clause
(arguments
(identifier)
(identifier))
(body
(binary_operator
(identifier)
(identifier))))))
=====================================
many arguments without parentheses
=====================================
fn x, y -> x + y end
---
(source
(anonymous_function
(stab_clause
(arguments
(identifier)
(identifier))
(body
(binary_operator
(identifier)
(identifier))))))
=====================================
multiline body
=====================================
fn x, y ->
y
x
end
---
(source
(anonymous_function
(stab_clause
(arguments
(identifier)
(identifier))
(body
(identifier)
(identifier)))))
=====================================
many clauses
=====================================
fn
1 -> :yes
2 -> :no
other -> :maybe
end
---
(source
(anonymous_function
(stab_clause
(arguments
(integer))
(body
(atom
(atom_literal))))
(stab_clause
(arguments
(integer))
(body
(atom
(atom_literal))))
(stab_clause
(arguments
(identifier))
(body
(atom
(atom_literal))))))
=====================================
with guard / no arguments
=====================================
fn
() when node() == :nonode@nohost -> true
end
---
(source
(anonymous_function
(stab_clause
(binary_operator
(arguments)
(binary_operator
(call
(identifier)
(arguments))
(atom
(atom_literal))))
(body
(atom
(atom_literal))))))
=====================================
with guard / one argument
=====================================
fn
x when x == [] -> x
end
---
(source
(anonymous_function
(stab_clause
(binary_operator
(arguments
(identifier))
(binary_operator
(identifier)
(list)))
(body
(atom
(atom_literal))))))
=====================================
with guard / multiple arguments
=====================================
fn
x, y when x == [] -> x
end
---
(source
(anonymous_function
(stab_clause
(binary_operator
(arguments
(identifier)
(identifier))
(binary_operator
(identifier)
(list)))
(body
(atom
(atom_literal))))))
=====================================
with guard / arguments in parentheses
=====================================
fn
(x, y) when y == [] -> y
end
---
(source
(anonymous_function
(stab_clause
(binary_operator
(arguments
(identifier)
(identifier))
(binary_operator
(identifier)
(list)))
(body
(atom
(atom_literal))))))
=====================================
with guard / multiple guards
=====================================
fn
x when x > 10 when x < 5 -> x
end
---
(source
(anonymous_function
(stab_clause
(binary_operator
(arguments
(identifier))
(binary_operator
(binary_operator
(identifier)
(identifier))
(binary_operator
(identifier)
(identifier))))
(body
(atom
(atom_literal))))))
=====================================
pattern matching
=====================================
fn
[h | tail] -> {h, tail}
%{x: x} when x == 1 -> 1
end
---
(source
(anonymous_function
(stab_clause
(arguments
(list
(binary_operator
(identifier)
(identifier))))
(body
(atom
(atom_literal))))
(stab_clause
(binary_operator
(arguments
(map
(map_content
(keywords
(pair
(keyword
(atom_literal))
(identifier))))))
(binary_operator
(binary_operator
(identifier)
(identifier))
(binary_operator
(identifier)
(identifier))))
(body
(atom
(atom_literal))))))

View File

@ -0,0 +1,96 @@
=====================================
empty
=====================================
()
---
(source
(block))
=====================================
single expression
=====================================
(1)
---
(source
(block
(integer)))
=====================================
multiple expressions separated by newline
=====================================
(
1
2
)
---
(source
(block
(integer)
(integer)))
=====================================
multiple expressions separated by semicolon
=====================================
(1;2)
---
(source
(block
(integer)
(integer)))
=====================================
multiple expressions separated by mixed separators
=====================================
(
1
;
2
)
---
(source
(block
(integer)
(integer)))
=====================================
leading semicolon
=====================================
(;1;2)
---
(source
(block
(integer)
(integer)))
=====================================
trailing semicolon
=====================================
(1;2;)
---
(source
(block
(integer)
(integer)))

View File

@ -0,0 +1,806 @@
=====================================
local call / no arguments
=====================================
fun()
---
(source
(call
(identifier)
(arguments)))
=====================================
local call / arguments in parentheses
=====================================
fun(a)
fun([1, 2], option: true, other: 5)
---
(source
(call
(identifier)
(arguments
(identifier)))
(call
(identifier)
(arguments
(list
(integer)
(integer))
(keywords
(pair
(keyword
(atom_literal))
(boolean))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
local call / arguments without parentheses
=====================================
fun a
fun [1, 2], option: true, other: 5
---
(source
(call
(identifier)
(arguments
(identifier)))
(call
(identifier)
(arguments
(list
(integer)
(integer))
(keywords
(pair
(keyword
(atom_literal))
(boolean))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
local call / nested with parentheses
=====================================
outer_fun(inner_fun(a))
---
(source
(call
(identifier)
(arguments
(call
(identifier)
(arguments
(identifier))))))
=====================================
local call / nested without parentheses (right associativity)
=====================================
outer_fun inner_fun a
---
(source
(call
(identifier)
(arguments
(call
(identifier)
(arguments
(identifier))))))
=====================================
local call / precedence with operator
=====================================
fun +1
outer_fun 1 + 1
1 + inner_fun 1
outer_fun 1 + inner_fun 1
fun 1, 2 |> other_fun
---
(source
(call
(identifier)
(arguments
(unary_operator
(integer))))
(call
(identifier)
(arguments
(binary_operator
(integer)
(integer))))
(binary_operator
(integer)
(call
(identifier)
(arguments
(integer))))
(call
(identifier)
(arguments
(binary_operator
(integer)
(call
(identifier)
(arguments
(integer))))))
(call
(identifier)
(arguments
(integer)
(binary_operator
(integer)
(identifier)))))
=====================================
local call / treats nonimmediate parentheses as a block argument
=====================================
fun (x)
---
(source
(call
(identifier)
(arguments
(block
(identifier)))))
=====================================
remote call / no arguments
=====================================
Mod.fun()
---
(source
(call
(dot
(alias)
(identifier))
(arguments)))
=====================================
remote call / no arguments without parentheses
=====================================
Mod.fun
---
(source
(call
(dot
(alias)
(identifier))))
=====================================
remote call / arguments in parentheses
=====================================
Mod.fun(a)
Mod.fun([1, 2], option: true, other: 5)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(identifier)))
(call
(dot
(alias)
(identifier))
(arguments
(list
(integer)
(integer))
(keywords
(pair
(keyword
(atom_literal))
(boolean))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
remote call / arguments without parentheses
=====================================
Mod.fun a
Mod.fun [1, 2], option: true, other: 5
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(identifier)))
(call
(dot
(alias)
(identifier))
(arguments
(list
(integer)
(integer))
(keywords
(pair
(keyword
(atom_literal))
(boolean))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
remote call / nested with parentheses
=====================================
Mod.outer_fun(Mod.inner_fun(a))
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))))
=====================================
remote call / nested without parentheses (right associativity)
=====================================
Mod.outer_fun Mod.inner_fun a
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))))
=====================================
remote call / precedence with operator
=====================================
Mod.outer_fun 1 + 1
1 + Mod.inner_fun 1
Mod.outer_fun 1 + Mod.inner_fun 1
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(binary_operator
(integer)
(integer))))
(binary_operator
(integer)
(call
(dot
(alias)
(identifier))
(arguments
(integer))))
(call
(dot
(alias)
(identifier))
(arguments
(binary_operator
(integer)
(call
(dot
(alias)
(identifier))
(arguments
(integer)))))))
=====================================
remote call / treats nonimmediate parentheses as a block argument
=====================================
Mod.fun (x)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(block
(identifier)))))
=====================================
remote call / multi-level alias
=====================================
Mod1.Mod2.Mod3.fun(a)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))
=====================================
remote call / operator
=====================================
Kernel.+(a, b)
---
(source
(call
(dot
(alias)
(operator_identifier))
(arguments
(identifier)
(identifier))))
=====================================
remote call / quoted function name
=====================================
Mod."fun"(a)
Mod.'fun'(a)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))
=====================================
remote call / atom literal module
=====================================
:mod.fun(a)
:"Elixir.Mod".fun(a)
---
(source
(call
(dot
(atom
(atom_literal))
(identifier))
(arguments
(identifier)))
(call
(dot
(atom
(string_content))
(identifier))
(arguments
(identifier))))
=====================================
anonymous call / no arguments
=====================================
fun.()
---
(source
(call
(dot
(identifier))
(arguments)))
=====================================
anonymous call / arguments in parentheses
=====================================
fun.(a)
fun.([1, 2], option: true, other: 5)
---
(source
(call
(dot
(identifier))
(arguments
(identifier)))
(call
(dot
(identifier))
(arguments
(list
(integer)
(integer))
(keywords
(pair
(keyword
(atom_literal))
(boolean))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
anonymous call / nested with parentheses
=====================================
outer_fun.(inner_fun.(a))
---
(source
(call
(dot
(identifier))
(arguments
(call
(dot
(identifier))
(arguments
(identifier))))))
=====================================
mixed call types
=====================================
Mod.outer_fun mid_fun inner_fun.(a)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(call
(identifier)
(call
(dot
(identifier))
(arguments
(identifier)))))))
=====================================
identifier call
=====================================
mod.fun(a)
---
(source
(call
(dot
(identifier)
(identifier))
(arguments
(identifier))))
=====================================
nested identifier call
=====================================
map.mod.fun(a)
---
(source
(call
(dot
(call
(dot
(identifier)
(identifier)))
(identifier))
(arguments
(identifier))))
=====================================
reserved word call
=====================================
a.and
---
(source
(call
(dot
(identifier)
(identifier))))
=====================================
range call
=====================================
(1..2).step
(1..2//3).step
---
(source
(call
(dot
(block
(binary_operator
(integer)
(integer)))
(identifier)))
(call
(dot
(block
(binary_operator
(binary_operator
(integer)
(integer))
(integer))))
(identifier)))
=====================================
multi-expression block call
=====================================
(
x
1..2
).step
---
(source
(call
(dot
(block
(identifier)
(binary_operator
(integer)
(integer)))
(identifier))))
=====================================
map call
=====================================
%{}.field
---
(source
(call
(dot
(map)
(identifier))))
=====================================
struct call
=====================================
%Mod{}.field
---
(source
(call
(dot
(map
(struct
(alias)))
(identifier))))
=====================================
arbitrary term call
=====================================
1.(1, 2)
---
(source
(call
(dot
(integer))
(arguments
(integer)
(integer))))
=====================================
escaped newline call
=====================================
fun \
a
---
(source
(call
(identifier)
(arguments
(identifier))))
=====================================
keyword list trailing separator
=====================================
fun(option: true, other: 5,)
---
(source
(call
(identifier)
(arguments
(keywords
(pair
(keyword
(atom_literal))
(boolean))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
newline before dot
=====================================
Mod
.fun(a)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))
=====================================
newline after dot
=====================================
Mod.
fun(a)
---
(source
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))
=====================================
access syntax
=====================================
map[key]
map[:key]
---
(source
(access_call
(identifier)
(identifier))
(access_call
(identifier)
(atom
(atom_literal))))
=====================================
access syntax / does not allow whitespace
=====================================
map [key]
---
(source
(call
(identifier)
(arguments
(list
(identifier)))))
=====================================
access syntax / precedence over dot call
=====================================
map[:mod].fun
---
(source
(call
(dot
(access_call
(identifier)
(atom
(atom_literal)))
(identifier))))
=====================================
[error] leading argument separator
=====================================
fun(, a)
---
(source
(call
(identifier)
(arguments
(ERROR)
(identifier))))

View File

@ -0,0 +1,130 @@
=====================================
anonymous function
=====================================
& &1 + &2
&(&1 + &2)
&foo(&1, a, &2)
---
(source
(unary_operator
(binary_operator
(unary_operator
(integer))
(unary_operator
(integer))))
(unary_operator
(binary_operator
(unary_operator
(integer))
(unary_operator
(integer))))
(unary_operator
(call
(arguments
(unary_operator
(integer))
(identifier)
(unary_operator
(integer))))))
=====================================
argument call
=====================================
& &1.some_fun
&(&1.some_fun)
& &1.(&2)
---
(source
(unary_operator
(call
(dot
(unary_operator
(integer)
(identifier)))))
(unary_operator
(call
(dot
(unary_operator
(integer)
(identifier)))))
(unary_operator
(call
(dot
(unary_operator
(integer)
(arguments
(unary_operator
(integer))))))))
=====================================
remote MFA
=====================================
&Mod.fun/1
---
(source
(unary_operator
(binary_operator
(call
(dot
(alias)
(identifier)))
(integer))))
=====================================
remote operator MFA
=====================================
&Kernel.>=/2
---
(source
(unary_operator
(binary_operator
(call
(dot
(alias)
(operator_identifier)))
(integer))))
=====================================
local MFA
=====================================
&fun/1
---
(source
(unary_operator
(binary_operator
(identifier)
(integer))))
=====================================
local operator MFA
=====================================
&>=/2
&//2
---
(source
(unary_operator
(binary_operator
(operator_identifier)
(integer)))
(unary_operator
(binary_operator
(operator_identifier)
(integer))))

View File

@ -0,0 +1,356 @@
=====================================
unary
=====================================
@arg
+arg
-arg
!arg
^arg
not arg
~~~arg
&arg
---
(source
(unary_operator
(identifier))
(unary_operator
(identifier))
(unary_operator
(identifier))
(unary_operator
(identifier))
(unary_operator
(identifier))
(unary_operator
(identifier))
(unary_operator
(identifier))
(unary_operator
(identifier)))
=====================================
binary left associative
=====================================
a * b * c
a / b / c
a + b + c
a - b - c
a ^^^ b ^^^ c
a in b in c
a not in b not in c
a |> b |> c
a <<< b <<< c
a >>> b >>> c
a <<~ b <<~ c
a ~>> b ~>> c
a <~ b <~ c
a ~> b ~> c
a <~> b <~> c
a <|> b <|> c
a < b < c
a > b > c
a <= b <= c
a >= b >= c
a == b == c
a != b != c
a =~ b =~ c
a === b === c
a !== b !== c
a && b && c
a &&& b &&& c
a and b and c
a || b || c
a ||| b ||| c
a or b or c
a <- b <- c
a \\ b \\ c
---
(source
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier)))
=====================================
binary right associative
=====================================
a ++ b ++ c
a -- b -- c
a +++ b +++ c
a --- b --- c
a .. b .. c
a <> b <> c
a = b = c
a | b | c
a :: b :: c
a when b when c
---
(source
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier)))
(binary_operator (identifier) (binary_operator (identifier) (identifier))))
=====================================
precedence on the same level falls back to associativity
=====================================
a * b / c
a + b - c
a in b not in c
a <<< b >>> c
a < b > c
a == b != c
a &&& b && c
a ||| b || c
a <- b \\ c
a ++ b -- c
---
(source
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (binary_operator (identifier) (identifier)) (identifier))
(binary_operator (identifier) (binary_operator (identifier) (identifier))))
=====================================
precedence on different levels
=====================================
& @ a - b
a -- b + c
a - b ++ c
a = b <<< c
a + b * c - d
---
(source
(unary_operator
(binary_operator
(unary_operator
(identifier))
(identifier)))
(binary_operator
(identifier)
(binary_operator
(identifier)
(identifier)))
(binary_operator
(binary_operator
(identifier)
(identifier))
(identifier))
(binary_operator
(identifier)
(binary_operator
(identifier)
(identifier)))
(binary_operator
(binary_operator
(identifier)
(binary_operator
(identifier)
(identifier)))
(identifier)))
=====================================
precedence determined by parentheses
=====================================
(& a) - b
(a + b) * (c - d)
---
(source
(binary_operator
(unary_operator
(identifier))
(identifier))
(binary_operator
(block
(binary_operator
(identifier)
(identifier)))
(block
(binary_operator
(identifier)
(identifier)))))
=====================================
multiline
=====================================
-
x
x
not in
[y]
---
(source
(unary_operator
(identifier))
(binary_operator
(identifier)
(list
(identifier))))
=====================================
stepped range
=====================================
1 .. 2 // 3
1..2//3
0..1//-1
---
(source
(binary_operator
(binary_operator
(integer)
(integer))
(integer))
(binary_operator
(binary_operator
(integer)
(integer))
(integer))
(binary_operator
(binary_operator
(integer)
(integer))
(unary_operator
(integer))))
=====================================
stepped range / multiline
=====================================
1..2
// 4
---
(source
(binary_operator
(binary_operator
(integer)
(integer))
(integer)))
=====================================
stepped ranges / blocks
=====================================
foo do end..bar do end//baz do end
1..(2//3)
(1..2)//3
(1..2)//(3)
---
(source
(binary_operator
(binary_operator
(call
(identifier)
(do_block))
(call
(identifier)
(do_block)))
(call
(identifier)
(do_block)))
(binary_operator
(integer)
(block
(binary_operator
(integer)
(integer))))
(binary_operator
(block
(binary_operator
(integer)
(integer)))
(integer))
(binary_operator
(block
(binary_operator
(integer)
(integer)))
(block
(integer))))

View File

@ -0,0 +1,246 @@
=====================================
simple literal
=====================================
~s(content)
~r{content}
~w[content]
~a<content>
~b"content"
~c'content'
~d|content|
~e/content/
---
(source
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content))
(sigil (sigil_name) (string_content)))
=====================================
multiple lines
=====================================
~s"line 1
line 2"
---
(source
(sigil
(sigil_name)
(string_content)))
=====================================
interpolation
=====================================
~s"hey #{name}!"
~r/hey #{
name
}!/
~w{##{name}#}
---
(source
(sigil
(sigil_name)
(string_content)
(interpolation
(identifier))
(string_content))
(sigil
(sigil_name)
(string_content)
(interpolation
(identifier))
(string_content))
(sigil
(sigil_name)
(string_content)
(interpolation
(identifier))
(string_content)))
=====================================
nested interpolation
=====================================
~s{this is #{~s{number #{1}}}!}
---
(source
(sigil
(sigil_name)
(string_content)
(interpolation
(sigil
(sigil_name)
(string_content)
(interpolation
(identifier))))
(string_content)))
=====================================
escape sequence
=====================================
~s{_\}_\n_\t_\r_\e_\\_\1_\x3f_\u0065\u0301_}
---
(source
(sigil
(sigil_name)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(escape_sequence)
(string_content)))
=====================================
escaped interpolation
=====================================
~s{\#{1}}
---
(source
(sigil
(sigil_name)
(escape_sequence)
(string_content)))
=====================================
upper sigil / no interpolation
=====================================
~S"hey #{name}!"
---
(source
(sigil
(sigil_name)
(string_content)))
=====================================
upper sigil / no escape sequence
=====================================
~S"\n"
---
(source
(sigil
(sigil_name)
(string_content)))
=====================================
upper sigil / escape terminator
=====================================
~S"content \" content"
~S{content \} content}
~S/content \/ content/
---
(source
(sigil
(sigil_name)
(string_content)
(escape_sequence)
(string_content))
(sigil
(sigil_name)
(string_content)
(escape_sequence)
(string_content))
(sigil
(sigil_name)
(string_content)
(escape_sequence)
(string_content)))
=====================================
heredoc delimiter
=====================================
~s"""
text
with "quotes"
"""
~s'''
text
with 'quotes'
'''
---
(source
(sigil
(sigil_name)
(string_content))
(sigil
(sigil_name)
(string_content)))
=====================================
modifiers
=====================================
~r/left|right/i
~r/left|right/iUx
---
(source
(sigil
(sigil_name)
(string_content)
(sigil_modifiers))
(sigil
(sigil_name)
(sigil_modifiers)))
=====================================
[error] accepts only a single character
=====================================
~mysigil"content"
---
(source
(ERROR)
(call
(string
(string_content))))

View File

@ -0,0 +1,364 @@
=====================================
def / no arguments
=====================================
def fun() do
end
---
(source
(call
(identifier)
(arguments
(call
(identifier)
(arguments)))
(do_block)))
=====================================
def / no arguments without parentheses
=====================================
def fun do
end
---
(source
(call
(identifier)
(arguments
(call
(identifier)))
(do_block)))
=====================================
def / one argument
=====================================
def fun(x) do
x
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)))))
(do_block
(identifier))))
=====================================
def / one argument without parentheses
=====================================
def fun x do
x
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)))))
(do_block
(identifier))))
=====================================
def / many arguments
=====================================
def fun(x, y) do
x + y
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)
(identifier)))))
(do_block
(binary_operator
(identifier)
(identifier)))))
=====================================
def / many arguments without parentheses
=====================================
def fun x, y do
x + y
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)
(identifier)))))
(do_block
(binary_operator
(identifier)
(identifier)))))
=====================================
def / default arguments
=====================================
def fun x, y \\ 1 do
x + y
end
def fun(x, y \\ 1) do
x + y
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)
(binary_operator
(identifier)
(integer))))))
(do_block
(binary_operator
(identifier)
(identifier))))
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)
(binary_operator
(identifier)
(integer))))))
(do_block
(binary_operator
(identifier)
(identifier)))))
=====================================
def / keyword do block
=====================================
def fun(), do: 1
def fun(x), do: x
---
(source
(call
(identifier)
(arguments
(call
(identifier)))
(keywords
(pair
(keyword
(atom_literal))
(integer))))
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)))))
(keywords
(pair
(keyword
(atom_literal))
(identifier)))))
=====================================
def / pattern matching
=====================================
def fun([{x, y} | tail]) do
x + y
end
---
(source
(call
(identifier)
(arguments
(call
(identifier)
(arguments
(list
(binary_operator
(tuple
(identifier)
(identifier))
(identifier))))))
(do_block
(binary_operator
(identifier)
(identifier)))))
=====================================
def / with guard
=====================================
def fun(x) when x == 1 do
x
end
---
(source
(call
(identifier)
(arguments
(binary_operator
(call
(identifier
(arguments
(identifier))))
(binary_operator
(identifier)
(integer))))
(do_block
(identifier))))
=====================================
def / with guard / multiple guards
=====================================
def fun(x) when x > 10 when x < 5 do
x
end
---
(source
(call
(identifier)
(arguments
(binary_operator
(call
(identifier
(arguments
(identifier))))
(binary_operator
(binary_operator
(identifier)
(integer))
(binary_operator
(identifier)
(integer)))))
(do_block
(identifier))))
=====================================
defp
=====================================
defp fun(x) do
x
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)))))
(do_block
(identifier))))
=====================================
defmacro
=====================================
defmacro fun(x) do
quote do
[unquote(x)]
end
end
---
(source
(call
(identifier)
(arguments
(call
(identifier
(arguments
(identifier)))))
(do_block
(call
(identifier)
(do_block
(list
(call
(identifier)
(arguments
(identifier)))))))))
=====================================
defguard
=====================================
defguard is_even(term) when is_integer(term) and rem(term, 2) == 0
---
(source
(call
(identifier)
(arguments
(binary_operator
(call
(identifier
(arguments
(identifier))))
(binary_operator
(call
(identifier)
(arguments
(identifier)))
(binary_operator
(call
(identifier)
(arguments
(identifier)
(integer)))
(integer)))))))

View File

@ -0,0 +1,136 @@
=====================================
for / enumerable
=====================================
for n <- [1, 2], do: n * 2
---
(source
(call
(identifier)
(arguments
(binary_operator
(identifier)
(list
(integer)
(integer))))
(keywords
(pair
(keyword
(atom_literal))
(binary_operator
(identifier)
(integer))))))
=====================================
for / enumerable / with options and block
=====================================
for line <- IO.stream(), into: IO.stream() do
String.upcase(line)
end
---
(source
(call
(identifier)
(arguments
(binary_operator
(identifier)
(call
(dot
(alias)
(identifier))))
(keywords
(pair
(keyword
(atom_literal))
(call
(dot
(alias)
(identifier))))))
(do_block
(call
(dot
(alias)
(identifier))
(arguments
(identifier))))))
=====================================
for / binary
=====================================
for <<c <- " hello world ">>, c != ?\s, into: "", do: <<c>>
---
(source
(call
(identifier)
(arguments
(binary
(binary_operator
(identifier)
(string
(string_content))))
(binary_operator
(identifier)
(char))
(keywords
(pair
(keyword
(atom_literal))
(string
(string_content)))
(pair
(keyword
(atom_literal))
(binary
(identifier)))))))
=====================================
for / reduce
=====================================
for x <- [1, 2, 1], reduce: %{} do
acc -> Map.update(acc, x, 1, & &1 + 1)
end
---
(source
(call
(identifier)
(arguments
(binary_operator
(identifier)
(list
(integer)
(integer)
(integer)))
(keywords
(pair
(keyword
(atom_literal))
(map))))
(do_block
(stab_clause
(arguments
(identifier))
(body
(call
(dot
(alias)
(identifier))
(arguments
(identifier)
(identifier)
(integer)
(unary_operator
(binary_operator
(unary_operator
(integer))
(integer))))))))))

View File

@ -0,0 +1,140 @@
=====================================
empty module definition
=====================================
defmodule Mod do
end
defmodule Mod.Child do
end
---
(source
(call
(identifier)
(arguments
(alias))
(do_block))
(call
(identifier)
(arguments
(alias))
(do_block)))
=====================================
module definition with atom literal
=====================================
defmodule :mod do
end
---
(source
(call
(identifier)
(arguments
(atom
(atom_literal)))
(do_block)))
=====================================
full module definition
=====================================
defmodule Mod do
@moduledoc """
Example module
"""
use UseMod
@attribute 1
@doc """
Example function
"""
@spec func(integer) :: integer
def func(x) when is_integer(x) do
priv(x) + priv(x)
end
defp priv(x), do: x * x
end
---
(source
(call
(identifier)
(arguments
(alias))
(do_block
(unary_operator
(call
(identifier)
(arguments
(string
(string_content)))))
(call
(identifier)
(arguments
(alias)))
(unary_operator
(call
(identifier)
(arguments
(integer))))
(unary_operator
(call
(identifier)
(arguments
(string
(string_content)))))
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(identifier)))
(identifier)))))
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(identifier)))
(call
(identifier)
(arguments
(identifier)))))
(do_block
(binary_operator
(call
(identifier)
(arguments
(identifier)))
(call
(identifier)
(arguments
(identifier))))))
(call
(identifier)
(arguments
(call
(identifier)
(arguments
(identifier)))
(keywords
(pair
(keyword
(atom_literal))
(binary_operator
(identifier)
(identifier)))))))))

View File

@ -0,0 +1,242 @@
=====================================
without type parentheses
=====================================
@spec fun(atom, integer, keyword) :: string
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(identifier)
(identifier)
(identifier)))
(identifier))))))
=====================================
with type parentheses
=====================================
@spec fun(atom(), integer(), keyword()) :: string()
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(call
(identifier))
(call
(identifier))
(call
(identifier))))
(call
(identifier)))))))
=====================================
with literals
=====================================
@spec fun(%{key: atom}) :: {:ok, atom} | {:error, binary}
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(map
(map_content
(keywords
(pair
(keyword
(atom_literal)
(identifier))))))))
(binary_operator
(tuple
(atom
(atom_literal))
(identifier))
(tuple
(atom
(atom_literal))
(identifier))))))))
=====================================
with function reference
=====================================
@spec fun((-> atom), (atom -> integer)) :: integer
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(stab_clause
(body
(identifier)))
(stab_clause
(arguments
(identifier))
(body
(identifier)))))
(identifier))))))
=====================================
with remote type
=====================================
@spec fun(Keyword.t()) :: String.t()
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(call
(dot
(alias)
(identifier)))))
(call
(dot
(alias)
(identifier))))))))
=====================================
with type guard
=====================================
@spec fun(arg1, arg2) :: {arg1, arg2} when arg1: atom, arg2: integer
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(binary_operator
(call
(identifier)
(arguments
(identifier)
(identifier)))
(tuple
(identifier)
(identifier)))
(keywords
(pair
(keyword
(atom_literal))
(identifier))
(pair
(keyword
(atom_literal))
(identifier))))))))
=====================================
with named arguments
=====================================
@spec days_since_epoch(year :: integer, month :: integer, day :: integer) :: integer
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(call
(identifier)
(arguments
(binary_operator
(identifier)
(identifier))
(binary_operator
(identifier)
(identifier))
(binary_operator
(identifier)
(identifier))))
(identifier))))))
=====================================
nonempty list
=====================================
@spec fun() :: [integer, ...]
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(identifier)
(list
(call
(identifier))
(identifier)))))))
=====================================
[error] type guard cannot end with keyword separator
=====================================
@spec fun(arg) :: arg when arg: atom,
---
(source
(unary_operator
(call
(identifier)
(arguments
(binary_operator
(binary_operator
(call
(identifier)
(arguments
(identifier)))
(identifier))
(keywords
(pair
(keyword
(atom_literal))
(identifier)))))))
(ERROR))

32
test/corpus/semicolon.txt Normal file
View File

@ -0,0 +1,32 @@
=====================================
separates expressions in the same line
=====================================
1 ; 1
---
(source (integer) (integer))
=====================================
trailing
=====================================
1;
2;
---
(source (integer) (integer))
=====================================
with comment
=====================================
1 ; # comment
---
(source
(integer)
(comment))

View File

@ -0,0 +1,88 @@
=====================================
single part
=====================================
Mod
AZ_az_19_
---
(source
(alias)
(alias)
(alias))
=====================================
multiple parts
=====================================
Mod.Child
Mod.Child.Child
---
(source
(alias)
(alias))
=====================================
qualified tuples
=====================================
Mod.{Child1, Child2}
---
(source
(dot
(alias)
(tuple
(alias)
(alias))))
=====================================
dot on identifier
=====================================
name.Mod
name.Mod.Child
---
(source
(dot
(identifier)
(alias))
(dot
(identifier)
(alias)))
=====================================
dot on special identifier
=====================================
__MODULE__.Child
(source
(dot
(special_identifier)
(alias)))
=====================================
[error] does not support characters outside ASCII
=====================================
Modこ
Ólá
Olá
---
(source
(alias)
(ERROR
(identifier))
(ERROR
(identifier))
(ERROR
(identifier)))

95
test/corpus/term/atom.txt Normal file
View File

@ -0,0 +1,95 @@
=====================================
simple literal
=====================================
:atom
:_az_AZ_19_
:nonode@nohost
:bang!
:question?
---
(source
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal)))
=====================================
operators
=====================================
[:~~~, :~>>, :~>, :|||, :||, :|>, :|, :>>>, :>=, :>, :=~, :===, :==, :=, :<~>, :<~, :<|>, :<>, :<=, :<<~, :<<<, :<-, :<, :+++, :++, :+, :^^^, :^, :&&&, :&&, :&, :\\, :/, :*, :@, :.., :., :!==, :!=, :!, :::, :->, :---, :--, :-]
---
(source
(list (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal)) (atom (atom_literal))))
=====================================
special operator-like atoms
=====================================
[:..., :%{}, :{}, :%, :<<>>, :..//]
---
(source
(list
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))))
=====================================
quoted atom
=====================================
:"atom ?? !! ' \n"
:'atom ?? !! " \n'
---
(source
(atom
(string_content)
(escape_sequence))
(atom
(string_content)
(escape_sequence)))
=====================================
interpolation
=====================================
:"hey #{name}!"
:'hey #{name}!'
---
(source
(atom
(string_content)
(interpolation
(identifier))
(string_content))
(atom
(string_content)
(interpolation
(identifier))
(string_content)))

View File

@ -0,0 +1,185 @@
=====================================
single item
=====================================
<<>>
<<10>>
<<10.0>>
<<"string">>
---
(source
(bitstring)
(bitstring
(integer))
(bitstring
(float))
(bitstring
(string
(string_content))))
=====================================
multiple items
=====================================
<<
10,
10.0,
"string"
>>
---
(source
(bitstring
(integer)
(float)
(string
(string_content))))
=====================================
size modifiers
=====================================
<<10::4>>
<<10::size(4)>>
---
(source
(bitstring
(binary_operator
(integer)
(integer)))
(bitstring
(binary_operator
(integer)
(call
(identifier)
(arguments
(integer))))))
=====================================
multiple modifiers
=====================================
<<"string"::utf8-big>>
<<"string"::utf16-big>>
<<"string"::utf32-big>>
<<10::32-little-unsigned>>
<<10::integer-signed-big>>
<<10.10::float-signed-native>>
---
(source
(bitstring
(binary_operator
(string
(string_content))
(binary_operator
(identifier)
(identifier)))
(binary_operator
(string
(string_content))
(binary_operator
(identifier)
(identifier)))
(binary_operator
(string
(string_content))
(binary_operator
(identifier)
(identifier)))
(binary_operator
(integer)
(binary_operator
(binary_operator
(integer)
(identifier))
(identifier)))
(binary_operator
(integer)
(binary_operator
(binary_operator
(identifier)
(identifier))
(identifier)))
(binary_operator
(float)
(binary_operator
(binary_operator
(identifier)
(identifier))
(identifier)))))
=====================================
multiple components with modifiers
=====================================
<<10::8-native, "string", 3.14::float, a::8, b::binary-size(known_size)>>
---
(source
(bitstring
(binary_operator
(integer)
(binary_operator
(integer)
(identifier)))
(string
(string_content))
(binary_operator
(float)
(identifier))
(binary_operator
(identifier)
(integer))
(binary_operator
(identifier)
(binary_operator
(identifier)
(call
(arguments
(identifier)))))))
=====================================
spacing
=====================================
<<
10 :: 8-native,
b :: binary - size(known_size)
>>
---
(source
(bitstring
(binary_operator
(integer)
(binary_operator
(integer)
(identifier)))
(binary_operator
(identifier)
(binary_operator
(identifier)
(call
(arguments
(identifier)))))))
=====================================
trailing separator
=====================================
<<1,>>
---
(source
(bitstring
(integer)))

View File

@ -0,0 +1,12 @@
=====================================
simple literal
=====================================
true
false
---
(source
(boolean)
(boolean))

55
test/corpus/term/char.txt Normal file
View File

@ -0,0 +1,55 @@
=====================================
regular character
=====================================
?a
?Z
?0
?9
?_
??
---
(source
(char)
(char)
(char)
(char)
(char)
(char))
=====================================
escaped character
=====================================
?\n
?\t
?\s
?\\
?\a
?\b
---
(source
(char)
(char)
(char)
(char)
(char)
(char))
=====================================
list of char literals
=====================================
[?a, ?b, ?c]
---
(source
(list
(char)
(char)
(char)))

View File

@ -0,0 +1,208 @@
=====================================
single line
=====================================
'Hello, 123!'
---
(source
(charlist
(string_content)))
=====================================
multiple lines
=====================================
'line 1
line 2'
---
(source
(charlist
(string_content)))
=====================================
interpolation
=====================================
'hey #{name}!'
'hey #{
name
}!'
'##{name}#'
---
(source
(charlist
(string_content)
(interpolation
(identifier))
(string_content))
(charlist
(string_content)
(interpolation
(identifier))
(string_content))
(charlist
(string_content)
(interpolation
(identifier))
(string_content)))
=====================================
nested interpolation
=====================================
'this is #{'number #{1}'}!'
---
(source
(charlist
(string_content)
(interpolation
(charlist
(string_content)
(interpolation
(identifier))))
(string_content)))
=====================================
escape sequence
=====================================
'_\'_\n_\t_\r_\e_\\_\1_\x3f_\u0065\u0301_'
---
(source
(charlist
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(escape_sequence)
(string_content)))
=====================================
escaped interpolation
=====================================
'\#{1}'
---
(source
(charlist
(escape_sequence)
(string_content)))
=====================================
heredoc / charlist
=====================================
'''
text
with 'quotes'
'''
---
(source
(charlist
(string_content)))
=====================================
heredoc / interpolation
=====================================
'''
hey #{name}!
'''
---
(source
(charlist
(string_content)
(interpolation
(identifier))
(string_content)))
=====================================
heredoc / nested interpolation
=====================================
'''
this is #{
'''
number #{1}
'''
}!
'''
---
(source
(charlist
(string_content)
(interpolation
(charlist
(string_content)
(interpolation
(identifier))))
(string_content)))
=====================================
heredoc / escaped delimiter
=====================================
'''
\'''
'''
'''
\'\'\'
'''
---
(source
(charlist
(escape_sequence)
(string_content)
(charlist
(escape_sequence)
(string_content)))
=====================================
heredoc / escaped interpolation
=====================================
'''
\#{1}
'''
---
(source
(charlist
(escape_sequence)
(string_content)))

View File

@ -0,0 +1,48 @@
=====================================
simple literal
=====================================
1234567890.1234567890
-1234567890.1234567890
-1_234_567_890.123_456_789_0
---
(source
(float)
(unary_operator
(float))
(unary_operator
(float)))
=====================================
scientific notation
=====================================
1.0e6
1.0e+6
1.0e-6
-1.0e6
-1.0e+6
-1.0e-6
1.0E6
1.0E+6
1.0E-6
1_234_567_890.123_456_789_0e1_234_567_890
---
(source
(float)
(float)
(float)
(unary_operator
(float))
(unary_operator
(float))
(unary_operator
(float))
(float)
(float)
(float)
(float))

View File

@ -0,0 +1,66 @@
=====================================
decimal
=====================================
1234567890
-1234567890
1_234_567_890
019
---
(source
(integer)
(unary_operator
(integer))
(integer)
(integer)
(integer))
=====================================
binary
=====================================
0b0101011
-0b0101011
0b0_10_10_11
---
(source
(integer)
(unary_operator
(integer))
(integer))
=====================================
octal
=====================================
0o1234567
-0o1234567
0o1_23_45_67
---
(source
(integer)
(unary_operator
(integer))
(integer))
=====================================
hexadecimal
=====================================
0x123456789abcdefABCDEF
-0x123456789abcdefABCDEF
0x123456789_abcdef_ABCDEF
---
(source
(integer)
(unary_operator
(integer))
(integer))

View File

@ -0,0 +1,158 @@
=====================================
simple literal
=====================================
[a_b@12?: 1, A_B@12!: 2]
---
(source
(list
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer)))))
=====================================
trailing separator
=====================================
[a: 1,]
---
(source
(list
(keywords
(pair
(keyword
(atom_literal))
(integer)))))
=====================================
with leading items
=====================================
[1, {:c, 1}, a: 1, b: 2]
---
(source
(list
(integer)
(tuple
(atom
(atom_literal))
(integer))
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer)))))
=====================================
operator key
=====================================
[~~~: 1, ==: 2, >: 3]
---
(source
(list
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer)))))
=====================================
quoted key
=====================================
[
"key1 ?? !! ' \n": 1,
'key2 ?? !! " \n': 2
]
---
(source
(list
(keywords
(pair
(keyword
(string_content)
(escape_sequence))
(integer))
(pair
(keyword
(string_content)
(escape_sequence))
(integer)))))
=====================================
key interpolation
=====================================
[
"hey #{name}!": 1,
'hey #{name}!': 2
]
---
(source
(list
(keywords
(pair
(keyword
(string_content)
(interpolation
(identifier))
(string_content))
(integer))
(pair
(keyword
(string_content)
(interpolation
(identifier))
(string_content))
(integer)))))
=====================================
[error] with trailing items
=====================================
[a: 1, b: 2, 1]
---
(source
(list
(ERROR
(keywords
(pair
(keyword
(atom_literal)))
(pair
(keyword
(atom_literal)))))
(integer)))

82
test/corpus/term/list.txt Normal file
View File

@ -0,0 +1,82 @@
=====================================
simple literal
=====================================
[]
[1]
[1, 2]
[1,2]
[ 1 , 2 ]
---
(source
(list)
(list
(integer))
(list
(integer)
(integer))
(list
(integer)
(integer))
(list
(integer)
(integer)))
=====================================
nested
=====================================
[[1], 1]
---
(source
(list
(list
(integer))
(integer)))
=====================================
trailing separator
=====================================
[1,]
[1,2,]
---
(source
(list
(integer))
(list
(integer)
(integer)))
=====================================
[error] missing element
=====================================
[, 1]
---
(source
(list
(ERROR
(integer))))
=====================================
[error] missing separator
=====================================
[1 2]
---
(source
(list
(integer)
(ERROR
(integer))))

201
test/corpus/term/map.txt Normal file
View File

@ -0,0 +1,201 @@
=====================================
empty
=====================================
%{}
---
(source
(map))
=====================================
from keywords
=====================================
%{a: 1, b: 2}
---
(source
(map
(map_content
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
from arrow entries
=====================================
%{:a => 1, "b" => 2, c => 3}
---
(source
(map
(map_content
(binary_operator
(atom
(atom_literal))
(integer))
(binary_operator
(string
(string_content))
(integer))
(binary_operator
(identifier)
(integer)))))
=====================================
from both arrow entries and keywords
=====================================
%{"a" => 1, b: 2, c: 3}
---
(source
(map
(map_content
(binary_operator
(string
(string_content))
(integer))
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
trailing separator
=====================================
%{"a" => 1,}
---
(source
(map
(map_content
(binary_operator
(string
(string_content))
(integer)))))
=====================================
update syntax
=====================================
%{user | name: "Jane", email: "jane@example.com"}
%{user | "name" => "Jane"}
---
(source
(map
(map_content
(binary_operator
(identifier)
(keywords
(pair
(keyword
(atom_literal))
(string
(string_content)))
(pair
(keyword
(atom_literal))
(string
(string_content)))))))
(map
(map_content
(binary_operator
(identifier)
(binary_operator
(string
(string_content))
(integer))))))
=====================================
[error] ordering
=====================================
%{b: 2, c: 3, "a" => 1}
---
(source
(map
(map_content)
(ERROR
(keywords
(pair
(keyword
(atom_literal)))
(pair
(keyword
(atom_literal)))))
(binary_operator
(string
(string_content))
(integer))))
=====================================
[error] missing separator
=====================================
%{"a" => 1 "b" => 2}
---
(source
(map
(map_content)
(ERROR
(binary_operator
(string
(string_content))
(integer)))
(binary_operator
(string
(string_content))
(integer))))
=====================================
[error] invalid content
=====================================
%{1}
%{1, 1}
%{a, [], {}}
---
(source
(map
(map_content
(ERROR
(integer))))
(map
(map_content
(ERROR
(integer)
(integer))))
(map
(map_content
(ERROR
(identifier)
(list)
(tuple)))))

10
test/corpus/term/nil.txt Normal file
View File

@ -0,0 +1,10 @@
=====================================
simple literal
=====================================
nil
---
(source
(nil))

220
test/corpus/term/string.txt Normal file
View File

@ -0,0 +1,220 @@
=====================================
single line
=====================================
"Hello, 123!"
---
(source
(string
(string_content)))
=====================================
multiple lines
=====================================
"line 1
line 2"
---
(source
(string
(string_content)))
=====================================
interpolation
=====================================
"hey #{name}!"
"hey #{
name
}!"
"##{name}#"
---
(source
(string
(string_content)
(interpolation
(identifier))
(string_content))
(string
(string_content)
(interpolation
(identifier))
(string_content))
(string
(string_content)
(interpolation
(identifier))
(string_content)))
=====================================
nested interpolation
=====================================
"this is #{"number #{1}"}!"
---
(source
(string
(string_content)
(interpolation
(string
(string_content)
(interpolation
(identifier))))
(string_content)))
=====================================
escape sequence
=====================================
"_\"_\n_\t_\r_\e_\\_\1_\x3f_\u0065\u0301_"
---
(source
(string
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(string_content)
(escape_sequence)
(escape_sequence)
(string_content)))
=====================================
escaped interpolation
=====================================
"\#{1}"
---
(source
(string
(escape_sequence)
(string_content)))
=====================================
heredoc / string
=====================================
"""
text
with "quotes"
"""
---
(source
(string
(string_content)))
=====================================
heredoc / interpolation
=====================================
"""
hey #{name}!
"""
---
(source
(string
(string_content)
(interpolation
(identifier))
(string_content)))
=====================================
heredoc / nested interpolation
=====================================
"""
this is #{
"""
number #{1}
"""
}!
"""
---
(source
(string
(string_content)
(interpolation
(string
(string_content)
(interpolation
(identifier))))
(string_content)))
=====================================
heredoc / escaped delimiter
=====================================
"""
\"""
"""
"""
\"\"\"
"""
---
(source
(string
(escape_sequence)
(string_content)
(string
(escape_sequence)
(string_content)))
=====================================
heredoc / escaped interpolation
=====================================
"""
\#{1}
"""
---
(source
(string
(escape_sequence)
(string_content)))
=====================================
[error] heredoc / no whitespace
=====================================
"""s"""
---
(source
(ERROR
(identifier)))

201
test/corpus/term/struct.txt Normal file
View File

@ -0,0 +1,201 @@
=====================================
empty
=====================================
%User{}
---
(source
(map
(struct
(alias))))
=====================================
from keywords
=====================================
%User{a: 1, b: 2}
---
(source
(map
(struct
(alias))
(map_content
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
from arrow entries
=====================================
%User{:a => 1, "b" => 2, c => 3}
---
(source
(map
(struct
(alias))
(map_content
(binary_operator
(atom
(atom_literal))
(integer))
(binary_operator
(string
(string_content))
(integer))
(binary_operator
(identifier)
(integer)))))
=====================================
from both arrow entries and keywords
=====================================
%User{"a" => 1, b: 2, c: 3}
---
(source
(map
(struct
(alias))
(map_content
(binary_operator
(string
(string_content))
(integer))
(keywords
(pair
(keyword
(atom_literal))
(integer))
(pair
(keyword
(atom_literal))
(integer))))))
=====================================
trailing separator
=====================================
%User{"a" => 1,}
---
(source
(map
(struct
(alias))
(map_content
(binary_operator
(string
(string_content))
(integer)))))
=====================================
update syntax
=====================================
%User{user | name: "Jane", email: "jane@example.com"}
%User{user | "name" => "Jane"}
---
(source
(map
(struct (alias))
(map_content
(binary_operator
(identifier)
(keywords
(pair
(keyword
(atom_literal))
(string
(string_content)))
(pair
(keyword
(atom_literal))
(string
(string_content)))))))
(map
(struct
(alias))
(map_content
(binary_operator
(identifier)
(binary_operator
(string
(string_content))
(integer))))))
=====================================
unused struct identifier
=====================================
%_{}
---
(source
(map
(struct
(unused_identifier))))
=====================================
matching struct identifier
=====================================
%name{}
---
(source
(map
(struct
(identifier))))
=====================================
pinned struct identifier
=====================================
%^name{}
---
(source
(map
(struct
(unary_operator
(identifier)))))
=====================================
with special identifier
=====================================
%__MODULE__{}
%__MODULE__.Child{}
---
(source
(map
(struct
(special_identifier)))
(map
(struct
(dot
(special_identifier)
(alias)))))

View File

@ -0,0 +1,82 @@
=====================================
simple literal
=====================================
{}
{1}
{1, 2}
{1,2}
{ 1 , 2 }
---
(source
(tuple)
(tuple
(integer))
(tuple
(integer)
(integer))
(tuple
(integer)
(integer))
(tuple
(integer)
(integer)))
=====================================
nested
=====================================
{{1}, 1}
---
(source
(tuple
(tuple
(integer))
(integer)))
=====================================
trailing separator
=====================================
{1,}
{1,2,}
---
(source
(tuple
(integer))
(tuple
(integer)
(integer)))
=====================================
[error] missing element
=====================================
{, 1}
---
(source
(tuple
(ERROR
(integer))))
=====================================
[error] missing separator
=====================================
{1 2}
---
(source
(tuple
(integer)
(ERROR
(integer))))

114
test/corpus/unicode.txt Normal file
View File

@ -0,0 +1,114 @@
=====================================
atom
=====================================
:time_μs
:"£"
:'£'
:こんにちは世界
:Ólá
:olá
:Olá
---
(source
(atom
(atom_literal))
(atom
(string_content))
(atom
(string_content))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal))
(atom
(atom_literal)))
=====================================
string
=====================================
"time_μs"
"£"
"こんにちは世界"
"Ólá"
"olá"
"Olá"
---
(source
(string
(string_content))
(string
(string_content))
(string
(string_content))
(string
(string_content))
(string
(string_content))
(string
(string_content)))
=====================================
charlist
=====================================
'time_μs'
'£'
'こんにちは世界'
'Ólá'
'olá'
'Olá'
---
(source
(charlist
(string_content))
(charlist
(string_content))
(charlist
(string_content))
(charlist
(string_content))
(charlist
(string_content))
(charlist
(string_content)))
=====================================
char
=====================================
?こ
---
(source
(char)
(char)
(char)
(char))
=====================================
variable
=====================================
time_μs
こんにちは世界
olá
---
(source
(identifier)
(identifier)
(identifier))

63
test/corpus/variable.txt Normal file
View File

@ -0,0 +1,63 @@
=====================================
regular
=====================================
snake_case
camelCase
az_AZ_19
bang!
question?
__TEST__
doctest
not1
notfalse
---
(source
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(identifier))
=====================================
unused
=====================================
_
_number
---
(source
(unused_identifier)
(unused_identifier))
=====================================
three dots identifier
=====================================
...
---
(source
(identifier))
=====================================
special identifier
=====================================
__MODULE__
__DIR__
---
(source
(special_identifier)
(special_identifier))