Merge pull request #23 from maxbrunsfeld/cleaner-integration-tests

Make it easier to write integration tests
This commit is contained in:
Max Brunsfeld 2016-01-15 11:23:39 -08:00
commit aaa77d69ec
100 changed files with 922 additions and 91611 deletions

3
.gitignore vendored
View file

@ -10,3 +10,6 @@ spec/run.out*
externals/cpplint.py
out
*.pyc
spec/fixtures/*
!spec/fixtures/.gitkeep

View file

@ -9,4 +9,4 @@ addons:
- libboost-regex-dev
install: script/configure.sh -D USE_BOOST_REGEX=true -D USE_LIBPROFILER=false
script: script/test_all.sh
script: script/ci

View file

@ -54,11 +54,16 @@ int main() {
{
"name": "arithmetic",
// Things that can appear anywhere in the language, like comments
// and whitespace, are expressed as 'extras'.
"extras": [
{"type": "PATTERN", "value": "\\s"},
{"type": "SYMBOL", "name": "comment"}
],
"rules": {
// The first rule listed in the grammar becomes the 'start rule'.
"expression": {
"type": "CHOICE",
"members": [
@ -70,13 +75,22 @@ int main() {
"type": "SEQ",
"members": [
{"type": "STRING", "value": "("},
{"type": "SYMBOL", "name": "expression"},
// Error recovery is controlled by wrapping rule subtrees
// in an 'ERROR' rule.
{
"type": "ERROR",
"content": {"type": "SYMBOL", "name": "expression"}
},
{"type": "STRING", "value": ")"}
]
}
]
},
// Tokens like '+' and '*' are described directly within the
// grammar's rules, as opposed to in a seperate lexer description.
"sum": {
"type": "PREC_LEFT",
"value": 1,
@ -90,6 +104,8 @@ int main() {
}
},
// Ambiguities can be resolved at compile time by assigning precedence
// values to rule subtrees.
"product": {
"type": "PREC_LEFT",
"value": 2,
@ -103,7 +119,9 @@ int main() {
}
},
"number": {"type": "PATTERN", "value": "\\d+"}
// Tokens can be specified using ECMAScript regexps.
"number": {"type": "PATTERN", "value": "\\d+"},
"comment": {"type": "PATTERN", "value": "#.*"},
"variable": {"type": "PATTERN", "value": "[a-zA-Z]\\w*"},
}
}

6
script/ci Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e
script/fetch_languages
script/test

27
script/fetch_languages Executable file
View file

@ -0,0 +1,27 @@
#!/usr/bin/env bash
GRAMMARS_DIR=$(dirname $0)/../spec/grammars
GRAMMARS=(
javascript
json
c
cpp
)
for grammar in ${GRAMMARS[@]}; do
echo "Fetching ${grammar} grammar..."
grammar_dir=${GRAMMARS_DIR}/${grammar}
grammar_url=https://github.com/maxbrunsfeld/tree-sitter-${grammar}
if [ ! -d $grammar_dir ]; then
git clone $grammar_url $grammar_dir
fi
(
cd $grammar_dir;
git reset --hard;
git pull origin master;
)
done

91
script/test Executable file
View file

@ -0,0 +1,91 @@
#!/usr/bin/env bash
function usage {
cat <<-EOF
USAGE
$0 [-dghv] [-f focus-string]
OPTIONS
-h print this message
-d run tests in a debugger (either lldb or gdb)
-g run tests with valgrind
-v run tests with verbose output
-f run only tests whose description contain the given string
EOF
}
profile=
mode=normal
args=()
target=tests
cmd="out/Debug/${target}"
while getopts "df:s:ghpv" option; do
case ${option} in
h)
usage
exit
;;
d)
mode=debug
;;
g)
mode=valgrind
;;
p)
profile=true
;;
f)
args+=("--only=${OPTARG}")
;;
v)
args+=("--reporter=spec")
;;
s)
export TREE_SITTER_SEED=${OPTARG}
;;
esac
done
BUILDTYPE=Debug make $target
args=${args:-""}
if [[ -n $profile ]]; then
export CPUPROFILE=/tmp/${target}-$(date '+%s').prof
fi
case ${mode} in
valgrind)
valgrind \
--suppressions=./script/util/valgrind.supp \
--dsymutil=yes \
$cmd "${args[@]}" 2>&1 | \
grep --color -E '\w+_specs?.cc:\d+|$'
;;
debug)
if which -s lldb; then
lldb $cmd -- "${args[@]}"
elif which -s gdb; then
gdb $cmd -- "${args[@]}"
else
echo "No debugger found"
exit 1
fi
;;
normal)
time $cmd "${args[@]}"
;;
esac
if [[ -n $profile ]]; then
pprof $cmd $CPUPROFILE
fi

View file

@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -e
script/test_compiler.sh
script/test_runtime.sh

View file

@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -e -u
source `dirname $0`/util/run_tests.sh
run_tests compiler_specs "$@"

View file

@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -e -u
source `dirname $0`/util/run_tests.sh
run_tests runtime_specs "$@"

View file

@ -1,92 +0,0 @@
function usage {
cat <<-EOF
USAGE
$0 [-dghv] [-f focus-string]
OPTIONS
-h print this message
-d run tests in a debugger (either lldb or gdb)
-g run tests with valgrind
-v run tests with verbose output
-f run only tests whose description contain the given string
EOF
}
function run_tests {
local profile=
local mode=normal
local args=()
local target=$1
local cmd="out/Debug/${target}"
shift
while getopts "df:s:ghpv" option; do
case ${option} in
h)
usage
exit
;;
d)
mode=debug
;;
g)
mode=valgrind
;;
p)
profile=true
;;
f)
args+=("--only=${OPTARG}")
;;
v)
args+=("--reporter=spec")
;;
s)
export TREE_SITTER_SEED=${OPTARG}
;;
esac
done
BUILDTYPE=Debug make $target
args=${args:-""}
if [[ -n $profile ]]; then
export CPUPROFILE=/tmp/${target}-$(date '+%s').prof
fi
case ${mode} in
valgrind)
valgrind \
--suppressions=./script/util/valgrind.supp \
--dsymutil=yes \
$cmd "${args[@]}" 2>&1 | \
grep --color -E '\w+_specs?.cc:\d+|$'
;;
debug)
if which -s lldb; then
lldb $cmd -- "${args[@]}"
elif which -s gdb; then
gdb $cmd -- "${args[@]}"
else
echo "No debugger found"
exit 1
fi
;;
normal)
time $cmd "${args[@]}"
;;
esac
if [[ -n $profile ]]; then
pprof $cmd $CPUPROFILE
fi
}

View file

@ -1,6 +1,8 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/rules/character_set.h"
#include "compiler/build_tables/does_match_any_line.h"
#include "helpers/rule_helpers.h"
#include "compiler/rules.h"
using namespace rules;
using namespace build_tables;

View file

@ -1,4 +1,4 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/syntax_grammar.h"
#include "compiler/build_tables/item_set_closure.h"
#include "compiler/build_tables/lookahead_set.h"

View file

@ -1,4 +1,4 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/rules/built_in_symbols.h"
#include "compiler/parse_table.h"
#include "compiler/build_tables/lex_conflict_manager.h"

View file

@ -1,6 +1,8 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/build_tables/lex_item.h"
#include "compiler/rules/metadata.h"
#include "compiler/rules.h"
#include "helpers/rule_helpers.h"
using namespace rules;
using namespace build_tables;

View file

@ -1,4 +1,4 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/rules/built_in_symbols.h"
#include "compiler/parse_table.h"
#include "compiler/build_tables/parse_conflict_manager.h"

View file

@ -1,7 +1,7 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/build_tables/parse_item.h"
#include "compiler/syntax_grammar.h"
#include "compiler/helpers/rule_helpers.h"
#include "helpers/rule_helpers.h"
using namespace rules;
using namespace build_tables;

View file

@ -1,6 +1,8 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/build_tables/rule_can_be_blank.h"
#include "compiler/rules/metadata.h"
#include "compiler/rules.h"
#include "helpers/rule_helpers.h"
using namespace rules;
using build_tables::rule_can_be_blank;

View file

@ -1,57 +0,0 @@
#include "compiler/compiler_spec_helper.h"
#include "compiler/compile.h"
#include <fstream>
#include <iostream>
static string src_dir() {
const char * dir = getenv("TREESITTER_DIR");
if (!dir) dir = getenv("PWD");
return dir;
}
namespace tree_sitter_examples {
extern const Grammar arithmetic;
extern const Grammar javascript;
extern const Grammar json;
extern const Grammar golang;
extern const Grammar c;
extern const Grammar cpp;
extern const Grammar anonymous_tokens;
} // namespace tree_sitter_examples
START_TEST
describe("compiling the example grammars", []() {
string example_parser_dir = src_dir() + "/spec/fixtures/parsers/";
auto compile_grammar = [&](const Grammar &grammar, string language) {
it(("compiles the " + language + " grammar").c_str(), [&]() {
auto result = compile(grammar, language);
string code = result.first;
const CompileError error = result.second;
if (error.type)
AssertThat(error.message, Equals(""));
ofstream file(example_parser_dir + language + ".c");
file << get<0>(result);
file.close();
});
};
// example languages
compile_grammar(tree_sitter_examples::arithmetic, "arithmetic");
compile_grammar(tree_sitter_examples::json, "json");
compile_grammar(tree_sitter_examples::javascript, "javascript");
compile_grammar(tree_sitter_examples::golang, "golang");
compile_grammar(tree_sitter_examples::c, "c");
compile_grammar(tree_sitter_examples::cpp, "cpp");
// edge cases
compile_grammar(tree_sitter_examples::anonymous_tokens, "anonymous_tokens");
});
END_TEST

View file

@ -1,47 +0,0 @@
#include "compiler/compiler_spec_helper.h"
#include "compiler/compile.h"
using namespace rules;
START_TEST
describe("compile_grammar", []() {
describe("when the grammar's start symbol is a token", [&]() {
it("does not fail", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON(
{
"name": "the_grammar",
"rules": {
"rule1": {
"type": "STRING",
"value": "hello"
}
}
}
)JSON");
AssertThat(string(result.error_message), IsEmpty());
AssertThat(string(result.code), !IsEmpty());
});
});
describe("when the grammar's start symbol is blank", [&]() {
it("does not fail", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON(
{
"name": "the_grammar",
"rules": {
"rule1": {
"type": "BLANK"
}
}
}
)JSON");
AssertThat(string(result.error_message), IsEmpty());
AssertThat(string(result.code), !IsEmpty());
});
});
});
END_TEST

View file

@ -1,17 +0,0 @@
#ifndef __tree_sitter_compiler_spec_helper_h__
#define __tree_sitter_compiler_spec_helper_h__
#include "bandit/bandit.h"
#include "compiler/helpers/stream_methods.h"
#include "compiler/helpers/equals_pointer.h"
#include "compiler/helpers/rule_helpers.h"
#include "compiler/rules.h"
using namespace tree_sitter;
using namespace std;
using namespace bandit;
#define START_TEST go_bandit([]() {
#define END_TEST });
#endif

View file

@ -1,5 +0,0 @@
#include "compiler/compiler_spec_helper.h"
int main(int argc, char *argv[]) {
return bandit::run(argc, argv);
}

View file

@ -1,6 +1,7 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/prepare_grammar/initial_syntax_grammar.h"
#include "compiler/prepare_grammar/expand_repeats.h"
#include "helpers/rule_helpers.h"
START_TEST

View file

@ -1,6 +1,7 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/lexical_grammar.h"
#include "compiler/prepare_grammar/expand_tokens.h"
#include "helpers/rule_helpers.h"
START_TEST

View file

@ -1,5 +1,6 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/prepare_grammar/extract_choices.h"
#include "helpers/rule_helpers.h"
START_TEST

View file

@ -1,8 +1,10 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/lexical_grammar.h"
#include "compiler/prepare_grammar/interned_grammar.h"
#include "compiler/prepare_grammar/initial_syntax_grammar.h"
#include "compiler/prepare_grammar/extract_tokens.h"
#include "helpers/rule_helpers.h"
#include "helpers/equals_pointer.h"
START_TEST

View file

@ -1,8 +1,9 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/prepare_grammar/flatten_grammar.h"
#include "compiler/prepare_grammar/initial_syntax_grammar.h"
#include "compiler/syntax_grammar.h"
#include "compiler/rules/built_in_symbols.h"
#include "helpers/rule_helpers.h"
template<typename T, typename Func>
std::vector<typename std::result_of<Func(T)>::type>

View file

@ -1,7 +1,10 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/prepare_grammar/intern_symbols.h"
#include "compiler/grammar.h"
#include "compiler/rules/named_symbol.h"
#include "compiler/rules/symbol.h"
#include "helpers/equals_pointer.h"
#include "helpers/rule_helpers.h"
START_TEST

View file

@ -1,5 +1,7 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/prepare_grammar/parse_regex.h"
#include "helpers/equals_pointer.h"
#include "helpers/rule_helpers.h"
START_TEST

View file

@ -1,4 +1,4 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/rules/character_set.h"
using namespace rules;

View file

@ -1,5 +1,7 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/rules/choice.h"
#include "helpers/rule_helpers.h"
#include "helpers/equals_pointer.h"
using namespace rules;

View file

@ -1,4 +1,4 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/rules/repeat.h"
#include "compiler/rules/symbol.h"

View file

@ -1,7 +1,6 @@
#include "compiler/compiler_spec_helper.h"
#include "spec_helper.h"
#include "compiler/util/string_helpers.h"
using namespace rules;
using util::escape_char;
START_TEST

0
spec/fixtures/.gitkeep vendored Normal file
View file

View file

@ -1,22 +0,0 @@
=====================================================
errors at the top level
=====================================================
x * * y
---
(ERROR (variable) (UNEXPECTED '*') (variable))
=====================================================
errors inside parenthesized expressions
=====================================================
x + (y * + z) * 5
---
(program (sum
(variable)
(product
(group (ERROR (variable) (UNEXPECTED '+') (variable))) (number))))

View file

@ -1,37 +0,0 @@
====================================
variables with greek letters
====================================
φη12ψ + aγδεε
---
(program (sum (variable) (variable)))
===============================================
operators of different precedence
===============================================
ε * δ + c * d
---
(program (sum
(product (variable) (variable))
(product (variable) (variable))))
============================
exponents
============================
x + y * z^(a + b)
---
(program (sum
(variable)
(product
(variable)
(exponent
(variable)
(group (sum (variable) (variable)))))))

View file

@ -1,135 +0,0 @@
==========================================
ambiguous declarations
==========================================
int main() {
// declare a function pointer
A * b(int a);
// evaluate an expression
c * d(5);
}
---
(translation_unit (function_definition
(identifier)
(function_declarator (identifier))
(compound_statement
(comment)
(declaration
(identifier)
(pointer_declarator (function_declarator (identifier) (parameter_declaration (identifier) (identifier)))))
(comment)
(expression_statement (math_expression
(identifier)
(call_expression (identifier) (number)))))))
==========================================
ambiguous expressions
==========================================
/*
* ambiguities
*/
int main() {
// cast
a((B *)c);
// parenthesized product
d((e * f));
}
---
(translation_unit
(comment)
(function_definition
(identifier)
(function_declarator (identifier))
(compound_statement
(comment)
(expression_statement (call_expression
(identifier)
(cast_expression (type_name (identifier) (abstract_pointer_declarator)) (identifier))))
(comment)
(expression_statement (call_expression
(identifier)
(math_expression (identifier) (identifier)))))))
==========================================
function-like macros that produce types
==========================================
// this is a macro
GIT_INLINE(int) x = 5;
---
(translation_unit
(comment)
(declaration
(macro_type (identifier) (identifier))
(identifier)
(initializer (number))))
============================================
3-way ambiguities (regression)
============================================
int main() {
/*
* Could be either:
* - function call
* - declaration w/ parenthesized declarator
* - declaration w/ macro type, no declarator
*/
ABC(d);
/*
* Normal declaration
*/
efg hij;
}
---
(translation_unit
(function_definition
(identifier)
(function_declarator (identifier))
(compound_statement
(comment)
(declaration (identifier) (identifier))
(comment)
(declaration (identifier) (identifier)))))
=========================================
Comments after for loops with ambiguities
===========================================
int main() {
for (a *b = c; d; e) {
aff;
}
// a-comment
g;
}
---
(translation_unit (function_definition
(identifier)
(function_declarator (identifier))
(compound_statement
(for_statement
(declaration (identifier) (pointer_declarator (identifier)) (initializer (identifier)))
(identifier)
(identifier)
(compound_statement
(expression_statement (identifier))))
(comment)
(expression_statement (identifier)))))

View file

@ -1,26 +0,0 @@
==========================================
errors in top-level declarations
==========================================
int int int;
int y;
---
(translation_unit
(declaration (ERROR (identifier) (identifier) (UNEXPECTED 'i') (identifier)))
(declaration (identifier) (identifier)))
==========================================
errors in compound statements
==========================================
int main() { %%% }
---
(translation_unit (function_definition
(identifier)
(function_declarator (identifier))
(compound_statement
(ERROR (UNEXPECTED '%')))))

View file

@ -1,13 +0,0 @@
=============================================
#defines
=============================================
#define THING abc def \
ghi jkl
#define OTHER_THING mno
---
(translation_unit
(preproc_define (identifier) (preproc_arg))
(preproc_define (identifier) (preproc_arg)))

View file

@ -1,59 +0,0 @@
==================================================
function calls
==================================================
int main() {
printf("hello %s", "world");
}
---
(translation_unit (function_definition
(type_specifier (identifier))
(declarator (direct_declarator (direct_declarator (identifier))))
(function_body (compound_statement
(expression_statement (call_expression (identifier) (string) (string)))))))
==================================================
template function / relational expression ambiguities
==================================================
int main() {
someVariable < someValue > 0.0;
someTemplate<SomeType>(0, 0);
}
---
(translation_unit (function_definition
(type_specifier (identifier))
(declarator (direct_declarator (direct_declarator (identifier))))
(function_body (compound_statement
(expression_statement
(relational_expression
(relational_expression (identifier) (identifier))
(number)))
(expression_statement
(call_expression
(template_call (identifier) (type_id (type_specifier (identifier))))
(number) (number)))))))
==================================================
template class / relational expression ambiguities
==================================================
int main() {
SomeTemplate<SomeType> someVariable = 1;
}
---
(translation_unit (function_definition
(type_specifier (identifier))
(declarator (direct_declarator (direct_declarator (identifier))))
(function_body (compound_statement
(simple_declaration
(type_specifier (template_call (identifier) (type_id (type_specifier (identifier)))))
(init_declarator
(declarator (direct_declarator (identifier)))
(initializer (initializer_clause (number)))))))))

View file

@ -1,41 +0,0 @@
==========================================
simple declarations
==========================================
package trivial
var X struct { Y int64 }
type x int64
var y = ""
func z() {}
---
(program
(package_directive (package_name))
(var_declaration (var_name) (struct_type (var_name) (type_name)))
(type_declaration (type_name) (type_name))
(var_declaration (var_name) (string))
(func_declaration (var_name) (block_statement)))
==========================================
comments
==========================================
package trivial
var x = 1 // on variable
// between declarations
func main() {
// in function
}
---
(program
(package_directive (package_name))
(var_declaration (var_name) (number) (comment))
(comment)
(func_declaration (var_name) (block_statement (comment))))

View file

@ -1,15 +0,0 @@
==========================================
indented code after blocks
=========================================
package trivial
func one() {}
func two() {}
---
(program
(package_directive (package_name))
(func_declaration (var_name) (block_statement))
(func_declaration (var_name) (block_statement)))

View file

@ -1,38 +0,0 @@
==========================================
function calls
==========================================
package main
func main() {
println("1", 2)
println()
}
---
(program
(package_directive (package_name))
(func_declaration (var_name) (block_statement
(expression_statement (call_expression (var_name) (string) (number)))
(expression_statement (call_expression (var_name))))))
============================================
selector expressions
============================================
package main
func main() {
x.SomeMethod(x.SomeField, x.OtherField.NestedField);
}
---
(program
(package_directive (package_name))
(func_declaration (var_name) (block_statement
(expression_statement (call_expression
(selector_expression (var_name) (var_name))
(selector_expression (var_name) (var_name))
(selector_expression (selector_expression (var_name) (var_name)) (var_name)))))))

View file

@ -1,97 +0,0 @@
============================================
return statements
============================================
package main
func main() {
return
}
func helper() {
return 1, two, "three"
}
---
(program (package_directive (package_name))
(func_declaration (var_name) (block_statement
(return_statement)))
(func_declaration (var_name) (block_statement
(return_statement (number) (var_name) (string)))))
============================================
variable declarations
============================================
package main
func main() {
x, y := stuff()
var z = 10
println(x, y, z)
}
---
(program (package_directive (package_name))
(func_declaration (var_name) (block_statement
(short_var_declaration (var_name) (var_name) (call_expression (var_name)))
(var_declaration (var_name) (number))
(expression_statement (call_expression (var_name) (var_name) (var_name) (var_name))))))
============================================
if statements
============================================
package main
func main() {
if condition1() {
}
if condition2() {
} else {
}
if condition3() {
} else if condition4() {
}
}
---
(program (package_directive (package_name))
(func_declaration (var_name) (block_statement
(if_statement (call_expression (var_name))
(block_statement))
(if_statement (call_expression (var_name))
(block_statement) (block_statement))
(if_statement (call_expression (var_name))
(block_statement)
(if_statement (call_expression (var_name))
(block_statement))))))
=============================================
range statements
=============================================
package main
func main() {
for k := range theMap() {
println(k)
}
for k, v := range theMap() {
println(k, v)
}
}
---
(program (package_directive (package_name))
(func_declaration (var_name) (block_statement
(range_statement (var_name) (call_expression (var_name)) (block_statement
(expression_statement (call_expression (var_name) (var_name)))))
(range_statement (var_name) (var_name) (call_expression (var_name)) (block_statement
(expression_statement (call_expression (var_name) (var_name) (var_name))))))))

View file

@ -1,76 +0,0 @@
==========================================
composite types
==========================================
package main
type x *struct {
field1 []int64
field2 map[string]interface{
DoStuff()
}
}
---
(program
(package_directive (package_name))
(type_declaration
(type_name)
(pointer_type (struct_type
(var_name) (slice_type (type_name))
(var_name) (map_type (type_name) (interface_type (var_name)))))))
============================================
functions arguments
============================================
package main
func oneArg(arg1 interface{}) {}
func argsOfSameType(arg1, arg2 string) {}
func argsOfDifferentTypes() (arg1 string, arg2 int64) {}
---
(program
(package_directive (package_name))
(func_declaration (var_name) (var_name) (interface_type) (block_statement))
(func_declaration (var_name) (var_name) (var_name) (type_name) (block_statement))
(func_declaration (var_name) (var_name) (type_name) (var_name) (type_name) (block_statement)))
============================================
functions with unnamed return values
============================================
package main
func oneReturnValue() string {}
func multipleReturnValues() (string, int64, error) {}
---
(program
(package_directive (package_name))
(func_declaration (var_name) (type_name)
(block_statement))
(func_declaration (var_name) (type_name) (type_name) (type_name)
(block_statement)))
============================================
functions with named return values
============================================
package main
func oneReturnValue() (result string) {}
func multipleReturnValues() (result string, count int64, err error) {}
---
(program
(package_directive (package_name))
(func_declaration (var_name) (var_name) (type_name)
(block_statement))
(func_declaration (var_name) (var_name) (type_name) (var_name) (type_name) (var_name) (type_name)
(block_statement)))

View file

@ -1,260 +0,0 @@
==========================================
multiple statements
==========================================
var x = {}, z, i = 0;
firstFunction(x)
secondFunction(x);
---
(program
(var_declaration
(var_assignment (identifier) (object))
(identifier)
(var_assignment (identifier) (number)))
(expression_statement (function_call (identifier) (arguments (identifier))))
(expression_statement (function_call (identifier) (arguments (identifier)))))
==========================================
if statements
==========================================
if (isReady()) {
console.log(theData)
}
---
(program (if_statement (function_call (identifier) (arguments))
(statement_block (expression_statement
(function_call (member_access (identifier) (identifier)) (arguments (identifier)))))))
==========================================
if statements whose bodies are objects
==========================================
if (a) {
b()
{
c();
},
d: 'e'
}
---
(program (if_statement (identifier)
(expression_statement (object
(method_definition (identifier) (statement_block (expression_statement (function_call (identifier) (arguments)))))
(pair (identifier) (string))))))
============================================
if statements whose bodies look like objects
============================================
if (f) {
g()
{
h();
i();
}
j()
}
---
(program (if_statement (identifier)
(statement_block
(expression_statement (function_call (identifier) (arguments)))
(statement_block
(expression_statement (function_call (identifier) (arguments)))
(expression_statement (function_call (identifier) (arguments))))
(expression_statement (function_call (identifier) (arguments))))))
==========================================
if-else statements
==========================================
if (theCondition) {
firstFunction();
} else {
secondFunction();
}
---
(program (if_statement
(identifier)
(statement_block (expression_statement (function_call (identifier) (arguments))))
(statement_block (expression_statement (function_call (identifier) (arguments))))))
==================================================
if-else statements with multiple conditions
==================================================
if (firstValue) {
firstFunction();
} else if (secondValue)
secondFunction();
else {
thirdFunction();
}
---
(program (if_statement (identifier)
(statement_block (expression_statement (function_call (identifier) (arguments))))
(if_statement (identifier)
(expression_statement (function_call (identifier) (arguments)))
(statement_block (expression_statement (function_call (identifier) (arguments)))))))
==========================================
for loops
==========================================
for (var i = 1; someCondition(i); i = next()) {
doSomething();
}
---
(program (for_statement
(var_declaration (var_assignment (identifier) (number)))
(function_call (identifier) (arguments (identifier)))
(assignment (identifier) (function_call (identifier) (arguments)))
(statement_block (expression_statement (function_call (identifier) (arguments))))))
==========================================
for-in loops
==========================================
for (var key in someObject)
doSomething();
for (key in someObject)
doSomethingElse();
---
(program
(for_in_statement
(identifier) (identifier)
(expression_statement (function_call (identifier) (arguments))))
(for_in_statement
(identifier) (identifier)
(expression_statement (function_call (identifier) (arguments)))))
==========================================
regular for loops beginning with an in-expression
==========================================
for (key in something && i = 0; i < n; i++) {
doSomething();
}
---
(program (for_statement
(bool_op
(type_op (identifier) (identifier))
(assignment (identifier) (number)))
(rel_op (identifier) (identifier))
(math_op (identifier))
(statement_block (expression_statement (function_call (identifier) (arguments))))))
==========================================
while loops
==========================================
while (someCondition(i)) {
doSomething();
}
---
(program (while_statement
(function_call (identifier) (arguments (identifier)))
(statement_block (expression_statement (function_call (identifier) (arguments))))))
==========================================
try/catch statements
==========================================
try {
doSomething();
} catch (e) {
logError(e);
}
try {
doSomething();
} finally {
logError();
}
---
(program
(try_statement
(statement_block (expression_statement (function_call (identifier) (arguments))))
(catch (identifier)
(statement_block (expression_statement (function_call (identifier) (arguments (identifier)))))))
(try_statement
(statement_block (expression_statement (function_call (identifier) (arguments))))
(finally
(statement_block (expression_statement (function_call (identifier) (arguments)))))))
===========================================
throw statements
===========================================
throw new Error("wtf");
---
(program
(throw_statement (constructor_call (identifier) (arguments (string)))))
===========================================
indented code after blocks
===========================================
function x() {}
return z;
---
(program
(expression_statement
(function_expression (identifier) (statement_block)))
(return_statement (identifier)))
===========================================
switch statements
===========================================
switch(x) {
case "hello":
print("one");
break;
case z():
print("two");
break;
default:
print("three");
}
---
(program (switch_statement (identifier)
(case
(string)
(expression_statement (function_call (identifier) (arguments (string))))
(break_statement))
(case
(function_call (identifier) (arguments))
(expression_statement (function_call (identifier) (arguments (string))))
(break_statement))
(default
(expression_statement (function_call (identifier) (arguments (string)))))))

View file

@ -1,30 +0,0 @@
==========================================
errors in function calls
==========================================
stuff(|||);
---
(program
(expression_statement (function_call (identifier) (arguments (ERROR (UNEXPECTED '|'))))))
==========================================
errors in if statements
==========================================
stuff();
if (*nonsense*) {
*more-nonsense*;
}
moreStuff();
---
(program
(expression_statement (function_call (identifier) (arguments)))
(if_statement
(ERROR (UNEXPECTED '*') (identifier))
(statement_block
(expression_statement (ERROR (UNEXPECTED '*') (identifier) (identifier)))))
(expression_statement (function_call (identifier) (arguments))))

View file

@ -1,82 +0,0 @@
==========================================
primitives
==========================================
theFunction(/regex1/, /regex2/g);
theFunction(100.0, 200);
theFunction('', "", 'single-quoted-string', "double-quoted-string");
---
(program
(expression_statement (function_call (identifier) (arguments (regex) (regex))))
(expression_statement (function_call (identifier) (arguments (number) (number))))
(expression_statement (function_call (identifier) (arguments (string) (string) (string) (string)))))
==========================================
function expressions
==========================================
var x = {
theMethod: function(argA, argB) {
var x = argA;
}
};
---
(program
(var_declaration (var_assignment
(identifier)
(object (pair (identifier) (function_expression
(formal_parameters (identifier) (identifier))
(statement_block
(var_declaration (var_assignment (identifier) (identifier))))))))))
==========================================
comments
==========================================
// this is the beginning of the script.
// here we go.
var thing = {
// this is a property.
// its value is a function.
key: function(x /* this is a parameter */) {
// this is one statement
one();
// this is another statement
two();
}
};
---
(program
(comment)
(comment)
(var_declaration (var_assignment
(identifier)
(object
(comment)
(comment)
(pair (identifier) (function_expression
(formal_parameters (identifier)) (comment)
(statement_block
(comment)
(expression_statement (function_call (identifier) (arguments)))
(comment)
(expression_statement (function_call (identifier) (arguments))))))))))
==========================================
comments within expressions
==========================================
y // comment
* z;
---
(program (expression_statement
(math_op (identifier) (comment) (identifier))))

View file

@ -1,193 +0,0 @@
==========================================
function calls
==========================================
x.theMethod(5, 6);
---
(program (expression_statement
(function_call
(member_access (identifier) (identifier))
(arguments (number) (number)))))
==========================================
constructor calls
==========================================
var x = new Node(5, new Node(3, null));
new Thing;
---
(program
(var_declaration (var_assignment
(identifier)
(constructor_call (identifier) (arguments
(number)
(constructor_call (identifier) (arguments
(number)
(null)))))))
(expression_statement (constructor_call (identifier))))
==========================================
property access with dot notation
==========================================
object.property = "the-value";
object.property;
---
(program
(expression_statement
(assignment (member_access (identifier) (identifier)) (string)))
(expression_statement
(member_access (identifier) (identifier))))
==========================================
property access across lines
==========================================
object
.someProperty
.otherProperty
---
(program (expression_statement
(member_access
(member_access (identifier) (identifier))
(identifier))))
===========================================
dynamic property access
==========================================
object[propertyName()] = propertyValue();
object[propertyName()];
---
(program
(expression_statement
(assignment
(subscript_access (identifier) (function_call (identifier) (arguments)))
(function_call (identifier) (arguments))))
(expression_statement
(subscript_access (identifier) (function_call (identifier) (arguments)))))
==========================================
ternary expressions
==========================================
isDone() ? stuff : otherStuff;
---
(program (expression_statement
(ternary (function_call (identifier) (arguments)) (identifier) (identifier))))
==========================================
mathematical operators
==========================================
a++ + b * c - d / e--
---
(program (expression_statement
(math_op
(math_op
(math_op (identifier))
(math_op (identifier) (identifier)))
(math_op
(identifier)
(math_op (identifier))))))
==========================================
boolean operators
=========================================
!a || !(b && c)
---
(program (expression_statement
(bool_op
(bool_op (identifier))
(bool_op
(bool_op (identifier) (identifier))))))
==========================================
boolean operator precedence
=========================================
a && b(c) && d;
---
(program
(expression_statement
(bool_op
(bool_op
(identifier)
(function_call (identifier) (arguments (identifier))))
(identifier))))
===========================================
type operators
===========================================
(x instanceof Array) || (typeof x === "string")
---
(program (expression_statement
(bool_op
(type_op (identifier) (identifier))
(rel_op (type_op (identifier)) (string)))))
============================================
the 'in' operator
===========================================
print(x in y)
---
(program (expression_statement
(function_call
(identifier)
(arguments (type_op (identifier) (identifier))))))
============================================
assignment operators
============================================
x += 1;
x -= 1;
x *= 2;
x /= 2;
---
(program
(expression_statement (math_assignment (identifier) (number)))
(expression_statement (math_assignment (identifier) (number)))
(expression_statement (math_assignment (identifier) (number)))
(expression_statement (math_assignment (identifier) (number))))
============================================
property access and operators
============================================
print(x.y.z && a.b.c)
---
(program (expression_statement
(function_call (identifier)
(arguments (bool_op
(member_access (member_access (identifier) (identifier)) (identifier))
(member_access (member_access (identifier) (identifier)) (identifier)))))))

View file

@ -1,56 +0,0 @@
==========================================
top-level errors
==========================================
[}
---
(ERROR (UNEXPECTED '}'))
==========================================
unexpected tokens
==========================================
barf
---
(ERROR (UNEXPECTED 'b'))
==========================================
errors inside arrays
==========================================
[1, , 2]
---
(array
(number)
(ERROR (UNEXPECTED ','))
(number))
==========================================
errors inside objects
==========================================
{ "key1": 1, oops }
---
(object (string) (number) (ERROR (UNEXPECTED 'o')))
==========================================
errors inside nested objects
==========================================
{ "key1": { "key2": 1, 2 }, [, "key3": 3 }
---
(object
(string) (object
(string) (number)
(ERROR (UNEXPECTED '2') (number)))
(ERROR (UNEXPECTED '['))
(string) (number))

View file

@ -1,35 +0,0 @@
===================
arrays
===================
[
333,
null,
true,
false,
{ "stuff": "good" }
]
---
(array
(number)
(null)
(true)
(false)
(object (string) (string)))
===================
long objects
===================
{
"key1": "value1",
"key2": 1
}
---
(object
(string) (string)
(string) (number))

View file

@ -1,16 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
extern const Grammar anonymous_tokens{{
{ "program", choice({
str("\n"),
str("\r"),
pattern("\\d"),
str("\"hello\"") }) },
}, {
pattern("\\s"),
}, {}};
} // namespace tree_sitter_examples

View file

@ -1,45 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
extern const Grammar arithmetic{{
{ "program", sym("_expression") },
{ "_expression", choice({
sym("sum"),
sym("difference"),
sym("product"),
sym("quotient"),
sym("exponent"),
sym("group"),
sym("number"),
sym("variable") }) },
{ "sum", infix_op("+", "_expression", 1) },
{ "difference", infix_op("-", "_expression", 1) },
{ "product", infix_op("*", "_expression", 2) },
{ "quotient", infix_op("/", "_expression", 2) },
{ "exponent", infix_op("^", "_expression", 3) },
{ "group", in_parens(err(sym("_expression"))) },
{ "number", pattern("\\d+") },
{ "variable", token(seq({
pattern("[a-zA-Z\u03B1-\u03C9]"),
repeat(choice({
pattern("[a-zA-Z\u03B1-\u03C9]"),
pattern("[0-9]") })) })) },
{ "comment", pattern("#.*") },
}, {
sym("comment"),
pattern("\\s"),
}, {}};
} // namespace tree_sitter_examples

View file

@ -1,270 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
// http://slps.github.io/zoo/c/iso-9899-tc3.html
extern const Grammar c{{
{ "translation_unit", repeat(choice({
sym("preproc_define"),
sym("preproc_call"),
sym("function_definition"),
sym("declaration") })) },
{ "preproc_define", seq({
str("#define"),
sym("identifier"),
optional(sym("preproc_arg")),
str("\n") }) },
{ "preproc_call", seq({
sym("preproc_directive"),
sym("preproc_arg") }) },
{ "preproc_arg", token(prec(-1, repeat1(choice({
str("\\\n"),
pattern(".") })))) },
{ "preproc_directive", pattern("#\a\\w*") },
{ "function_definition", seq({
optional(sym("declaration_specifiers")),
sym("_type_specifier"),
sym("_declarator"),
sym("compound_statement") }) },
{ "declaration_specifiers", repeat1(choice({
sym("storage_class_specifier"),
sym("type_qualifier") })) },
{ "storage_class_specifier", choice({
str("typedef"),
str("extern"),
str("static"),
str("auto"),
str("register") }) },
{ "_type_specifier", choice({
sym("struct_specifier"),
sym("numeric_type_specifier"),
sym("identifier"),
sym("macro_type"), }) },
{ "numeric_type_specifier", seq({
repeat1(choice({
str("signed"),
str("unsigned"),
str("long"),
str("short") })),
sym("identifier") }) },
{ "struct_specifier", seq({
str("struct"),
optional(sym("identifier")),
seq({
str("{"),
repeat(sym("struct_declaration")),
str("}") }) }) },
{ "type_name", seq({
repeat(sym("type_qualifier")),
sym("_type_specifier"),
optional(sym("_abstract_declarator")) }) },
{ "struct_declaration", seq({
sym("_type_specifier"),
sym("_declarator") }) },
{ "parameter_declaration", seq({
optional(sym("declaration_specifiers")),
sym("_type_specifier"),
sym("_declarator") }) },
{ "declaration", seq({
err(seq({
optional(sym("declaration_specifiers")),
sym("_type_specifier"),
comma_sep1(choice({
sym("_declarator"),
sym("_init_declarator") })) })),
str(";") }) },
{ "_init_declarator", seq({
sym("_declarator"),
str("="),
sym("initializer") }) },
{ "initializer", choice({
sym("_expression"),
seq({
str("{"),
sym("initializer_list"),
optional(str(",")),
str("}") }) }) },
{ "initializer_list", choice({
seq({
optional(sym("designation")),
sym("initializer") }),
seq({
sym("initializer_list"),
str(","),
optional(sym("designation")),
sym("initializer") }) }) },
{ "designation", seq({
repeat1(choice({
seq({
str("["),
sym("_expression"),
str("]") }),
seq({
str("."),
sym("identifier") }) })),
str("=") }) },
{ "_declarator", choice({
sym("pointer_declarator"),
sym("function_declarator"),
sym("array_declarator"),
sym("identifier"),
seq({ str("("), sym("_declarator"), str(")") }) }) },
{ "_abstract_declarator", choice({
sym("abstract_pointer_declarator"),
sym("abstract_function_declarator"),
sym("abstract_array_declarator"),
prec(1, seq({ str("("), sym("_abstract_declarator"), str(")") })) }) },
{ "pointer_declarator", seq({
str("*"),
sym("_declarator") }) },
{ "abstract_pointer_declarator", seq({
str("*"),
optional(sym("_abstract_declarator")) }) },
{ "function_declarator", prec(1, seq({
sym("_declarator"),
str("("),
comma_sep(sym("parameter_declaration")),
str(")") })) },
{ "abstract_function_declarator", prec(1, seq({
sym("_abstract_declarator"),
str("("),
comma_sep(sym("parameter_declaration")),
str(")") })) },
{ "array_declarator", prec(1, seq({
sym("_declarator"),
str("["),
optional(sym("_expression")),
str("]") })) },
{ "abstract_array_declarator", prec(1, seq({
sym("_abstract_declarator"),
str("["),
optional(sym("_expression")),
str("]") })) },
{ "type_qualifier", choice({
str("const"),
str("restrict"),
str("volatile") }) },
{ "compound_statement", seq({
str("{"),
err(repeat(choice({ sym("declaration"), sym("_statement") }))),
str("}") }) },
{ "_expression", choice({
sym("cast_expression"),
sym("math_expression"),
sym("call_expression"),
sym("pointer_expression"),
sym("assignment_expression"),
sym("string"),
sym("identifier"),
sym("number"),
prec(1, seq({ str("("), sym("_expression"), str(")") })) }) },
{ "cast_expression", prec(4, seq({
str("("),
sym("type_name"),
str(")"),
sym("_expression") })) },
{ "math_expression", choice({
prec_left(1, seq({ sym("_expression"), str("+"), sym("_expression") })),
prec_left(2, seq({ sym("_expression"), str("*"), sym("_expression") })) }) },
{ "call_expression", prec(3, seq({
sym("_expression"),
str("("),
comma_sep(sym("_expression")),
str(")") })) },
{ "pointer_expression", seq({
choice({
str("*"),
str("&") }),
sym("_expression") }) },
{ "assignment_expression", prec_right(-1, seq({
sym("_expression"),
str("="),
sym("_expression") })) },
{ "_statement", choice({
sym("for_statement"),
sym("expression_statement"),
sym("compound_statement") }) },
{ "for_statement", seq({
str("for"),
str("("),
choice({
sym("declaration"),
seq({ optional(sym("_expression")), str(";") }) }),
optional(sym("_expression")),
str(";"),
comma_sep(sym("_expression")),
str(")"),
sym("_statement") }) },
{ "expression_statement", seq({
sym("_expression"),
str(";") }) },
{ "string", delimited("\"") },
{ "identifier", pattern("\\a[\\w_]*") },
{ "number", pattern("\\d+(\\.\\d+)?") },
{ "macro_type", seq({
sym("identifier"),
str("("),
sym("_type_specifier"),
str(")") }) },
{ "comment", token(choice({
pattern("//[^\n]*"),
seq({
str("/*"),
repeat(choice({
pattern("[^\\*]"),
pattern("\\*[^/]") })),
str("*/") }) })) },
}, {
sym("comment"),
pattern("[ \t\r\n]"),
}, {
{ "_type_specifier", "_expression" },
{ "_type_specifier", "_expression", "macro_type" },
{ "_type_specifier", "macro_type" },
}};
} // namespace tree_sitter_examples

View file

@ -1,223 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
// http://slps.github.io/zoo/cpp/iso-n2723.html
extern const Grammar cpp{{
{ "translation_unit", repeat(sym("_declaration")) },
{ "_declaration", choice({
sym("_block_declaration"),
sym("function_definition") }) },
{ "_block_declaration", choice({
sym("simple_declaration"),
sym("namespace_alias_definition"), }) },
{ "function_definition", seq({
repeat(sym("decl_specifier")),
sym("type_specifier"),
sym("declarator"),
choice({
sym("function_body"),
seq({
str("="),
choice({
str("default"),
str("delete") }),
str(";") }) }) }) },
{ "simple_declaration", seq({
repeat(sym("decl_specifier")),
sym("type_specifier"),
comma_sep1(sym("init_declarator")),
str(";") }) },
{ "namespace_alias_definition", seq({
str("namespace"),
sym("identifier"),
str("="),
sym("scoped_identifier") }) },
{ "scoped_identifier", seq({
sym("identifier"),
str("::"),
choice({
sym("identifier"),
sym("scoped_identifier") }) }) },
{ "declarator", seq({
repeat(sym("pointer_operator")),
sym("direct_declarator") }) },
{ "abstract_declarator", seq({
repeat(sym("pointer_operator")),
sym("direct_abstract_declarator") }) },
{ "direct_declarator", choice({
sym("identifier"),
seq({
str("("),
sym("declarator"),
str(")") }),
seq({
sym("direct_declarator"),
str("("),
comma_sep(sym("parameter_declaration")),
str(")") }) }) },
{ "parameter_declaration", seq({
repeat(sym("decl_specifier")),
sym("type_specifier"),
choice({
sym("declarator"),
sym("abstract_declarator") }) }) },
{ "direct_abstract_declarator", choice({
seq({
str("("),
sym("abstract_declarator"),
str(")") }) }) },
{ "cv_qualifier", choice({
str("const"),
str("volatile") }) },
{ "type_id", seq({
sym("type_specifier"),
optional(sym("abstract_declarator")) }) },
{ "pointer_operator", choice({
seq({ str("*"), repeat(sym("cv_qualifier")) }),
str("&"),
str("&&") }) },
{ "type_name", choice({
sym("identifier"),
sym("template_call") }) },
{ "function_body", choice({
// sym("function_try_block"),
seq({
optional(sym("constructor_initializer")),
sym("compound_statement") }) }) },
{ "constructor_initializer", seq({
str(":"),
repeat(sym("member_initializer")),
optional(str("...")) }) },
{ "member_initializer", seq({
sym("identifier"),
choice({
// sym("braced_initializer_list"),
seq({
str("("),
str("initializer_list"),
str(")") }) }) }) },
{ "init_declarator", seq({
sym("declarator"),
optional(sym("initializer")) }) },
{ "decl_specifier", choice({
sym("storage_class_specifier"),
sym("function_specifier"),
str("friend"),
str("typedef"),
str("constexpr") }) },
{ "storage_class_specifier", choice({
str("register"),
str("static"),
str("thread_local"),
str("extern"),
str("mutable") }) },
{ "type_specifier", choice({
sym("scoped_identifier"),
sym("template_call"),
sym("identifier") }) },
{ "compound_statement", seq({
str("{"),
repeat(sym("_statement")),
str("}") }) },
{ "_statement", choice({
sym("compound_statement"),
sym("_block_declaration"),
sym("expression_statement") }) },
{ "expression_statement", seq({
optional(sym("_expression")),
str(";") }) },
{ "initializer", choice({
// sym("braced_initializer_list"),
seq({
str("="),
sym("initializer_clause") }) }) },
{ "initializer_clause", choice({
// sym("braced_initializer_list"),
sym("_expression") }) },
{ "function_specifier", choice({
str("inline"),
str("virtual"),
str("explicit") }) },
{ "_expression", choice({
sym("relational_expression"),
sym("call_expression"),
sym("identifier"),
sym("template_call"),
sym("scoped_identifier"),
sym("string"),
sym("number") }) },
{ "call_expression", seq({
sym("_expression"),
str("("),
comma_sep(sym("_expression")),
str(")") }) },
{ "relational_expression", prec_left(seq({
sym("_expression"),
choice({
str(">"),
str(">="),
str("=="),
str("!="),
str("<="),
str("<") }),
sym("_expression") })) },
{ "template_call", seq({
choice({ sym("identifier"), sym("scoped_identifier") }),
str("<"),
choice({
sym("_expression"),
sym("type_id") }),
str(">") }) },
{ "string", delimited("\"") },
{ "identifier", pattern("\\a[\\w_]*") },
{ "number", pattern("\\d+(\\.\\d+)?") },
{ "comment", pattern("//[^\n]*") },
}, {
sym("comment"),
pattern("[ \t\r\n]"),
}, {
{ "type_specifier", "_expression" },
{ "template_call", "_expression" },
{ "template_call", "relational_expression" },
}};
} // namespace tree_sitter_examples

View file

@ -1,212 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
static rule_ptr terminated(rule_ptr rule) {
return seq({ rule, choice({
sym("_line_break"),
str(";") }) });
}
extern const Grammar golang{{
{ "program", seq({
sym("package_directive"),
repeat(sym("imports_block")),
repeat(sym("_declaration")) }) },
{ "package_directive", seq({
str("package"),
sym("package_name") }) },
{ "imports_block", seq({
str("import"),
choice({
in_parens(err(repeat(sym("package_import")))),
sym("package_import") }) }) },
{ "package_import", sym("string") },
{ "_declaration", choice({
sym("type_declaration"),
sym("var_declaration"),
sym("func_declaration") }) },
/*
* Declarations
*/
{ "type_declaration", terminated(seq({
str("type"),
sym("type_name"),
sym("_type_expression") })) },
{ "var_declaration", terminated(seq({
str("var"),
sym("var_name"),
choice({
seq({
optional(sym("_type_expression")),
str("="),
sym("_expression") }),
sym("_type_expression") }) })) },
{ "func_declaration", terminated(seq({
str("func"),
sym("var_name"),
sym("_func_signature"),
sym("block_statement") })) },
{ "block_statement", in_braces(err(repeat(sym("_statement")))) },
{ "_type_expression", choice({
sym("pointer_type"),
sym("slice_type"),
sym("map_type"),
sym("interface_type"),
sym("struct_type"),
sym("type_name") }) },
/*
* Type expressions
*/
{ "pointer_type", seq({
str("*"),
sym("_type_expression") }) },
{ "map_type", seq({
str("map"),
in_brackets(sym("_type_expression")),
sym("_type_expression") }) },
{ "slice_type", seq({
in_brackets(blank()),
sym("_type_expression") }) },
{ "struct_type", seq({
str("struct"),
in_braces(repeat(seq({
sym("var_name"),
sym("_type_expression") }))) }) },
{ "interface_type", seq({
str("interface"),
in_braces(repeat(seq({
sym("var_name"),
sym("_func_signature") }))) }) },
/*
* Statements
*/
{ "_statement", choice({
sym("expression_statement"),
sym("return_statement"),
sym("var_declaration"),
sym("short_var_declaration"),
sym("range_statement"),
sym("if_statement") }) },
{ "return_statement", terminated(seq({
str("return"),
comma_sep(sym("_expression")) })) },
{ "short_var_declaration", terminated(seq({
comma_sep(sym("var_name")),
str(":="),
sym("_expression") })) },
{ "range_statement", seq({
str("for"),
sym("var_name"),
optional(seq({ str(","), sym("var_name") })),
str(":="),
str("range"),
sym("_expression"),
sym("block_statement") }) },
{ "if_statement", seq({
str("if"),
sym("_expression"),
sym("block_statement"),
optional(seq({
str("else"),
choice({
sym("if_statement"),
sym("block_statement") }) })) }) },
{ "expression_statement", terminated(sym("_expression")) },
/*
* Value expressions
*/
{ "_expression", choice({
sym("call_expression"),
sym("selector_expression"),
sym("math_op"),
sym("bool_op"),
sym("number"),
sym("string"),
sym("var_name") }) },
{ "call_expression", seq({
sym("_expression"),
in_parens(comma_sep(sym("_expression"))) }) },
{ "selector_expression", seq({
sym("_expression"),
str("."),
sym("var_name") }) },
{ "math_op", choice({
infix_op("*", "_expression", 2),
infix_op("/", "_expression", 2),
infix_op("+", "_expression", 1),
infix_op("-", "_expression", 1) }) },
{ "bool_op", choice({
infix_op("||", "_expression", 1),
infix_op("&&", "_expression", 2),
infix_op("==", "_expression", 3),
infix_op("<=", "_expression", 3),
infix_op("<", "_expression", 3),
infix_op(">=", "_expression", 3),
infix_op(">", "_expression", 3),
prefix_op("!", "_expression", 4) }) },
{ "_func_signature", prec(10, seq({
in_parens(comma_sep(seq({
comma_sep1(sym("var_name")),
sym("_type_expression") }))),
choice({
in_parens(choice({
comma_sep1(seq({ sym("var_name"), sym("type_name") })),
comma_sep1(sym("type_name")) })),
sym("type_name"),
blank() }) })) },
{ "_line_break", str("\n") },
{ "string", delimited("\"") },
{ "package_name", sym("_identifier") },
{ "var_name", sym("_identifier") },
{ "type_name", sym("_identifier") },
{ "_identifier", pattern("\\a[\\w_]*") },
{ "number", pattern("\\d+(\\.\\d+)?") },
{ "comment", pattern("//[^\n]*") },
}, {
sym("comment"),
sym("_line_break"),
pattern("[ \t\r]"),
}, {}};
} // namespace tree_sitter_examples

View file

@ -1,59 +0,0 @@
#include "compiler/rules.h"
namespace tree_sitter_examples {
using namespace tree_sitter;
rule_ptr comma_sep1(rule_ptr element) {
return seq({ element, repeat(seq({ str(","), element })) });
}
rule_ptr comma_sep(rule_ptr element) {
return choice({ comma_sep1(element), blank() });
}
rule_ptr optional(rule_ptr rule) {
return choice({ rule, blank() });
}
rule_ptr in_parens(rule_ptr rule) {
return seq({ str("("), rule, str(")") });
}
rule_ptr in_braces(rule_ptr rule) {
return seq({ str("{"), rule, str("}") });
}
rule_ptr in_brackets(rule_ptr rule) {
return seq({ str("["), rule, str("]") });
}
rule_ptr infix_op(std::string op, std::string rule_name, int precedence) {
return prec_left(precedence, seq({
sym(rule_name),
str(op),
sym(rule_name) }));
}
rule_ptr prefix_op(std::string op, std::string rule_name, int precedence) {
return prec(precedence, seq({
str(op),
sym(rule_name) }));
}
rule_ptr postfix_op(std::string op, std::string rule_name, int precedence) {
return prec(precedence, seq({
sym(rule_name),
str(op) }));
}
rule_ptr delimited(std::string delimiter) {
return token(seq({
str(delimiter),
repeat(choice({
pattern("[^" + delimiter + "]"),
seq({ str("\\"), str(delimiter) }) })),
str(delimiter) }));
}
} // namespace tree_sitter_examples

View file

@ -1,24 +0,0 @@
#ifndef TREESITTER_EXAMPLES_HELPERS_
#define TREESITTER_EXAMPLES_HELPERS_
#include "compiler/rules.h"
#include "compiler/grammar.h"
namespace tree_sitter_examples {
using namespace tree_sitter;
rule_ptr comma_sep1(rule_ptr element);
rule_ptr comma_sep(rule_ptr element);
rule_ptr optional(rule_ptr rule);
rule_ptr in_parens(rule_ptr rule);
rule_ptr in_braces(rule_ptr rule);
rule_ptr in_brackets(rule_ptr rule);
rule_ptr infix_op(std::string op, std::string rule_name, int precedence);
rule_ptr prefix_op(std::string op, std::string rule_name, int precedence);
rule_ptr postfix_op(std::string op, std::string rule_name, int precedence);
rule_ptr delimited(std::string delimiter);
} // namespace tree_sitter_examples
#endif // TREESITTER_EXAMPLES_HELPERS_

View file

@ -1,361 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
static rule_ptr terminated(rule_ptr rule) {
return seq({ rule, choice({
sym("_line_break"),
str(";") }) });
}
enum {
PREC_COMMA = -1,
PREC_BLOCK = 1,
PREC_TERNARY = 2,
PREC_OR = 3,
PREC_AND = 4,
PREC_ASSIGN = 5,
PREC_REL = 5,
PREC_ADD = 6,
PREC_MULT = 7,
PREC_TYPE = 8,
PREC_NOT = 9,
PREC_SIGN = 10,
PREC_INC = 11,
PREC_SHORT_NEW = 12,
PREC_CALL = 13,
PREC_FULL_NEW = 14,
PREC_MEMBER = 15,
PREC_ARGS = 16,
};
extern const Grammar javascript{{
{ "program", repeat(sym("_statement")) },
/*
* Statements
*/
{ "_statement", choice({
sym("expression_statement"),
sym("var_declaration"),
sym("statement_block"),
sym("if_statement"),
sym("switch_statement"),
sym("for_statement"),
sym("while_statement"),
sym("for_in_statement"),
// sym("do_statement"),
sym("try_statement"),
sym("return_statement"),
sym("break_statement"),
sym("throw_statement"),
sym("delete_statement") }) },
{ "expression_statement", choice({
terminated(sym("_expression")),
seq({ err(sym("_expression")), str(";") }) }) },
{ "var_declaration", terminated(seq({
str("var"),
comma_sep1(err(choice({
sym("identifier"),
sym("var_assignment") }))) })) },
{ "statement_block", prec(PREC_BLOCK,
in_braces(err(repeat(sym("_statement"))))) },
{ "if_statement", prec_right(0, seq({
str("if"),
sym("_paren_expression"),
sym("_statement"),
optional(seq({
str("else"),
sym("_statement") })) })) },
{ "switch_statement", seq({
str("switch"),
sym("_paren_expression"),
str("{"),
repeat(choice({ sym("case"), sym("default") })),
str("}") }) },
{ "for_statement", seq({
str("for"),
str("("),
choice({
sym("var_declaration"),
seq({ sym("_expression"), str(";") }),
str(";") }),
optional(err(sym("_expression"))), str(";"),
optional(err(sym("_expression"))),
str(")"),
sym("_statement") }) },
{ "for_in_statement", seq({
str("for"),
str("("),
optional(str("var")),
sym("identifier"),
str("in"),
sym("_expression"),
str(")"),
sym("_statement") }) },
{ "while_statement", seq({
str("while"),
sym("_paren_expression"),
sym("_statement") }) },
// { "do_statement", seq({
// str("do"),
// sym("_statement"),
// str("while"),
// sym("_paren_expression") })},
{ "try_statement", seq({
str("try"),
sym("statement_block"),
optional(sym("catch")),
optional(sym("finally")) }) },
{ "return_statement", terminated(seq({
str("return"),
optional(sym("_expression")) })) },
{ "throw_statement", terminated(seq({
str("throw"),
sym("_expression") })) },
{ "break_statement", terminated(str("break")) },
{ "delete_statement", terminated(seq({
str("delete"),
choice({ sym("member_access"), sym("subscript_access") }) })) },
/*
* Statement components
*/
{ "case", seq({
str("case"),
sym("_expression"),
str(":"),
repeat(sym("_statement")) }) },
{ "default", seq({
str("default"),
str(":"),
repeat(sym("_statement")) }) },
{ "catch", seq({
str("catch"),
str("("),
err(sym("identifier")),
str(")"),
sym("statement_block") }) },
{ "finally", seq({
str("finally"),
sym("statement_block") }) },
{ "var_assignment", seq({
sym("identifier"),
str("="),
sym("_expression") }) },
{ "_paren_expression", in_parens(err(sym("_expression"))) },
/*
* Expressions
*/
{ "_expression", choice({
sym("object"),
sym("array"),
sym("function_expression"),
sym("function_call"),
sym("constructor_call"),
sym("member_access"),
sym("subscript_access"),
sym("assignment"),
sym("math_assignment"),
sym("ternary"),
sym("bool_op"),
sym("math_op"),
// sym("comma_op"),
// sym("bitwise_op"),
sym("rel_op"),
sym("type_op"),
sym("null"),
sym("number"),
sym("undefined"),
sym("regex"),
sym("string"),
sym("false"),
sym("identifier"),
sym("true"),
sym("_paren_expression") }) },
{ "object", in_braces(comma_sep(err(choice({
sym("pair"),
sym("method_definition") })))) },
{ "array", in_brackets(comma_sep(err(sym("_expression")))) },
{ "function_expression", seq({
str("function"),
optional(sym("identifier")),
str("("),
optional(sym("formal_parameters")),
str(")"),
sym("statement_block") }) },
{ "function_call", prec(PREC_CALL, seq({
sym("_expression"),
sym("arguments") })) },
{ "constructor_call", choice({
prec_right(PREC_SHORT_NEW, seq({
str("new"),
sym("_expression") })),
prec_right(PREC_MEMBER, seq({
str("new"),
sym("_expression"),
sym("arguments") })) }) },
{ "member_access", prec(PREC_MEMBER, seq({
sym("_expression"),
str("."),
sym("identifier") })) },
{ "subscript_access", prec(PREC_MEMBER, seq({
sym("_expression"),
str("["),
err(sym("_expression")),
str("]") })) },
{ "assignment", prec_right(PREC_ASSIGN, seq({
sym("_expression"),
str("="),
sym("_expression") })) },
{ "math_assignment", prec_right(PREC_ASSIGN, seq({
sym("_expression"),
choice({ str("+="), str("-="), str("*="), str("/=") }),
sym("_expression") })) },
{ "ternary", prec_right(PREC_TERNARY, seq({
sym("_expression"),
str("?"),
sym("_expression"),
str(":"),
sym("_expression") })) },
{ "bool_op", choice({
infix_op("||", "_expression", PREC_OR),
infix_op("&&", "_expression", PREC_AND),
prefix_op("!", "_expression", PREC_NOT) }) },
{ "comma_op", infix_op(",", "_expression", PREC_COMMA) },
{ "math_op", choice({
// prefix_op("+", "_expression", PREC_SIGN),
// prefix_op("-", "_expression", PREC_SIGN),
postfix_op("++", "_expression", PREC_INC),
postfix_op("--", "_expression", PREC_INC),
infix_op("*", "_expression", PREC_MULT),
infix_op("/", "_expression", PREC_MULT),
infix_op("+", "_expression", PREC_ADD),
infix_op("-", "_expression", PREC_ADD) }) },
// { "bitwise_op", choice({
// infix_op("&", "_expression", PREC_MULT),
// infix_op("|", "_expression", PREC_MULT),
// infix_op("<<", "_expression", PREC_MULT),
// infix_op(">>", "_expression", PREC_MULT) }) },
{ "rel_op", choice({
// infix_op("==", "_expression", PREC_REL),
// infix_op("!=", "_expression", PREC_REL),
// infix_op("<=", "_expression", PREC_REL),
// infix_op(">=", "_expression", PREC_REL),
infix_op("===", "_expression", PREC_REL),
infix_op("!==", "_expression", PREC_REL),
infix_op("<", "_expression", PREC_REL),
infix_op(">", "_expression", PREC_REL) }) },
{ "type_op", choice({
infix_op("in", "_expression", PREC_REL),
infix_op("instanceof", "_expression", PREC_REL),
prefix_op("typeof", "_expression", PREC_TYPE) }) },
/*
* Primitives
*/
{ "comment", token(choice({
seq({
str("/*"),
repeat(pattern("[^*]|(*[^/])")),
str("*/") }),
pattern("//[^\n]*") })) },
{ "string", token(choice({
delimited("\""),
delimited("'") })) },
{ "regex", token(seq({ delimited("/"), optional(str("g")) })) },
{ "number", pattern("\\d+(\\.\\d+)?") },
{ "identifier", pattern("[\\a_$][\\w_$]*") },
{ "null", str("null") },
{ "undefined", str("undefined") },
{ "true", str("true") },
{ "false", str("false") },
{ "_line_break", str("\n") },
/*
* Expression components
*/
{ "formal_parameters", comma_sep1(sym("identifier")) },
{ "arguments", prec(PREC_ARGS, seq({
str("("),
comma_sep(err(sym("_expression"))),
str(")") })) },
{ "pair", seq({
choice({ sym("string"), sym("identifier") }),
str(":"),
sym("_expression") }) },
{ "method_definition", seq({
sym("identifier"),
str("("),
comma_sep(sym("identifier")),
str(")"),
sym("statement_block") }) },
}, {
sym("comment"),
sym("_line_break"),
pattern("[ \t\r]"),
}, {
{ "for_in_statement", "_expression" },
{ "method_definition", "_expression" },
}};
} // namespace tree_sitter_examples

View file

@ -1,29 +0,0 @@
#include "tree_sitter/compiler.h"
#include "helpers.h"
namespace tree_sitter_examples {
extern const Grammar json{{
{ "_value", choice({
sym("object"),
sym("array"),
sym("string"),
sym("number"),
sym("true"),
sym("false"),
sym("null"), }) },
{ "object", in_braces(comma_sep(err(seq({
sym("string"),
str(":"),
sym("_value") })))) },
{ "array", in_brackets(comma_sep(err(sym("_value")))) },
{ "string", pattern("\"([^\"]|\\\\\")*\"") },
{ "number", pattern("\\d+(\\.\\d+)?") },
{ "null", str("null") },
{ "true", str("true") },
{ "false", str("false") },
}, {
pattern("\\s"),
}, {}};
} // namespace tree_sitter_examples

View file

@ -1,153 +0,0 @@
#include "tree_sitter/parser.h"
#define STATE_COUNT 3
#define SYMBOL_COUNT 7
enum {
sym_program = ts_builtin_sym_start,
anon_sym_LF,
anon_sym_CR,
aux_sym_SLASH_BSLASHd_SLASH,
anon_sym_DQUOTEhello_DQUOTE,
};
static const char *ts_symbol_names[] = {
[sym_program] = "program",
[ts_builtin_sym_error] = "ERROR",
[ts_builtin_sym_end] = "END",
[anon_sym_LF] = "\n",
[anon_sym_CR] = "\r",
[aux_sym_SLASH_BSLASHd_SLASH] = "/\\d/",
[anon_sym_DQUOTEhello_DQUOTE] = "\"hello\"",
};
static const TSSymbolMetadata ts_symbol_metadata[SYMBOL_COUNT] = {
[sym_program] = {.visible = true, .named = true, .structural = true, .extra = false},
[ts_builtin_sym_error] = {.visible = true, .named = true, .structural = false, .extra = false},
[ts_builtin_sym_end] = {.visible = false, .named = false, .structural = true, .extra = false},
[anon_sym_LF] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_CR] = {.visible = true, .named = false, .structural = true, .extra = false},
[aux_sym_SLASH_BSLASHd_SLASH] = {.visible = false, .named = false, .structural = true, .extra = false},
[anon_sym_DQUOTEhello_DQUOTE] = {.visible = true, .named = false, .structural = true, .extra = false},
};
static TSTree *ts_lex(TSLexer *lexer, TSStateId state, bool error_mode) {
START_LEXER();
switch (state) {
case 0:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == ' '))
ADVANCE(0);
if (lookahead == '\n')
ADVANCE(2);
if (lookahead == '\r')
ADVANCE(3);
if (lookahead == '\"')
ADVANCE(4);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(11);
LEX_ERROR();
case 1:
ACCEPT_TOKEN(ts_builtin_sym_end);
case 2:
START_TOKEN();
ACCEPT_TOKEN(anon_sym_LF);
case 3:
START_TOKEN();
ACCEPT_TOKEN(anon_sym_CR);
case 4:
if (lookahead == 'h')
ADVANCE(5);
LEX_ERROR();
case 5:
if (lookahead == 'e')
ADVANCE(6);
LEX_ERROR();
case 6:
if (lookahead == 'l')
ADVANCE(7);
LEX_ERROR();
case 7:
if (lookahead == 'l')
ADVANCE(8);
LEX_ERROR();
case 8:
if (lookahead == 'o')
ADVANCE(9);
LEX_ERROR();
case 9:
if (lookahead == '\"')
ADVANCE(10);
LEX_ERROR();
case 10:
ACCEPT_TOKEN(anon_sym_DQUOTEhello_DQUOTE);
case 11:
ACCEPT_TOKEN(aux_sym_SLASH_BSLASHd_SLASH);
case 12:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == ' '))
ADVANCE(12);
if (lookahead == '\n')
ADVANCE(2);
if (lookahead == '\r')
ADVANCE(3);
if (lookahead == '\"')
ADVANCE(4);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(11);
LEX_ERROR();
case 13:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(13);
LEX_ERROR();
default:
LEX_ERROR();
}
}
static TSStateId ts_lex_states[STATE_COUNT] = {
[0] = 12,
[1] = 13,
[2] = 13,
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
static unsigned short ts_parse_table[STATE_COUNT][SYMBOL_COUNT] = {
[0] = {
[sym_program] = 2,
[anon_sym_LF] = 4,
[anon_sym_CR] = 4,
[aux_sym_SLASH_BSLASHd_SLASH] = 4,
[anon_sym_DQUOTEhello_DQUOTE] = 4,
},
[1] = {
[ts_builtin_sym_end] = 6,
},
[2] = {
[ts_builtin_sym_end] = 8,
},
};
static TSParseActionEntry ts_parse_actions[] = {
[0] = {.count = 1}, ERROR(),
[2] = {.count = 1}, SHIFT(1, 0),
[4] = {.count = 1}, SHIFT(2, 0),
[6] = {.count = 1}, ACCEPT_INPUT(),
[8] = {.count = 1}, REDUCE(sym_program, 1, 0),
};
#pragma GCC diagnostic pop
EXPORT_LANGUAGE(ts_language_anonymous_tokens);

View file

@ -1,660 +0,0 @@
#include "tree_sitter/parser.h"
#define STATE_COUNT 33
#define SYMBOL_COUNT 20
enum {
sym_program = ts_builtin_sym_start,
sym__expression,
sym_sum,
sym_difference,
sym_product,
sym_quotient,
sym_exponent,
sym_group,
anon_sym_PLUS,
anon_sym_DASH,
anon_sym_STAR,
anon_sym_SLASH,
anon_sym_CARET,
anon_sym_LPAREN,
anon_sym_RPAREN,
sym_number,
sym_variable,
sym_comment,
};
static const char *ts_symbol_names[] = {
[sym_program] = "program",
[sym__expression] = "_expression",
[sym_sum] = "sum",
[sym_difference] = "difference",
[sym_product] = "product",
[sym_quotient] = "quotient",
[sym_exponent] = "exponent",
[sym_group] = "group",
[ts_builtin_sym_error] = "ERROR",
[ts_builtin_sym_end] = "END",
[anon_sym_PLUS] = "+",
[anon_sym_DASH] = "-",
[anon_sym_STAR] = "*",
[anon_sym_SLASH] = "/",
[anon_sym_CARET] = "^",
[anon_sym_LPAREN] = "(",
[anon_sym_RPAREN] = ")",
[sym_number] = "number",
[sym_variable] = "variable",
[sym_comment] = "comment",
};
static const TSSymbolMetadata ts_symbol_metadata[SYMBOL_COUNT] = {
[sym_program] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym__expression] = {.visible = false, .named = false, .structural = true, .extra = false},
[sym_sum] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_difference] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_product] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_quotient] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_exponent] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_group] = {.visible = true, .named = true, .structural = true, .extra = false},
[ts_builtin_sym_error] = {.visible = true, .named = true, .structural = true, .extra = false},
[ts_builtin_sym_end] = {.visible = false, .named = false, .structural = true, .extra = false},
[anon_sym_PLUS] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_DASH] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_STAR] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_SLASH] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_CARET] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_LPAREN] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_RPAREN] = {.visible = true, .named = false, .structural = true, .extra = false},
[sym_number] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_variable] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_comment] = {.visible = true, .named = true, .structural = false, .extra = true},
};
static TSTree *ts_lex(TSLexer *lexer, TSStateId state, bool error_mode) {
START_LEXER();
switch (state) {
case 0:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(0);
if (lookahead == '#')
ADVANCE(2);
if (lookahead == '(')
ADVANCE(3);
if (lookahead == ')')
ADVANCE(4);
if (lookahead == '*')
ADVANCE(5);
if (lookahead == '+')
ADVANCE(6);
if (lookahead == '-')
ADVANCE(7);
if (lookahead == '/')
ADVANCE(8);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(9);
if (('A' <= lookahead && lookahead <= 'Z') ||
('a' <= lookahead && lookahead <= 'z') ||
(945 <= lookahead && lookahead <= 969))
ADVANCE(10);
if (lookahead == '^')
ADVANCE(11);
LEX_ERROR();
case 1:
ACCEPT_TOKEN(ts_builtin_sym_end);
case 2:
if (!((lookahead == 0) ||
(lookahead == '\n')))
ADVANCE(2);
ACCEPT_TOKEN(sym_comment);
case 3:
ACCEPT_TOKEN(anon_sym_LPAREN);
case 4:
ACCEPT_TOKEN(anon_sym_RPAREN);
case 5:
ACCEPT_TOKEN(anon_sym_STAR);
case 6:
ACCEPT_TOKEN(anon_sym_PLUS);
case 7:
ACCEPT_TOKEN(anon_sym_DASH);
case 8:
ACCEPT_TOKEN(anon_sym_SLASH);
case 9:
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(9);
ACCEPT_TOKEN(sym_number);
case 10:
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(10);
if (('A' <= lookahead && lookahead <= 'Z') ||
('a' <= lookahead && lookahead <= 'z') ||
(945 <= lookahead && lookahead <= 969))
ADVANCE(10);
ACCEPT_TOKEN(sym_variable);
case 11:
ACCEPT_TOKEN(anon_sym_CARET);
case 12:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(12);
if (lookahead == '#')
ADVANCE(2);
if (lookahead == '(')
ADVANCE(3);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(9);
if (('A' <= lookahead && lookahead <= 'Z') ||
('a' <= lookahead && lookahead <= 'z') ||
(945 <= lookahead && lookahead <= 969))
ADVANCE(10);
LEX_ERROR();
case 13:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(13);
if (lookahead == '#')
ADVANCE(2);
LEX_ERROR();
case 14:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(14);
if (lookahead == '#')
ADVANCE(2);
if (lookahead == '*')
ADVANCE(5);
if (lookahead == '+')
ADVANCE(6);
if (lookahead == '-')
ADVANCE(7);
if (lookahead == '/')
ADVANCE(8);
if (lookahead == '^')
ADVANCE(11);
LEX_ERROR();
case 15:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(15);
if (lookahead == '#')
ADVANCE(2);
if (lookahead == ')')
ADVANCE(4);
if (lookahead == '*')
ADVANCE(5);
if (lookahead == '+')
ADVANCE(6);
if (lookahead == '-')
ADVANCE(7);
if (lookahead == '/')
ADVANCE(8);
if (lookahead == '^')
ADVANCE(11);
LEX_ERROR();
case 16:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(16);
if (lookahead == '#')
ADVANCE(2);
if (lookahead == ')')
ADVANCE(4);
LEX_ERROR();
default:
LEX_ERROR();
}
}
static TSStateId ts_lex_states[STATE_COUNT] = {
[0] = 12,
[1] = 13,
[2] = 14,
[3] = 14,
[4] = 12,
[5] = 15,
[6] = 15,
[7] = 16,
[8] = 12,
[9] = 15,
[10] = 16,
[11] = 15,
[12] = 12,
[13] = 12,
[14] = 12,
[15] = 12,
[16] = 12,
[17] = 15,
[18] = 15,
[19] = 15,
[20] = 15,
[21] = 15,
[22] = 14,
[23] = 12,
[24] = 12,
[25] = 12,
[26] = 12,
[27] = 12,
[28] = 14,
[29] = 14,
[30] = 14,
[31] = 14,
[32] = 14,
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
static unsigned short ts_parse_table[STATE_COUNT][SYMBOL_COUNT] = {
[0] = {
[sym_program] = 2,
[sym__expression] = 4,
[sym_sum] = 6,
[sym_difference] = 6,
[sym_product] = 6,
[sym_quotient] = 6,
[sym_exponent] = 6,
[sym_group] = 6,
[anon_sym_LPAREN] = 8,
[sym_number] = 6,
[sym_variable] = 6,
[sym_comment] = 10,
},
[1] = {
[ts_builtin_sym_end] = 12,
[sym_comment] = 14,
},
[2] = {
[ts_builtin_sym_end] = 16,
[anon_sym_PLUS] = 18,
[anon_sym_DASH] = 20,
[anon_sym_STAR] = 22,
[anon_sym_SLASH] = 24,
[anon_sym_CARET] = 26,
[sym_comment] = 14,
},
[3] = {
[ts_builtin_sym_end] = 28,
[anon_sym_PLUS] = 28,
[anon_sym_DASH] = 28,
[anon_sym_STAR] = 28,
[anon_sym_SLASH] = 28,
[anon_sym_CARET] = 28,
[sym_comment] = 14,
},
[4] = {
[sym__expression] = 30,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[ts_builtin_sym_error] = 34,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[5] = {
[anon_sym_PLUS] = 38,
[anon_sym_DASH] = 40,
[anon_sym_STAR] = 42,
[anon_sym_SLASH] = 44,
[anon_sym_CARET] = 46,
[anon_sym_RPAREN] = 48,
[sym_comment] = 14,
},
[6] = {
[anon_sym_PLUS] = 28,
[anon_sym_DASH] = 28,
[anon_sym_STAR] = 28,
[anon_sym_SLASH] = 28,
[anon_sym_CARET] = 28,
[anon_sym_RPAREN] = 28,
[sym_comment] = 14,
},
[7] = {
[anon_sym_RPAREN] = 48,
[sym_comment] = 14,
},
[8] = {
[sym__expression] = 50,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[ts_builtin_sym_error] = 52,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[9] = {
[anon_sym_PLUS] = 38,
[anon_sym_DASH] = 40,
[anon_sym_STAR] = 42,
[anon_sym_SLASH] = 44,
[anon_sym_CARET] = 46,
[anon_sym_RPAREN] = 54,
[sym_comment] = 14,
},
[10] = {
[anon_sym_RPAREN] = 54,
[sym_comment] = 14,
},
[11] = {
[anon_sym_PLUS] = 56,
[anon_sym_DASH] = 56,
[anon_sym_STAR] = 56,
[anon_sym_SLASH] = 56,
[anon_sym_CARET] = 56,
[anon_sym_RPAREN] = 56,
[sym_comment] = 14,
},
[12] = {
[sym__expression] = 58,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[13] = {
[sym__expression] = 60,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[14] = {
[sym__expression] = 62,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[15] = {
[sym__expression] = 64,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[16] = {
[sym__expression] = 66,
[sym_sum] = 32,
[sym_difference] = 32,
[sym_product] = 32,
[sym_quotient] = 32,
[sym_exponent] = 32,
[sym_group] = 32,
[anon_sym_LPAREN] = 36,
[sym_number] = 32,
[sym_variable] = 32,
[sym_comment] = 14,
},
[17] = {
[anon_sym_PLUS] = 68,
[anon_sym_DASH] = 68,
[anon_sym_STAR] = 68,
[anon_sym_SLASH] = 68,
[anon_sym_CARET] = 68,
[anon_sym_RPAREN] = 68,
[sym_comment] = 14,
},
[18] = {
[anon_sym_PLUS] = 70,
[anon_sym_DASH] = 70,
[anon_sym_STAR] = 70,
[anon_sym_SLASH] = 70,
[anon_sym_CARET] = 46,
[anon_sym_RPAREN] = 70,
[sym_comment] = 14,
},
[19] = {
[anon_sym_PLUS] = 72,
[anon_sym_DASH] = 72,
[anon_sym_STAR] = 72,
[anon_sym_SLASH] = 72,
[anon_sym_CARET] = 46,
[anon_sym_RPAREN] = 72,
[sym_comment] = 14,
},
[20] = {
[anon_sym_PLUS] = 74,
[anon_sym_DASH] = 74,
[anon_sym_STAR] = 42,
[anon_sym_SLASH] = 44,
[anon_sym_CARET] = 46,
[anon_sym_RPAREN] = 74,
[sym_comment] = 14,
},
[21] = {
[anon_sym_PLUS] = 76,
[anon_sym_DASH] = 76,
[anon_sym_STAR] = 42,
[anon_sym_SLASH] = 44,
[anon_sym_CARET] = 46,
[anon_sym_RPAREN] = 76,
[sym_comment] = 14,
},
[22] = {
[ts_builtin_sym_end] = 56,
[anon_sym_PLUS] = 56,
[anon_sym_DASH] = 56,
[anon_sym_STAR] = 56,
[anon_sym_SLASH] = 56,
[anon_sym_CARET] = 56,
[sym_comment] = 14,
},
[23] = {
[sym__expression] = 78,
[sym_sum] = 6,
[sym_difference] = 6,
[sym_product] = 6,
[sym_quotient] = 6,
[sym_exponent] = 6,
[sym_group] = 6,
[anon_sym_LPAREN] = 8,
[sym_number] = 6,
[sym_variable] = 6,
[sym_comment] = 14,
},
[24] = {
[sym__expression] = 80,
[sym_sum] = 6,
[sym_difference] = 6,
[sym_product] = 6,
[sym_quotient] = 6,
[sym_exponent] = 6,
[sym_group] = 6,
[anon_sym_LPAREN] = 8,
[sym_number] = 6,
[sym_variable] = 6,
[sym_comment] = 14,
},
[25] = {
[sym__expression] = 82,
[sym_sum] = 6,
[sym_difference] = 6,
[sym_product] = 6,
[sym_quotient] = 6,
[sym_exponent] = 6,
[sym_group] = 6,
[anon_sym_LPAREN] = 8,
[sym_number] = 6,
[sym_variable] = 6,
[sym_comment] = 14,
},
[26] = {
[sym__expression] = 84,
[sym_sum] = 6,
[sym_difference] = 6,
[sym_product] = 6,
[sym_quotient] = 6,
[sym_exponent] = 6,
[sym_group] = 6,
[anon_sym_LPAREN] = 8,
[sym_number] = 6,
[sym_variable] = 6,
[sym_comment] = 14,
},
[27] = {
[sym__expression] = 86,
[sym_sum] = 6,
[sym_difference] = 6,
[sym_product] = 6,
[sym_quotient] = 6,
[sym_exponent] = 6,
[sym_group] = 6,
[anon_sym_LPAREN] = 8,
[sym_number] = 6,
[sym_variable] = 6,
[sym_comment] = 14,
},
[28] = {
[ts_builtin_sym_end] = 68,
[anon_sym_PLUS] = 68,
[anon_sym_DASH] = 68,
[anon_sym_STAR] = 68,
[anon_sym_SLASH] = 68,
[anon_sym_CARET] = 68,
[sym_comment] = 14,
},
[29] = {
[ts_builtin_sym_end] = 70,
[anon_sym_PLUS] = 70,
[anon_sym_DASH] = 70,
[anon_sym_STAR] = 70,
[anon_sym_SLASH] = 70,
[anon_sym_CARET] = 26,
[sym_comment] = 14,
},
[30] = {
[ts_builtin_sym_end] = 72,
[anon_sym_PLUS] = 72,
[anon_sym_DASH] = 72,
[anon_sym_STAR] = 72,
[anon_sym_SLASH] = 72,
[anon_sym_CARET] = 26,
[sym_comment] = 14,
},
[31] = {
[ts_builtin_sym_end] = 74,
[anon_sym_PLUS] = 74,
[anon_sym_DASH] = 74,
[anon_sym_STAR] = 22,
[anon_sym_SLASH] = 24,
[anon_sym_CARET] = 26,
[sym_comment] = 14,
},
[32] = {
[ts_builtin_sym_end] = 76,
[anon_sym_PLUS] = 76,
[anon_sym_DASH] = 76,
[anon_sym_STAR] = 22,
[anon_sym_SLASH] = 24,
[anon_sym_CARET] = 26,
[sym_comment] = 14,
},
};
static TSParseActionEntry ts_parse_actions[] = {
[0] = {.count = 1}, ERROR(),
[2] = {.count = 1}, SHIFT(1, 0),
[4] = {.count = 1}, SHIFT(2, 0),
[6] = {.count = 1}, SHIFT(3, 0),
[8] = {.count = 1}, SHIFT(4, 0),
[10] = {.count = 1}, SHIFT_EXTRA(),
[12] = {.count = 1}, ACCEPT_INPUT(),
[14] = {.count = 1}, SHIFT_EXTRA(),
[16] = {.count = 1}, REDUCE(sym_program, 1, 0),
[18] = {.count = 1}, SHIFT(23, 0),
[20] = {.count = 1}, SHIFT(24, 0),
[22] = {.count = 1}, SHIFT(25, 0),
[24] = {.count = 1}, SHIFT(26, 0),
[26] = {.count = 1}, SHIFT(27, 0),
[28] = {.count = 1}, REDUCE(sym__expression, 1, 0),
[30] = {.count = 1}, SHIFT(5, 0),
[32] = {.count = 1}, SHIFT(6, 0),
[34] = {.count = 1}, SHIFT(7, 0),
[36] = {.count = 1}, SHIFT(8, 0),
[38] = {.count = 1}, SHIFT(12, 0),
[40] = {.count = 1}, SHIFT(13, 0),
[42] = {.count = 1}, SHIFT(14, 0),
[44] = {.count = 1}, SHIFT(15, 0),
[46] = {.count = 1}, SHIFT(16, 0),
[48] = {.count = 1}, SHIFT(22, 0),
[50] = {.count = 1}, SHIFT(9, 0),
[52] = {.count = 1}, SHIFT(10, 0),
[54] = {.count = 1}, SHIFT(11, 0),
[56] = {.count = 1}, REDUCE(sym_group, 3, 0),
[58] = {.count = 1}, SHIFT(21, 0),
[60] = {.count = 1}, SHIFT(20, 0),
[62] = {.count = 1}, SHIFT(19, 0),
[64] = {.count = 1}, SHIFT(18, 0),
[66] = {.count = 1}, SHIFT(17, 0),
[68] = {.count = 1}, REDUCE(sym_exponent, 3, 0),
[70] = {.count = 1}, REDUCE(sym_quotient, 3, FRAGILE),
[72] = {.count = 1}, REDUCE(sym_product, 3, FRAGILE),
[74] = {.count = 1}, REDUCE(sym_difference, 3, FRAGILE),
[76] = {.count = 1}, REDUCE(sym_sum, 3, FRAGILE),
[78] = {.count = 1}, SHIFT(32, 0),
[80] = {.count = 1}, SHIFT(31, 0),
[82] = {.count = 1}, SHIFT(30, 0),
[84] = {.count = 1}, SHIFT(29, 0),
[86] = {.count = 1}, SHIFT(28, 0),
};
#pragma GCC diagnostic pop
EXPORT_LANGUAGE(ts_language_arithmetic);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,875 +0,0 @@
#include "tree_sitter/parser.h"
#define STATE_COUNT 69
#define SYMBOL_COUNT 18
enum {
sym__value = ts_builtin_sym_start,
sym_object,
sym_array,
aux_sym_object_repeat1,
aux_sym_array_repeat1,
anon_sym_LBRACE,
anon_sym_COLON,
anon_sym_COMMA,
anon_sym_RBRACE,
anon_sym_LBRACK,
anon_sym_RBRACK,
sym_string,
sym_number,
sym_null,
sym_true,
sym_false,
};
static const char *ts_symbol_names[] = {
[sym__value] = "_value",
[sym_object] = "object",
[sym_array] = "array",
[aux_sym_object_repeat1] = "object_repeat1",
[aux_sym_array_repeat1] = "array_repeat1",
[ts_builtin_sym_error] = "ERROR",
[ts_builtin_sym_end] = "END",
[anon_sym_LBRACE] = "{",
[anon_sym_COLON] = ":",
[anon_sym_COMMA] = ",",
[anon_sym_RBRACE] = "}",
[anon_sym_LBRACK] = "[",
[anon_sym_RBRACK] = "]",
[sym_string] = "string",
[sym_number] = "number",
[sym_null] = "null",
[sym_true] = "true",
[sym_false] = "false",
};
static const TSSymbolMetadata ts_symbol_metadata[SYMBOL_COUNT] = {
[sym__value] = {.visible = false, .named = false, .structural = true, .extra = false},
[sym_object] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_array] = {.visible = true, .named = true, .structural = true, .extra = false},
[aux_sym_object_repeat1] = {.visible = false, .named = false, .structural = true, .extra = false},
[aux_sym_array_repeat1] = {.visible = false, .named = false, .structural = true, .extra = false},
[ts_builtin_sym_error] = {.visible = true, .named = true, .structural = true, .extra = false},
[ts_builtin_sym_end] = {.visible = false, .named = false, .structural = true, .extra = false},
[anon_sym_LBRACE] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_COLON] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_COMMA] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_RBRACE] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_LBRACK] = {.visible = true, .named = false, .structural = true, .extra = false},
[anon_sym_RBRACK] = {.visible = true, .named = false, .structural = true, .extra = false},
[sym_string] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_number] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_null] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_true] = {.visible = true, .named = true, .structural = true, .extra = false},
[sym_false] = {.visible = true, .named = true, .structural = true, .extra = false},
};
static TSTree *ts_lex(TSLexer *lexer, TSStateId state, bool error_mode) {
START_LEXER();
switch (state) {
case 0:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(0);
if (lookahead == '\"')
ADVANCE(2);
if (lookahead == ',')
ADVANCE(6);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(7);
if (lookahead == ':')
ADVANCE(10);
if (lookahead == '[')
ADVANCE(11);
if (lookahead == ']')
ADVANCE(12);
if (lookahead == 'f')
ADVANCE(13);
if (lookahead == 'n')
ADVANCE(18);
if (lookahead == 't')
ADVANCE(22);
if (lookahead == '{')
ADVANCE(26);
if (lookahead == '}')
ADVANCE(27);
LEX_ERROR();
case 1:
ACCEPT_TOKEN(ts_builtin_sym_end);
case 2:
if (lookahead == '\"')
ADVANCE(3);
if (lookahead == '\\')
ADVANCE(4);
if (!((lookahead == 0) ||
(lookahead == '\"') ||
(lookahead == '\\')))
ADVANCE(2);
LEX_ERROR();
case 3:
ACCEPT_TOKEN(sym_string);
case 4:
if (lookahead == '\"')
ADVANCE(5);
if (lookahead == '\\')
ADVANCE(4);
if (!((lookahead == 0) ||
(lookahead == '\"') ||
(lookahead == '\\')))
ADVANCE(2);
LEX_ERROR();
case 5:
if (lookahead == '\"')
ADVANCE(3);
if (lookahead == '\\')
ADVANCE(4);
if (!((lookahead == 0) ||
(lookahead == '\"') ||
(lookahead == '\\')))
ADVANCE(2);
ACCEPT_TOKEN(sym_string);
case 6:
ACCEPT_TOKEN(anon_sym_COMMA);
case 7:
if (lookahead == '.')
ADVANCE(8);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(7);
ACCEPT_TOKEN(sym_number);
case 8:
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(9);
LEX_ERROR();
case 9:
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(9);
ACCEPT_TOKEN(sym_number);
case 10:
ACCEPT_TOKEN(anon_sym_COLON);
case 11:
ACCEPT_TOKEN(anon_sym_LBRACK);
case 12:
ACCEPT_TOKEN(anon_sym_RBRACK);
case 13:
if (lookahead == 'a')
ADVANCE(14);
LEX_ERROR();
case 14:
if (lookahead == 'l')
ADVANCE(15);
LEX_ERROR();
case 15:
if (lookahead == 's')
ADVANCE(16);
LEX_ERROR();
case 16:
if (lookahead == 'e')
ADVANCE(17);
LEX_ERROR();
case 17:
ACCEPT_TOKEN(sym_false);
case 18:
if (lookahead == 'u')
ADVANCE(19);
LEX_ERROR();
case 19:
if (lookahead == 'l')
ADVANCE(20);
LEX_ERROR();
case 20:
if (lookahead == 'l')
ADVANCE(21);
LEX_ERROR();
case 21:
ACCEPT_TOKEN(sym_null);
case 22:
if (lookahead == 'r')
ADVANCE(23);
LEX_ERROR();
case 23:
if (lookahead == 'u')
ADVANCE(24);
LEX_ERROR();
case 24:
if (lookahead == 'e')
ADVANCE(25);
LEX_ERROR();
case 25:
ACCEPT_TOKEN(sym_true);
case 26:
ACCEPT_TOKEN(anon_sym_LBRACE);
case 27:
ACCEPT_TOKEN(anon_sym_RBRACE);
case 28:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(28);
if (lookahead == '\"')
ADVANCE(2);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(7);
if (lookahead == '[')
ADVANCE(11);
if (lookahead == 'f')
ADVANCE(13);
if (lookahead == 'n')
ADVANCE(18);
if (lookahead == 't')
ADVANCE(22);
if (lookahead == '{')
ADVANCE(26);
LEX_ERROR();
case 29:
START_TOKEN();
if (lookahead == 0)
ADVANCE(1);
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(29);
LEX_ERROR();
case 30:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(30);
if (lookahead == '\"')
ADVANCE(2);
if (lookahead == '}')
ADVANCE(27);
LEX_ERROR();
case 31:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(31);
if (lookahead == '\"')
ADVANCE(2);
if ('0' <= lookahead && lookahead <= '9')
ADVANCE(7);
if (lookahead == '[')
ADVANCE(11);
if (lookahead == ']')
ADVANCE(12);
if (lookahead == 'f')
ADVANCE(13);
if (lookahead == 'n')
ADVANCE(18);
if (lookahead == 't')
ADVANCE(22);
if (lookahead == '{')
ADVANCE(26);
LEX_ERROR();
case 32:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(32);
if (lookahead == ',')
ADVANCE(6);
if (lookahead == ']')
ADVANCE(12);
LEX_ERROR();
case 33:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(33);
if (lookahead == ']')
ADVANCE(12);
LEX_ERROR();
case 34:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(34);
if (lookahead == ',')
ADVANCE(6);
if (lookahead == '}')
ADVANCE(27);
LEX_ERROR();
case 35:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(35);
if (lookahead == ':')
ADVANCE(10);
LEX_ERROR();
case 36:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(36);
if (lookahead == '}')
ADVANCE(27);
LEX_ERROR();
case 37:
START_TOKEN();
if ((lookahead == '\t') ||
(lookahead == '\n') ||
(lookahead == '\r') ||
(lookahead == ' '))
ADVANCE(37);
if (lookahead == '\"')
ADVANCE(2);
LEX_ERROR();
default:
LEX_ERROR();
}
}
static TSStateId ts_lex_states[STATE_COUNT] = {
[0] = 28,
[1] = 29,
[2] = 29,
[3] = 30,
[4] = 31,
[5] = 32,
[6] = 32,
[7] = 30,
[8] = 31,
[9] = 29,
[10] = 32,
[11] = 32,
[12] = 33,
[13] = 28,
[14] = 32,
[15] = 32,
[16] = 33,
[17] = 32,
[18] = 34,
[19] = 32,
[20] = 35,
[21] = 28,
[22] = 34,
[23] = 34,
[24] = 30,
[25] = 31,
[26] = 32,
[27] = 34,
[28] = 33,
[29] = 34,
[30] = 34,
[31] = 34,
[32] = 34,
[33] = 35,
[34] = 28,
[35] = 34,
[36] = 36,
[37] = 37,
[38] = 34,
[39] = 34,
[40] = 35,
[41] = 28,
[42] = 34,
[43] = 36,
[44] = 36,
[45] = 34,
[46] = 36,
[47] = 34,
[48] = 34,
[49] = 36,
[50] = 32,
[51] = 32,
[52] = 36,
[53] = 32,
[54] = 32,
[55] = 33,
[56] = 29,
[57] = 29,
[58] = 34,
[59] = 29,
[60] = 35,
[61] = 28,
[62] = 34,
[63] = 36,
[64] = 29,
[65] = 29,
[66] = 36,
[67] = 29,
[68] = 29,
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
static unsigned short ts_parse_table[STATE_COUNT][SYMBOL_COUNT] = {
[0] = {
[sym__value] = 2,
[sym_object] = 4,
[sym_array] = 4,
[anon_sym_LBRACE] = 6,
[anon_sym_LBRACK] = 8,
[sym_string] = 4,
[sym_number] = 4,
[sym_null] = 4,
[sym_true] = 4,
[sym_false] = 4,
},
[1] = {
[ts_builtin_sym_end] = 10,
},
[2] = {
[ts_builtin_sym_end] = 12,
},
[3] = {
[ts_builtin_sym_error] = 14,
[anon_sym_RBRACE] = 16,
[sym_string] = 18,
},
[4] = {
[sym__value] = 20,
[sym_object] = 22,
[sym_array] = 22,
[ts_builtin_sym_error] = 20,
[anon_sym_LBRACE] = 24,
[anon_sym_LBRACK] = 26,
[anon_sym_RBRACK] = 28,
[sym_string] = 22,
[sym_number] = 22,
[sym_null] = 22,
[sym_true] = 22,
[sym_false] = 22,
},
[5] = {
[aux_sym_array_repeat1] = 30,
[anon_sym_COMMA] = 32,
[anon_sym_RBRACK] = 34,
},
[6] = {
[aux_sym_array_repeat1] = 12,
[anon_sym_COMMA] = 12,
[anon_sym_RBRACK] = 12,
},
[7] = {
[ts_builtin_sym_error] = 36,
[anon_sym_RBRACE] = 38,
[sym_string] = 40,
},
[8] = {
[sym__value] = 42,
[sym_object] = 22,
[sym_array] = 22,
[ts_builtin_sym_error] = 42,
[anon_sym_LBRACE] = 24,
[anon_sym_LBRACK] = 26,
[anon_sym_RBRACK] = 44,
[sym_string] = 22,
[sym_number] = 22,
[sym_null] = 22,
[sym_true] = 22,
[sym_false] = 22,
},
[9] = {
[ts_builtin_sym_end] = 46,
},
[10] = {
[aux_sym_array_repeat1] = 48,
[anon_sym_COMMA] = 32,
[anon_sym_RBRACK] = 50,
},
[11] = {
[aux_sym_array_repeat1] = 46,
[anon_sym_COMMA] = 46,
[anon_sym_RBRACK] = 46,
},
[12] = {
[anon_sym_RBRACK] = 52,
},
[13] = {
[sym__value] = 54,
[sym_object] = 22,
[sym_array] = 22,
[ts_builtin_sym_error] = 54,
[anon_sym_LBRACE] = 24,
[anon_sym_LBRACK] = 26,
[sym_string] = 22,
[sym_number] = 22,
[sym_null] = 22,
[sym_true] = 22,
[sym_false] = 22,
},
[14] = {
[aux_sym_array_repeat1] = 56,
[anon_sym_COMMA] = 56,
[anon_sym_RBRACK] = 56,
},
[15] = {
[aux_sym_array_repeat1] = 58,
[anon_sym_COMMA] = 32,
[anon_sym_RBRACK] = 60,
},
[16] = {
[anon_sym_RBRACK] = 62,
},
[17] = {
[aux_sym_array_repeat1] = 64,
[anon_sym_COMMA] = 64,
[anon_sym_RBRACK] = 64,
},
[18] = {
[aux_sym_object_repeat1] = 66,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 70,
},
[19] = {
[aux_sym_array_repeat1] = 72,
[anon_sym_COMMA] = 72,
[anon_sym_RBRACK] = 72,
},
[20] = {
[anon_sym_COLON] = 74,
},
[21] = {
[sym__value] = 76,
[sym_object] = 78,
[sym_array] = 78,
[anon_sym_LBRACE] = 80,
[anon_sym_LBRACK] = 82,
[sym_string] = 78,
[sym_number] = 78,
[sym_null] = 78,
[sym_true] = 78,
[sym_false] = 78,
},
[22] = {
[aux_sym_object_repeat1] = 84,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 86,
},
[23] = {
[aux_sym_object_repeat1] = 12,
[anon_sym_COMMA] = 12,
[anon_sym_RBRACE] = 12,
},
[24] = {
[ts_builtin_sym_error] = 88,
[anon_sym_RBRACE] = 90,
[sym_string] = 92,
},
[25] = {
[sym__value] = 94,
[sym_object] = 22,
[sym_array] = 22,
[ts_builtin_sym_error] = 94,
[anon_sym_LBRACE] = 24,
[anon_sym_LBRACK] = 26,
[anon_sym_RBRACK] = 96,
[sym_string] = 22,
[sym_number] = 22,
[sym_null] = 22,
[sym_true] = 22,
[sym_false] = 22,
},
[26] = {
[aux_sym_array_repeat1] = 98,
[anon_sym_COMMA] = 32,
[anon_sym_RBRACK] = 100,
},
[27] = {
[aux_sym_object_repeat1] = 46,
[anon_sym_COMMA] = 46,
[anon_sym_RBRACE] = 46,
},
[28] = {
[anon_sym_RBRACK] = 102,
},
[29] = {
[aux_sym_object_repeat1] = 56,
[anon_sym_COMMA] = 56,
[anon_sym_RBRACE] = 56,
},
[30] = {
[aux_sym_object_repeat1] = 64,
[anon_sym_COMMA] = 64,
[anon_sym_RBRACE] = 64,
},
[31] = {
[aux_sym_object_repeat1] = 104,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 106,
},
[32] = {
[aux_sym_object_repeat1] = 72,
[anon_sym_COMMA] = 72,
[anon_sym_RBRACE] = 72,
},
[33] = {
[anon_sym_COLON] = 108,
},
[34] = {
[sym__value] = 110,
[sym_object] = 78,
[sym_array] = 78,
[anon_sym_LBRACE] = 80,
[anon_sym_LBRACK] = 82,
[sym_string] = 78,
[sym_number] = 78,
[sym_null] = 78,
[sym_true] = 78,
[sym_false] = 78,
},
[35] = {
[aux_sym_object_repeat1] = 112,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 114,
},
[36] = {
[anon_sym_RBRACE] = 116,
},
[37] = {
[ts_builtin_sym_error] = 118,
[sym_string] = 120,
},
[38] = {
[aux_sym_object_repeat1] = 122,
[anon_sym_COMMA] = 122,
[anon_sym_RBRACE] = 122,
},
[39] = {
[aux_sym_object_repeat1] = 124,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 126,
},
[40] = {
[anon_sym_COLON] = 128,
},
[41] = {
[sym__value] = 130,
[sym_object] = 78,
[sym_array] = 78,
[anon_sym_LBRACE] = 80,
[anon_sym_LBRACK] = 82,
[sym_string] = 78,
[sym_number] = 78,
[sym_null] = 78,
[sym_true] = 78,
[sym_false] = 78,
},
[42] = {
[aux_sym_object_repeat1] = 132,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 134,
},
[43] = {
[anon_sym_RBRACE] = 136,
},
[44] = {
[anon_sym_RBRACE] = 138,
},
[45] = {
[aux_sym_object_repeat1] = 140,
[anon_sym_COMMA] = 140,
[anon_sym_RBRACE] = 140,
},
[46] = {
[anon_sym_RBRACE] = 142,
},
[47] = {
[aux_sym_object_repeat1] = 144,
[anon_sym_COMMA] = 144,
[anon_sym_RBRACE] = 144,
},
[48] = {
[aux_sym_object_repeat1] = 146,
[anon_sym_COMMA] = 146,
[anon_sym_RBRACE] = 146,
},
[49] = {
[anon_sym_RBRACE] = 148,
},
[50] = {
[aux_sym_array_repeat1] = 122,
[anon_sym_COMMA] = 122,
[anon_sym_RBRACK] = 122,
},
[51] = {
[aux_sym_array_repeat1] = 140,
[anon_sym_COMMA] = 140,
[anon_sym_RBRACK] = 140,
},
[52] = {
[anon_sym_RBRACE] = 150,
},
[53] = {
[aux_sym_array_repeat1] = 144,
[anon_sym_COMMA] = 144,
[anon_sym_RBRACK] = 144,
},
[54] = {
[aux_sym_array_repeat1] = 146,
[anon_sym_COMMA] = 146,
[anon_sym_RBRACK] = 146,
},
[55] = {
[anon_sym_RBRACK] = 152,
},
[56] = {
[ts_builtin_sym_end] = 56,
},
[57] = {
[ts_builtin_sym_end] = 64,
},
[58] = {
[aux_sym_object_repeat1] = 154,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 156,
},
[59] = {
[ts_builtin_sym_end] = 72,
},
[60] = {
[anon_sym_COLON] = 158,
},
[61] = {
[sym__value] = 160,
[sym_object] = 78,
[sym_array] = 78,
[anon_sym_LBRACE] = 80,
[anon_sym_LBRACK] = 82,
[sym_string] = 78,
[sym_number] = 78,
[sym_null] = 78,
[sym_true] = 78,
[sym_false] = 78,
},
[62] = {
[aux_sym_object_repeat1] = 162,
[anon_sym_COMMA] = 68,
[anon_sym_RBRACE] = 164,
},
[63] = {
[anon_sym_RBRACE] = 166,
},
[64] = {
[ts_builtin_sym_end] = 122,
},
[65] = {
[ts_builtin_sym_end] = 140,
},
[66] = {
[anon_sym_RBRACE] = 168,
},
[67] = {
[ts_builtin_sym_end] = 144,
},
[68] = {
[ts_builtin_sym_end] = 146,
},
};
static TSParseActionEntry ts_parse_actions[] = {
[0] = {.count = 1}, ERROR(),
[2] = {.count = 1}, SHIFT(1, 0),
[4] = {.count = 1}, SHIFT(2, 0),
[6] = {.count = 1}, SHIFT(3, 0),
[8] = {.count = 1}, SHIFT(4, 0),
[10] = {.count = 1}, ACCEPT_INPUT(),
[12] = {.count = 1}, REDUCE(sym__value, 1, 0),
[14] = {.count = 1}, SHIFT(58, 0),
[16] = {.count = 1}, SHIFT(59, 0),
[18] = {.count = 1}, SHIFT(60, 0),
[20] = {.count = 1}, SHIFT(5, 0),
[22] = {.count = 1}, SHIFT(6, 0),
[24] = {.count = 1}, SHIFT(7, 0),
[26] = {.count = 1}, SHIFT(8, 0),
[28] = {.count = 1}, SHIFT(9, 0),
[30] = {.count = 1}, SHIFT(55, 0),
[32] = {.count = 1}, SHIFT(13, 0),
[34] = {.count = 1}, SHIFT(56, 0),
[36] = {.count = 1}, SHIFT(18, 0),
[38] = {.count = 1}, SHIFT(19, 0),
[40] = {.count = 1}, SHIFT(20, 0),
[42] = {.count = 1}, SHIFT(10, 0),
[44] = {.count = 1}, SHIFT(11, 0),
[46] = {.count = 1}, REDUCE(sym_array, 2, 0),
[48] = {.count = 1}, SHIFT(12, 0),
[50] = {.count = 1}, SHIFT(14, 0),
[52] = {.count = 1}, SHIFT(17, 0),
[54] = {.count = 1}, SHIFT(15, 0),
[56] = {.count = 1}, REDUCE(sym_array, 3, 0),
[58] = {.count = 1}, SHIFT(16, 0),
[60] = {.count = 1}, REDUCE(aux_sym_array_repeat1, 2, 0),
[62] = {.count = 1}, REDUCE(aux_sym_array_repeat1, 3, 0),
[64] = {.count = 1}, REDUCE(sym_array, 4, 0),
[66] = {.count = 1}, SHIFT(52, 0),
[68] = {.count = 1}, SHIFT(37, 0),
[70] = {.count = 1}, SHIFT(53, 0),
[72] = {.count = 1}, REDUCE(sym_object, 2, 0),
[74] = {.count = 1}, SHIFT(21, 0),
[76] = {.count = 1}, SHIFT(22, 0),
[78] = {.count = 1}, SHIFT(23, 0),
[80] = {.count = 1}, SHIFT(24, 0),
[82] = {.count = 1}, SHIFT(25, 0),
[84] = {.count = 1}, SHIFT(49, 0),
[86] = {.count = 1}, SHIFT(50, 0),
[88] = {.count = 1}, SHIFT(31, 0),
[90] = {.count = 1}, SHIFT(32, 0),
[92] = {.count = 1}, SHIFT(33, 0),
[94] = {.count = 1}, SHIFT(26, 0),
[96] = {.count = 1}, SHIFT(27, 0),
[98] = {.count = 1}, SHIFT(28, 0),
[100] = {.count = 1}, SHIFT(29, 0),
[102] = {.count = 1}, SHIFT(30, 0),
[104] = {.count = 1}, SHIFT(46, 0),
[106] = {.count = 1}, SHIFT(47, 0),
[108] = {.count = 1}, SHIFT(34, 0),
[110] = {.count = 1}, SHIFT(35, 0),
[112] = {.count = 1}, SHIFT(36, 0),
[114] = {.count = 1}, SHIFT(38, 0),
[116] = {.count = 1}, SHIFT(45, 0),
[118] = {.count = 1}, SHIFT(39, 0),
[120] = {.count = 1}, SHIFT(40, 0),
[122] = {.count = 1}, REDUCE(sym_object, 5, 0),
[124] = {.count = 1}, SHIFT(44, 0),
[126] = {.count = 1}, REDUCE(aux_sym_object_repeat1, 2, 0),
[128] = {.count = 1}, SHIFT(41, 0),
[130] = {.count = 1}, SHIFT(42, 0),
[132] = {.count = 1}, SHIFT(43, 0),
[134] = {.count = 1}, REDUCE(aux_sym_object_repeat1, 4, 0),
[136] = {.count = 1}, REDUCE(aux_sym_object_repeat1, 5, 0),
[138] = {.count = 1}, REDUCE(aux_sym_object_repeat1, 3, 0),
[140] = {.count = 1}, REDUCE(sym_object, 6, 0),
[142] = {.count = 1}, SHIFT(48, 0),
[144] = {.count = 1}, REDUCE(sym_object, 3, 0),
[146] = {.count = 1}, REDUCE(sym_object, 4, 0),
[148] = {.count = 1}, SHIFT(51, 0),
[150] = {.count = 1}, SHIFT(54, 0),
[152] = {.count = 1}, SHIFT(57, 0),
[154] = {.count = 1}, SHIFT(66, 0),
[156] = {.count = 1}, SHIFT(67, 0),
[158] = {.count = 1}, SHIFT(61, 0),
[160] = {.count = 1}, SHIFT(62, 0),
[162] = {.count = 1}, SHIFT(63, 0),
[164] = {.count = 1}, SHIFT(64, 0),
[166] = {.count = 1}, SHIFT(65, 0),
[168] = {.count = 1}, SHIFT(68, 0),
};
#pragma GCC diagnostic pop
EXPORT_LANGUAGE(ts_language_json);

View file

@ -1,4 +1,4 @@
#include "runtime/helpers/encoding_helpers.h"
#include "helpers/encoding_helpers.h"
#include "runtime/utf16.h"
#include <assert.h>
#include "utf8proc.h"

View file

@ -0,0 +1,122 @@
#include "spec_helper.h"
#include "helpers/load_language.h"
#include <unistd.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <fstream>
#include "tree_sitter/compiler.h"
using std::string;
using std::ofstream;
static std::string run_cmd(const char *cmd, const char *args[]) {
int child_pid = fork();
if (child_pid < 0)
return "fork failed";
if (child_pid == 0) {
close(0);
dup2(1, 0);
dup2(2, 1);
dup2(1, 2);
execvp(cmd, (char * const * )args);
return "";
}
int status;
do {
waitpid(child_pid, &status, 0);
} while (!WIFEXITED(status));
if (WEXITSTATUS(status) == 0)
return "";
else
return "command failed";
return "";
}
const TSLanguage *load_language(const string &name, const TSCompileResult &compile_result) {
if (compile_result.error_type != TSCompileErrorTypeNone) {
AssertThat(string(compile_result.error_message), IsEmpty());
return nullptr;
}
return load_language(name, compile_result.code);
}
const TSLanguage *load_language(const string &name, const string &code) {
string language_function_name = "ts_language_" + name;
static char source_file_template[256] = {};
snprintf(source_file_template, 256, "/tmp/tree-sitter-test-%sXXXXXXXXX", name.c_str());
const char *temp_directory = mkdtemp(source_file_template);
if (!temp_directory) {
AssertThat(string("Failed to create temp directory"), IsEmpty());
return nullptr;
}
string source_filename = string(temp_directory) + "/parser.c";
string obj_filename = string(source_filename) + ".o";
string lib_filename = string(source_filename) + ".so";
string header_dir = string(getenv("PWD")) + "/include";
ofstream source_file;
source_file.open(source_filename);
source_file << code;
source_file.close();
const char *compiler_name = getenv("CC");
if (!compiler_name) {
compiler_name = "gcc";
}
const char *compile_argv[] = {
compiler_name,
"-x", "c",
"-fPIC",
"-I", header_dir.c_str(),
"-c", source_filename.c_str(),
"-o", obj_filename.c_str(),
NULL
};
string compile_error = run_cmd("gcc", compile_argv);
if (!compile_error.empty()) {
AssertThat(string(compile_error), IsEmpty());
return nullptr;
}
const char *link_argv[] = {
compiler_name,
"-shared",
"-Wl", obj_filename.c_str(),
"-o", lib_filename.c_str(),
NULL
};
string link_error = run_cmd("gcc", link_argv);
if (!link_error.empty()) {
AssertThat(link_error, IsEmpty());
return nullptr;
}
void *parser_lib = dlopen(lib_filename.c_str(), RTLD_NOW);
if (!parser_lib) {
std::string message(dlerror());
AssertThat(message, IsEmpty());
return nullptr;
}
void *symbol_value = dlsym(parser_lib, language_function_name.c_str());
if (!symbol_value) {
std::string message(dlerror());
AssertThat(message, IsEmpty());
return nullptr;
}
typedef TSLanguage * (* LanguageFunction)();
LanguageFunction language_fn = reinterpret_cast<LanguageFunction>(symbol_value);
return language_fn();
}

View file

@ -0,0 +1,11 @@
#ifndef HELPERS_LOAD_LANGUAGE_H_
#define HELPERS_LOAD_LANGUAGE_H_
#include "tree_sitter/compiler.h"
#include "tree_sitter/runtime.h"
#include <string>
const TSLanguage *load_language(const std::string &, const std::string &);
const TSLanguage *load_language(const std::string &, const TSCompileResult &);
#endif // HELPERS_LOAD_LANGUAGE_H_

View file

@ -1,3 +1,5 @@
#ifndef HELPERS_POINT_HELPERS_H_
#define HELPERS_POINT_HELPERS_H_
bool operator==(const TSPoint &left, const TSPoint &right);
@ -6,3 +8,5 @@ bool operator<(const TSPoint &left, const TSPoint &right);
bool operator>(const TSPoint &left, const TSPoint &right);
std::ostream &operator<<(std::ostream &stream, const TSPoint &point);
#endif // HELPERS_POINT_HELPERS_H_

View file

@ -1,4 +1,4 @@
#include "runtime/helpers/read_test_entries.h"
#include "helpers/read_test_entries.h"
#include <string>
#include <fstream>
#include <streambuf>
@ -94,16 +94,9 @@ static vector<string> list_directory(string dir_name) {
return result;
}
static string src_dir() {
const char *dir = getenv("TREESITTER_DIR");
if (!dir) dir = getenv("PWD");
return dir;
}
vector<TestEntry> test_entries_for_language(string language) {
vector<TestEntry> read_corpus_entries(string directory) {
vector<TestEntry> result;
string language_dir = src_dir() + "/spec/fixtures/corpus/" + language;
vector<string> filenames = list_directory(language_dir);
vector<string> filenames = list_directory(directory);
for (string &filename : filenames) {
ifstream file(filename);

View file

@ -10,6 +10,6 @@ struct TestEntry {
std::string tree_string;
};
std::vector<TestEntry> test_entries_for_language(std::string language);
std::vector<TestEntry> read_corpus_entries(std::string directory);
#endif

View file

@ -1,7 +1,8 @@
#ifndef __tree_sitter__character_set_helpers__
#define __tree_sitter__character_set_helpers__
#ifndef HELPERS_RULE_HELPERS_H_
#define HELPERS_RULE_HELPERS_H_
#include "tree_sitter/compiler.h"
#include "compiler/rules.h"
#include "compiler/rules/character_set.h"
#include "compiler/rules/metadata.h"
#include "compiler/variable.h"
@ -17,4 +18,4 @@ namespace tree_sitter {
bool operator==(const Variable &left, const Variable &right);
}
#endif
#endif // HELPERS_RULE_HELPERS_H_

View file

@ -1,4 +1,4 @@
#include "runtime/helpers/spy_debugger.h"
#include "helpers/spy_debugger.h"
#include <string>
#include <vector>

View file

@ -1,5 +1,5 @@
#include "runtime/helpers/spy_input.h"
#include "runtime/helpers/encoding_helpers.h"
#include "helpers/spy_input.h"
#include "helpers/encoding_helpers.h"
#include <string.h>
#include <algorithm>
#include <assert.h>

View file

@ -1,5 +1,5 @@
#ifndef HELPERS_spy_input_H_
#define HELPERS_spy_input_H_
#ifndef HELPERS_SPY_INPUT_H_
#define HELPERS_SPY_INPUT_H_
#include <string>
#include <vector>
@ -36,4 +36,4 @@ class SpyInput {
std::vector<std::string> strings_read;
};
#endif // HELPERS_spy_input_H_
#endif // HELPERS_SPY_INPUT_H_

View file

@ -1,5 +1,5 @@
#include "compiler/helpers/stream_methods.h"
#include "compiler/compiler_spec_helper.h"
#include "helpers/stream_methods.h"
#include "spec_helper.h"
#include "tree_sitter/compiler.h"
#include "compiler/parse_table.h"
#include "compiler/syntax_grammar.h"

View file

@ -1,5 +1,5 @@
#ifndef tree_sitter_stream_methods_h
#define tree_sitter_stream_methods_h
#ifndef HELPERS_STREAM_METHODS_H_
#define HELPERS_STREAM_METHODS_H_
#include <iostream>
#include <set>
@ -127,4 +127,4 @@ ostream &operator<<(ostream &, const LookaheadSet &);
} // namespace build_tables
} // namespace tree_sitter
#endif
#endif // HELPERS_STREAM_METHODS_H_

View file

@ -0,0 +1,72 @@
#include "helpers/test_languages.h"
#include "helpers/load_language.h"
#include <sys/stat.h>
#include <fstream>
#include <map>
#include <string>
using std::map;
using std::string;
using std::ifstream;
using std::ofstream;
using std::istreambuf_iterator;
map<string, const TSLanguage *> loaded_languages;
int libcompiler_mtime = -1;
static int get_modified_time(const string &path) {
struct stat file_stat;
int error = stat(path.c_str(), &file_stat);
if (error != 0) {
fprintf(stderr, "Error in stat() for path: %s", + path.c_str());
return 0;
}
return file_stat.st_mtime;
}
const TSLanguage *get_test_language(const string &language_name) {
if (libcompiler_mtime == -1) {
libcompiler_mtime = get_modified_time("out/Debug/libcompiler.a");
}
if (loaded_languages[language_name]) {
return loaded_languages[language_name];
}
string language_dir = string("spec/fixtures/") + language_name;
string grammar_filename = language_dir + "/src/grammar.json";
string parser_filename = language_dir + "/src/parser.c";
int grammar_mtime = get_modified_time(grammar_filename);
int parser_mtime = get_modified_time(parser_filename);
string parser_code;
if (parser_mtime <= grammar_mtime || parser_mtime <= libcompiler_mtime) {
printf("\n" "Regenerating the %s parser...\n", language_name.c_str());
ifstream grammar_file(grammar_filename);
istreambuf_iterator<char> grammar_file_iterator(grammar_file), end_iterator;
std::string grammar_json(grammar_file_iterator, end_iterator);
TSCompileResult result = ts_compile_grammar(grammar_json.c_str());
if (result.error_type != TSCompileErrorTypeNone) {
fprintf(stderr, "Failed to compile %s grammar: %s\n", language_name.c_str(), result.error_message);
return nullptr;
}
ofstream parser_file(parser_filename);
parser_file << result.code;
parser_code = result.code;
grammar_file.close();
parser_file.close();
} else {
ifstream parser_file(parser_filename);
istreambuf_iterator<char> grammar_file_iterator(parser_file), end_iterator;
parser_code.assign(grammar_file_iterator, end_iterator);
}
const TSLanguage *language = load_language(language_name, parser_code);
loaded_languages[language_name] = language;
return language;
};

View file

@ -0,0 +1,9 @@
#ifndef HELPERS_TEST_LANGUAGES_H_
#define HELPERS_TEST_LANGUAGES_H_
#include "tree_sitter/runtime.h"
#include <string>
const TSLanguage *get_test_language(const std::string &);
#endif // HELPERS_TEST_LANGUAGES_H_

View file

@ -1,4 +1,4 @@
#include "runtime/helpers/tree_helpers.h"
#include "helpers/tree_helpers.h"
#include <ostream>
using std::string;

View file

@ -0,0 +1,191 @@
#include "spec_helper.h"
#include "helpers/load_language.h"
START_TEST
describe("compile_grammar", []() {
TSDocument *document;
before_each([&]() {
document = ts_document_make();
});
after_each([&]() {
ts_document_free(document);
});
describe("when the grammar's start symbol is a token", [&]() {
it("parses the token", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON(
{
"name": "test_language",
"rules": {
"first_rule": {"type": "STRING", "value": "the-value"}
}
}
)JSON");
ts_document_set_language(document, load_language("test_language", result));
ts_document_set_input_string(document, "the-value");
ts_document_parse(document);
TSNode root_node = ts_document_root_node(document);
AssertThat(ts_node_string(root_node, document), Equals("(first_rule)"));
});
});
describe("when the grammar's start symbol is blank", [&]() {
it("parses the empty string", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON(
{
"name": "test_language",
"rules": {
"first_rule": {"type": "BLANK"}
}
}
)JSON");
ts_document_set_language(document, load_language("test_language", result));
ts_document_set_input_string(document, "");
ts_document_parse(document);
TSNode root_node = ts_document_root_node(document);
AssertThat(ts_node_string(root_node, document), Equals("(first_rule)"));
});
});
describe("when the grammar contains anonymous tokens with escaped characters", [&]() {
it("escapes the escaped characters properly in the generated parser", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON(
{
"name": "test_language",
"rules": {
"first_rule": {
"type": "CHOICE",
"members": [
{"type": "STRING", "value": "\n"},
{"type": "STRING", "value": "\r"},
{"type": "STRING", "value": "'hello'"},
{"type": "PATTERN", "value": "\\d+"}
]
}
}
}
)JSON");
ts_document_set_language(document, load_language("test_language", result));
ts_document_set_input_string(document, "1234");
ts_document_parse(document);
TSNode root_node = ts_document_root_node(document);
AssertThat(ts_node_string(root_node, document), Equals("(first_rule)"));
ts_document_set_input_string(document, "\n");
ts_document_parse(document);
root_node = ts_document_root_node(document);
AssertThat(ts_node_string(root_node, document), Equals("(first_rule)"));
ts_document_set_input_string(document, "'hello'");
ts_document_parse(document);
root_node = ts_document_root_node(document);
AssertThat(ts_node_string(root_node, document), Equals("(first_rule)"));
});
});
describe("the grammar in the README", [&]() {
it("works", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON(
{
"name": "arithmetic",
// Things that can appear anywhere in the language, like comments
// and whitespace, are expressed as 'extras'.
"extras": [
{"type": "PATTERN", "value": "\\s"},
{"type": "SYMBOL", "name": "comment"}
],
"rules": {
// The first rule listed in the grammar becomes the 'start rule'.
"expression": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "sum"},
{"type": "SYMBOL", "name": "product"},
{"type": "SYMBOL", "name": "number"},
{"type": "SYMBOL", "name": "variable"},
{
"type": "SEQ",
"members": [
{"type": "STRING", "value": "("},
// Error recovery is controlled by wrapping rule subtrees
// in an 'ERROR' rule.
{
"type": "ERROR",
"content": {"type": "SYMBOL", "name": "expression"}
},
{"type": "STRING", "value": ")"}
]
}
]
},
// Tokens like '+' and '*' are described directly within the
// grammar's rules, as opposed to in a seperate lexer description.
"sum": {
"type": "PREC_LEFT",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": "+"},
{"type": "SYMBOL", "name": "expression"}
]
}
},
// Ambiguities can be resolved at compile time by assigning precedence
// values to rule subtrees.
"product": {
"type": "PREC_LEFT",
"value": 2,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": "*"},
{"type": "SYMBOL", "name": "expression"}
]
}
},
// Tokens can be specified using ECMAScript regexps.
"number": {"type": "PATTERN", "value": "\\d+"},
"comment": {"type": "PATTERN", "value": "#.*"},
"variable": {"type": "PATTERN", "value": "[a-zA-Z]\\w*"}
}
}
)JSON");
const TSLanguage *language = load_language("arithmetic", result);
ts_document_set_language(document, language);
ts_document_set_input_string(document, "a + b * c");
ts_document_parse(document);
TSNode root_node = ts_document_root_node(document);
AssertThat(ts_node_string(root_node, document), Equals(
"(expression (sum "
"(expression (variable)) "
"(expression (product "
"(expression (variable)) "
"(expression (variable))))))"));
});
});
});
END_TEST

View file

@ -1,37 +1,19 @@
#include "runtime/runtime_spec_helper.h"
#include <functional>
#include "spec_helper.h"
#include "helpers/test_languages.h"
#include "helpers/read_test_entries.h"
#include "helpers/spy_input.h"
#include "helpers/log_debugger.h"
#include "helpers/point_helpers.h"
#include "helpers/encoding_helpers.h"
#include <set>
#include <utility>
#include "runtime/length.h"
#include "runtime/helpers/read_test_entries.h"
#include "runtime/helpers/spy_input.h"
#include "runtime/helpers/log_debugger.h"
#include "runtime/helpers/point_helpers.h"
#include "runtime/helpers/encoding_helpers.h"
extern "C" const TSLanguage *ts_language_javascript();
extern "C" const TSLanguage *ts_language_json();
extern "C" const TSLanguage *ts_language_arithmetic();
extern "C" const TSLanguage *ts_language_golang();
extern "C" const TSLanguage *ts_language_c();
extern "C" const TSLanguage *ts_language_cpp();
map<string, const TSLanguage *> languages({
{"json", ts_language_json()},
{"arithmetic", ts_language_arithmetic()},
{"javascript", ts_language_javascript()},
{"golang", ts_language_golang()},
{"c", ts_language_c()},
{"cpp", ts_language_cpp()},
});
void expect_the_correct_tree(TSNode node, TSDocument *doc, string tree_string) {
const char *node_string = ts_node_string(node, doc);
static void expect_the_correct_tree(TSNode node, TSDocument *document, string tree_string) {
const char *node_string = ts_node_string(node, document);
AssertThat(node_string, Equals(tree_string));
free((void *)node_string);
}
void expect_a_consistent_tree(TSNode node, TSDocument *doc) {
static void expect_a_consistent_tree(TSNode node, TSDocument *document) {
size_t child_count = ts_node_child_count(node);
size_t start_char = ts_node_start_char(node);
size_t end_char = ts_node_end_char(node);
@ -65,7 +47,7 @@ void expect_a_consistent_tree(TSNode node, TSDocument *doc) {
AssertThat(child_start_point, !IsLessThan(start_point));
AssertThat(child_end_point, !IsGreaterThan(end_point));
expect_a_consistent_tree(child, doc);
expect_a_consistent_tree(child, document);
if (ts_node_has_changes(child))
some_child_has_changes = true;
@ -75,7 +57,7 @@ void expect_a_consistent_tree(TSNode node, TSDocument *doc) {
AssertThat(has_changes, Equals(some_child_has_changes));
}
string random_string(char min, char max) {
static string random_string(char min, char max) {
string result;
size_t length = random() % 12;
for (size_t i = 0; i < length; i++) {
@ -85,12 +67,12 @@ string random_string(char min, char max) {
return result;
}
string random_char(string characters) {
static string random_char(string characters) {
size_t index = random() % characters.size();
return string() + characters[index];
}
string random_words(size_t count) {
static string random_words(size_t count) {
string result;
bool just_inserted_word = false;
for (size_t i = 0; i < count; i++) {
@ -108,44 +90,60 @@ string random_words(size_t count) {
START_TEST
describe("Languages", [&]() {
for (const auto &pair : languages) {
describe(("The " + pair.first + " parser").c_str(), [&]() {
TSDocument *doc;
describe("The Corpus", []() {
vector<string> test_languages({
"javascript",
"json",
"c",
"cpp",
});
for (auto &language_name : test_languages) {
string language_dir = string("spec/fixtures/") + language_name;
describe(("the " + language_name + " language").c_str(), [&]() {
TSDocument *document;
before_each([&]() {
doc = ts_document_make();
ts_document_set_language(doc, pair.second);
// ts_document_set_debugger(doc, log_debugger_make(true));
document = ts_document_make();
ts_document_set_language(document, get_test_language(language_name));
// ts_document_set_debugger(document, log_debugger_make(true));
});
after_each([&]() {
ts_document_free(doc);
ts_document_free(document);
});
for (auto &entry : test_entries_for_language(pair.first)) {
for (auto &entry : read_corpus_entries(language_dir + "/grammar_test")) {
SpyInput *input;
auto it_handles_edit_sequence = [&](string name, std::function<void()> edit_sequence){
it(("parses " + entry.description + ": " + name).c_str(), [&]() {
input = new SpyInput(entry.input, 3);
ts_document_set_input(doc, input->input());
ts_document_set_input(document, input->input());
edit_sequence();
TSNode root_node = ts_document_root_node(doc);
expect_the_correct_tree(root_node, doc, entry.tree_string);
expect_a_consistent_tree(root_node, doc);
TSNode root_node = ts_document_root_node(document);
expect_the_correct_tree(root_node, document, entry.tree_string);
expect_a_consistent_tree(root_node, document);
delete input;
});
};
it_handles_edit_sequence("initial parse", [&]() {
ts_document_parse(doc);
ts_document_parse(document);
});
std::set<std::pair<size_t, size_t>> deletions;
std::set<std::pair<size_t, string>> insertions;
for (size_t i = 0; i < 80; i++) {
// TODO - fix these incremental parsing bugs.
if (language_name == "javascript" && entry.description.find("Try catch finally") != string::npos)
continue;
if (language_name == "c" && entry.description.find("Boolean operators") != string::npos)
continue;
for (size_t i = 0; i < 60; i++) {
size_t edit_position = random() % utf8_char_count(entry.input);
size_t deletion_size = random() % (utf8_char_count(entry.input) - edit_position);
string inserted_text = random_words(random() % 4 + 1);
@ -154,11 +152,11 @@ describe("Languages", [&]() {
string description = "\"" + inserted_text + "\" at " + to_string(edit_position);
it_handles_edit_sequence("repairing an insertion of " + description, [&]() {
ts_document_edit(doc, input->replace(edit_position, 0, inserted_text));
ts_document_parse(doc);
ts_document_edit(document, input->replace(edit_position, 0, inserted_text));
ts_document_parse(document);
ts_document_edit(doc, input->undo());
ts_document_parse(doc);
ts_document_edit(document, input->undo());
ts_document_parse(document);
});
}
@ -166,11 +164,11 @@ describe("Languages", [&]() {
string desription = to_string(edit_position) + "-" + to_string(edit_position + deletion_size);
it_handles_edit_sequence("repairing a deletion of " + desription, [&]() {
ts_document_edit(doc, input->replace(edit_position, deletion_size, ""));
ts_document_parse(doc);
ts_document_edit(document, input->replace(edit_position, deletion_size, ""));
ts_document_parse(document);
ts_document_edit(doc, input->undo());
ts_document_parse(doc);
ts_document_edit(document, input->undo());
ts_document_parse(document);
});
}
}

View file

@ -1,11 +1,9 @@
#include "runtime/runtime_spec_helper.h"
#include "runtime/helpers/tree_helpers.h"
#include "spec_helper.h"
#include "runtime/debugger.h"
#include "runtime/helpers/spy_debugger.h"
#include "runtime/helpers/spy_input.h"
extern "C" const TSLanguage * ts_language_json();
extern "C" const TSLanguage * ts_language_javascript();
#include "helpers/tree_helpers.h"
#include "helpers/spy_debugger.h"
#include "helpers/spy_input.h"
#include "helpers/test_languages.h"
START_TEST
@ -25,15 +23,15 @@ describe("Document", [&]() {
SpyInput *spy_input;
before_each([&]() {
ts_document_set_language(doc, ts_language_json());
spy_input = new SpyInput("{\"key\": [null, 2]}", 3);
ts_document_set_language(doc, get_test_language("json"));
ts_document_set_input_string(doc, "{\"key\": [1, 2]}");
ts_document_parse(doc);
root = ts_document_root_node(doc);
AssertThat(ts_node_string(root, doc), Equals(
"(object (string) (array (number) (number)))"));
spy_input = new SpyInput("{\"key\": [null, 2]}", 3);
"(object (pair (string) (array (number) (number))))"));
});
after_each([&]() {
@ -77,7 +75,7 @@ describe("Document", [&]() {
TSNode new_root = ts_document_root_node(doc);
AssertThat(ts_node_string(new_root, doc), Equals(
"(object (string) (array (null) (number)))"));
"(object (pair (string) (array (null) (number))))"));
AssertThat(spy_input->strings_read, Equals(vector<string>({" [null, 2", ""})));
});
@ -102,19 +100,19 @@ describe("Document", [&]() {
});
it("uses the given language for future parses", [&]() {
ts_document_set_language(doc, ts_language_json());
ts_document_set_language(doc, get_test_language("json"));
ts_document_parse(doc);
root = ts_document_root_node(doc);
AssertThat(ts_node_string(root, doc), Equals(
"(object (string) (array (number) (number)))"));
"(object (pair (string) (array (number) (number))))"));
});
it("clears out any previous tree", [&]() {
ts_document_set_language(doc, ts_language_json());
ts_document_set_language(doc, get_test_language("json"));
ts_document_parse(doc);
ts_document_set_language(doc, ts_language_javascript());
ts_document_set_language(doc, get_test_language("javascript"));
AssertThat(ts_document_root_node(doc).data, Equals<void *>(nullptr));
ts_document_parse(doc);
@ -130,7 +128,7 @@ describe("Document", [&]() {
before_each([&]() {
debugger = new SpyDebugger();
ts_document_set_language(doc, ts_language_json());
ts_document_set_language(doc, get_test_language("json"));
ts_document_set_input_string(doc, "[1, 2]");
});

View file

@ -1,8 +1,7 @@
#include "runtime/runtime_spec_helper.h"
#include "runtime/helpers/tree_helpers.h"
#include "runtime/helpers/point_helpers.h"
extern "C" TSLanguage * ts_language_json();
#include "spec_helper.h"
#include "helpers/tree_helpers.h"
#include "helpers/point_helpers.h"
#include "helpers/test_languages.h"
START_TEST
@ -35,9 +34,7 @@ describe("Node", []() {
before_each([&]() {
document = ts_document_make();
ts_document_set_language(document, ts_language_json());
ts_document_set_language(document, get_test_language("json"));
ts_document_set_input_string(document, input_string.c_str());
ts_document_parse(document);
@ -46,7 +43,7 @@ describe("Node", []() {
"(array "
"(number) "
"(false) "
"(object (string) (null)))"));
"(object (pair (string) (null))))"));
});
after_each([&]() {
@ -55,17 +52,9 @@ describe("Node", []() {
describe("named_child_count(), named_child(i)", [&]() {
it("returns the named child node at the given index", [&]() {
AssertThat(ts_node_named_child_count(array_node), Equals<size_t>(3));
TSNode child1 = ts_node_named_child(array_node, 0);
TSNode child2 = ts_node_named_child(array_node, 1);
TSNode child3 = ts_node_named_child(array_node, 2);
AssertThat(ts_node_name(array_node, document), Equals("array"));
AssertThat(ts_node_name(child1, document), Equals("number"));
AssertThat(ts_node_name(child2, document), Equals("false"));
AssertThat(ts_node_name(child3, document), Equals("object"));
AssertThat(ts_node_named_child_count(array_node), Equals<size_t>(3));
AssertThat(ts_node_start_byte(array_node), Equals(array_index));
AssertThat(ts_node_end_byte(array_node), Equals(array_end_index));
AssertThat(ts_node_start_char(array_node), Equals(array_index));
@ -73,46 +62,63 @@ describe("Node", []() {
AssertThat(ts_node_start_point(array_node), Equals<TSPoint>({ 2, 0 }));
AssertThat(ts_node_end_point(array_node), Equals<TSPoint>({ 8, 1 }));
AssertThat(ts_node_start_byte(child1), Equals(number_index));
AssertThat(ts_node_end_byte(child1), Equals(number_end_index));
AssertThat(ts_node_start_char(child1), Equals(number_index));
AssertThat(ts_node_end_char(child1), Equals(number_end_index));
AssertThat(ts_node_start_point(child1), Equals<TSPoint>({ 3, 2 }));
AssertThat(ts_node_end_point(child1), Equals<TSPoint>({ 3, 5 }));
TSNode number_node = ts_node_named_child(array_node, 0);
TSNode false_node = ts_node_named_child(array_node, 1);
TSNode object_node = ts_node_named_child(array_node, 2);
AssertThat(ts_node_start_byte(child2), Equals(false_index));
AssertThat(ts_node_end_byte(child2), Equals(false_end_index));
AssertThat(ts_node_start_point(child2), Equals<TSPoint>({ 4, 2 }));
AssertThat(ts_node_end_point(child2), Equals<TSPoint>({ 4, 7 }));
AssertThat(ts_node_name(number_node, document), Equals("number"));
AssertThat(ts_node_name(false_node, document), Equals("false"));
AssertThat(ts_node_name(object_node, document), Equals("object"));
AssertThat(ts_node_start_byte(child3), Equals(object_index));
AssertThat(ts_node_end_byte(child3), Equals(object_end_index));
AssertThat(ts_node_start_point(child3), Equals<TSPoint>({ 5, 2 }));
AssertThat(ts_node_end_point(child3), Equals<TSPoint>({ 7, 3 }));
AssertThat(ts_node_start_byte(number_node), Equals(number_index));
AssertThat(ts_node_end_byte(number_node), Equals(number_end_index));
AssertThat(ts_node_start_char(number_node), Equals(number_index));
AssertThat(ts_node_end_char(number_node), Equals(number_end_index));
AssertThat(ts_node_start_point(number_node), Equals<TSPoint>({ 3, 2 }));
AssertThat(ts_node_end_point(number_node), Equals<TSPoint>({ 3, 5 }));
AssertThat(ts_node_named_child_count(child3), Equals<size_t>(2));
AssertThat(ts_node_start_byte(false_node), Equals(false_index));
AssertThat(ts_node_end_byte(false_node), Equals(false_end_index));
AssertThat(ts_node_start_point(false_node), Equals<TSPoint>({ 4, 2 }));
AssertThat(ts_node_end_point(false_node), Equals<TSPoint>({ 4, 7 }));
TSNode grandchild1 = ts_node_named_child(child3, 0);
TSNode grandchild2 = ts_node_named_child(child3, 1);
AssertThat(ts_node_start_byte(object_node), Equals(object_index));
AssertThat(ts_node_end_byte(object_node), Equals(object_end_index));
AssertThat(ts_node_start_point(object_node), Equals<TSPoint>({ 5, 2 }));
AssertThat(ts_node_end_point(object_node), Equals<TSPoint>({ 7, 3 }));
AssertThat(ts_node_named_child_count(object_node), Equals<size_t>(1));
AssertThat(ts_node_name(grandchild1, document), Equals("string"));
AssertThat(ts_node_name(grandchild2, document), Equals("null"));
TSNode pair_node = ts_node_named_child(object_node, 0);
AssertThat(ts_node_start_byte(grandchild1), Equals(string_index));
AssertThat(ts_node_end_byte(grandchild1), Equals(string_end_index));
AssertThat(ts_node_start_point(grandchild1), Equals<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(grandchild1), Equals<TSPoint>({ 6, 7 }));
AssertThat(ts_node_name(pair_node, document), Equals("pair"));
AssertThat(ts_node_start_byte(pair_node), Equals(string_index));
AssertThat(ts_node_end_byte(pair_node), Equals(null_end_index));
AssertThat(ts_node_start_point(pair_node), Equals<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(pair_node), Equals<TSPoint>({ 6, 13 }));
AssertThat(ts_node_named_child_count(pair_node), Equals<size_t>(2));
AssertThat(ts_node_start_byte(grandchild2), Equals(null_index));
AssertThat(ts_node_end_byte(grandchild2), Equals(null_end_index));
AssertThat(ts_node_start_point(grandchild2), Equals<TSPoint>({ 6, 9 }));
AssertThat(ts_node_end_point(grandchild2), Equals<TSPoint>({ 6, 13 }));
TSNode string_node = ts_node_named_child(pair_node, 0);
TSNode null_node = ts_node_named_child(pair_node, 1);
AssertThat(ts_node_parent(grandchild1), Equals(child3));
AssertThat(ts_node_parent(grandchild2), Equals(child3));
AssertThat(ts_node_parent(child1), Equals(array_node));
AssertThat(ts_node_parent(child2), Equals(array_node));
AssertThat(ts_node_parent(child3), Equals(array_node));
AssertThat(ts_node_name(string_node, document), Equals("string"));
AssertThat(ts_node_name(null_node, document), Equals("null"));
AssertThat(ts_node_start_byte(string_node), Equals(string_index));
AssertThat(ts_node_end_byte(string_node), Equals(string_end_index));
AssertThat(ts_node_start_point(string_node), Equals<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(string_node), Equals<TSPoint>({ 6, 7 }));
AssertThat(ts_node_start_byte(null_node), Equals(null_index));
AssertThat(ts_node_end_byte(null_node), Equals(null_end_index));
AssertThat(ts_node_start_point(null_node), Equals<TSPoint>({ 6, 9 }));
AssertThat(ts_node_end_point(null_node), Equals<TSPoint>({ 6, 13 }));
AssertThat(ts_node_parent(string_node), Equals(pair_node));
AssertThat(ts_node_parent(null_node), Equals(pair_node));
AssertThat(ts_node_parent(pair_node), Equals(object_node));
AssertThat(ts_node_parent(number_node), Equals(array_node));
AssertThat(ts_node_parent(false_node), Equals(array_node));
AssertThat(ts_node_parent(object_node), Equals(array_node));
AssertThat(ts_node_parent(array_node).data, Equals<void *>(nullptr));
});
});
@ -166,25 +172,30 @@ describe("Node", []() {
AssertThat(ts_node_start_point(child7), Equals<TSPoint>({ 8, 0 }));
AssertThat(ts_node_end_point(child7), Equals<TSPoint>({ 8, 1 }));
AssertThat(ts_node_child_count(child6), Equals<size_t>(5))
AssertThat(ts_node_child_count(child6), Equals<size_t>(3))
TSNode grandchild1 = ts_node_child(child6, 0);
TSNode grandchild2 = ts_node_child(child6, 1);
TSNode grandchild3 = ts_node_child(child6, 2);
TSNode grandchild4 = ts_node_child(child6, 3);
TSNode grandchild5 = ts_node_child(child6, 4);
TSNode left_brace = ts_node_child(child6, 0);
TSNode pair = ts_node_child(child6, 1);
TSNode right_brace = ts_node_child(child6, 2);
TSNode grandchild2 = ts_node_child(pair, 0);
TSNode grandchild3 = ts_node_child(pair, 1);
TSNode grandchild4 = ts_node_child(pair, 2);
AssertThat(ts_node_name(left_brace, document), Equals("{"));
AssertThat(ts_node_name(pair, document), Equals("pair"));
AssertThat(ts_node_name(right_brace, document), Equals("}"));
AssertThat(ts_node_name(grandchild1, document), Equals("{"));
AssertThat(ts_node_name(grandchild2, document), Equals("string"));
AssertThat(ts_node_name(grandchild3, document), Equals(":"));
AssertThat(ts_node_name(grandchild4, document), Equals("null"));
AssertThat(ts_node_name(grandchild5, document), Equals("}"));
AssertThat(ts_node_parent(grandchild1), Equals(child6));
AssertThat(ts_node_parent(grandchild2), Equals(child6));
AssertThat(ts_node_parent(grandchild3), Equals(child6));
AssertThat(ts_node_parent(grandchild4), Equals(child6));
AssertThat(ts_node_parent(grandchild5), Equals(child6));
AssertThat(ts_node_parent(grandchild2), Equals(pair));
AssertThat(ts_node_parent(grandchild3), Equals(pair));
AssertThat(ts_node_parent(grandchild4), Equals(pair));
AssertThat(ts_node_parent(left_brace), Equals(child6));
AssertThat(ts_node_parent(pair), Equals(child6));
AssertThat(ts_node_parent(right_brace), Equals(child6));
AssertThat(ts_node_parent(child1), Equals(array_node));
AssertThat(ts_node_parent(child2), Equals(array_node));
AssertThat(ts_node_parent(child3), Equals(array_node));
@ -205,10 +216,11 @@ describe("Node", []() {
TSNode array_comma_node2 = ts_node_child(array_node, 4);
TSNode object_node = ts_node_child(array_node, 5);
TSNode brace_node1 = ts_node_child(object_node, 0);
TSNode string_node = ts_node_child(object_node, 1);
TSNode colon_node = ts_node_child(object_node, 2);
TSNode null_node = ts_node_child(object_node, 3);
TSNode brace_node2 = ts_node_child(object_node, 4);
TSNode pair_node = ts_node_child(object_node, 1);
TSNode string_node = ts_node_child(pair_node, 0);
TSNode colon_node = ts_node_child(pair_node, 1);
TSNode null_node = ts_node_child(pair_node, 2);
TSNode brace_node2 = ts_node_child(object_node, 2);
TSNode bracket_node2 = ts_node_child(array_node, 6);
AssertThat(ts_node_next_sibling(bracket_node1), Equals(number_node));
@ -227,24 +239,26 @@ describe("Node", []() {
AssertThat(ts_node_prev_sibling(object_node), Equals(array_comma_node2));
AssertThat(ts_node_prev_sibling(bracket_node2), Equals(object_node));
AssertThat(ts_node_next_sibling(brace_node1), Equals(string_node));
AssertThat(ts_node_next_sibling(string_node), Equals(colon_node));
AssertThat(ts_node_next_sibling(colon_node), Equals(null_node));
AssertThat(ts_node_next_sibling(null_node), Equals(brace_node2));
AssertThat(ts_node_next_sibling(brace_node1), Equals(pair_node));
AssertThat(ts_node_next_sibling(pair_node), Equals(brace_node2));
AssertThat(ts_node_next_sibling(brace_node2).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_sibling(brace_node1).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_sibling(string_node), Equals(brace_node1));
AssertThat(ts_node_prev_sibling(pair_node), Equals(brace_node1));
AssertThat(ts_node_prev_sibling(brace_node2), Equals(pair_node));
AssertThat(ts_node_next_sibling(string_node), Equals(colon_node));
AssertThat(ts_node_next_sibling(colon_node), Equals(null_node));
AssertThat(ts_node_next_sibling(null_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_sibling(string_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_sibling(colon_node), Equals(string_node));
AssertThat(ts_node_prev_sibling(null_node), Equals(colon_node));
AssertThat(ts_node_prev_sibling(brace_node2), Equals(null_node));
});
it("returns null when the node has no parent", [&]() {
AssertThat(ts_node_next_named_sibling(array_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_named_sibling(array_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_next_named_sibling(array_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_named_sibling(array_node).data, Equals<void *>(nullptr));
});
});
@ -253,8 +267,9 @@ describe("Node", []() {
TSNode number_node = ts_node_named_child(array_node, 0);
TSNode false_node = ts_node_named_child(array_node, 1);
TSNode object_node = ts_node_named_child(array_node, 2);
TSNode string_node = ts_node_named_child(object_node, 0);
TSNode null_node = ts_node_named_child(object_node, 1);
TSNode pair_node = ts_node_named_child(object_node, 0);
TSNode string_node = ts_node_named_child(pair_node, 0);
TSNode null_node = ts_node_named_child(pair_node, 1);
AssertThat(ts_node_next_named_sibling(number_node), Equals(false_node));
AssertThat(ts_node_next_named_sibling(false_node), Equals(object_node));
@ -267,8 +282,6 @@ describe("Node", []() {
it("returns null when the node has no parent", [&]() {
AssertThat(ts_node_next_named_sibling(array_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_named_sibling(array_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_next_named_sibling(array_node).data, Equals<void *>(nullptr));
AssertThat(ts_node_prev_named_sibling(array_node).data, Equals<void *>(nullptr));
});
});
@ -311,12 +324,12 @@ describe("Node", []() {
describe("when there is no leaf node that spans the given range", [&]() {
it("returns the smallest node that does span the range", [&]() {
TSNode node = ts_node_named_descendant_for_range(array_node, string_index, string_index + 3);
AssertThat(ts_node_name(node, document), Equals("object"));
AssertThat(ts_node_start_byte(node), Equals(object_index));
AssertThat(ts_node_end_byte(node), Equals(object_end_index));
AssertThat(ts_node_start_point(node), Equals<TSPoint>({ 5, 2 }));
AssertThat(ts_node_end_point(node), Equals<TSPoint>({ 7, 3 }));
TSNode pair_node = ts_node_named_descendant_for_range(array_node, string_index, string_index + 3);
AssertThat(ts_node_name(pair_node, document), Equals("pair"));
AssertThat(ts_node_start_byte(pair_node), Equals(string_index));
AssertThat(ts_node_end_byte(pair_node), Equals(null_end_index));
AssertThat(ts_node_start_point(pair_node), Equals<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(pair_node), Equals<TSPoint>({ 6, 13 }));
});
it("does not return invisible nodes (repeats)", [&]() {
@ -340,11 +353,11 @@ describe("Node", []() {
AssertThat(ts_node_end_point(node1), Equals<TSPoint>({ 6, 8 }));
TSNode node2 = ts_node_descendant_for_range(array_node, string_index + 2, string_index + 4);
AssertThat(ts_node_name(node2, document), Equals("object"));
AssertThat(ts_node_start_byte(node2), Equals(object_index));
AssertThat(ts_node_end_byte(node2), Equals(object_end_index));
AssertThat(ts_node_start_point(node2), Equals<TSPoint>({ 5, 2 }));
AssertThat(ts_node_end_point(node2), Equals<TSPoint>({ 7, 3 }));
AssertThat(ts_node_name(node2, document), Equals("pair"));
AssertThat(ts_node_start_byte(node2), Equals(string_index));
AssertThat(ts_node_end_byte(node2), Equals(null_end_index));
AssertThat(ts_node_start_point(node2), Equals<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(node2), Equals<TSPoint>({ 6, 13 }));
});
});
});

View file

@ -1,10 +1,7 @@
#include "runtime/runtime_spec_helper.h"
#include "runtime/helpers/spy_input.h"
#include "runtime/helpers/log_debugger.h"
extern "C" const TSLanguage * ts_language_json();
extern "C" const TSLanguage * ts_language_javascript();
extern "C" const TSLanguage * ts_language_arithmetic();
#include "spec_helper.h"
#include "helpers/spy_input.h"
#include "helpers/test_languages.h"
#include "helpers/log_debugger.h"
START_TEST
@ -69,7 +66,7 @@ describe("Parser", [&]() {
describe("handling errors", [&]() {
before_each([&]() {
ts_document_set_language(doc, ts_language_json());
ts_document_set_language(doc, get_test_language("json"));
});
describe("when the error occurs at the beginning of a token", [&]() {
@ -155,7 +152,7 @@ describe("Parser", [&]() {
// In the javascript example grammar, ASI works by using newlines as
// terminators in statements, but also as extra tokens.
before_each([&]() {
ts_document_set_language(doc, ts_language_javascript());
ts_document_set_language(doc, get_test_language("javascript"));
});
describe("when the token appears as part of a grammar rule", [&]() {
@ -163,7 +160,7 @@ describe("Parser", [&]() {
set_text("fn()\n");
AssertThat(ts_node_string(root, doc), Equals(
"(program (expression_statement (function_call (identifier) (arguments))))"));
"(program (expression_statement (function_call (identifier))))"));
});
});
@ -175,8 +172,7 @@ describe("Parser", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (expression_statement (function_call "
"(member_access (function_call (identifier) (arguments)) (identifier)) "
"(arguments))))"));
"(member_access (function_call (identifier)) (identifier)))))"));
});
});
@ -190,75 +186,66 @@ describe("Parser", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (expression_statement (function_call "
"(member_access (function_call (identifier) (arguments)) "
"(member_access (function_call (identifier)) "
"(comment) "
"(identifier)) "
"(arguments))))"));
"(identifier)))))"));
});
});
});
describe("editing", [&]() {
before_each([&]() {
ts_document_set_language(doc, ts_language_arithmetic());
ts_document_set_language(doc, get_test_language("javascript"));
});
describe("inserting text", [&]() {
describe("creating new tokens near the end of the input", [&]() {
before_each([&]() {
set_text("x ^ (100 + abc)");
it("updates the parse tree and re-reads only the changed portion of the text", [&]() {
set_text("x * (100 + abc);");
AssertThat(ts_node_string(root, doc), Equals(
"(program (exponent "
"(variable) "
"(group (sum (number) (variable)))))"));
"(program (expression_statement (math_op "
"(identifier) "
"(math_op (number) (identifier)))))"));
insert_text(strlen("x ^ (100 + abc"), " * 5");
});
insert_text(strlen("x ^ (100 + abc"), ".d");
it("updates the parse tree", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (exponent "
"(variable) "
"(group (sum (number) (product (variable) (number))))))"));
});
"(program (expression_statement (math_op "
"(identifier) "
"(math_op (number) (member_access (identifier) (identifier))))))"));
it("re-reads only the changed portion of the input", [&]() {
AssertThat(input->strings_read, Equals(vector<string>({ " abc * 5)", "" })));
AssertThat(input->strings_read, Equals(vector<string>({ " abc.d);", "" })));
});
});
describe("creating new tokens near the beginning of the input", [&]() {
before_each([&]() {
it("updates the parse tree and re-reads only the changed portion of the input", [&]() {
chunk_size = 2;
set_text("123 * 456 ^ (10 + x)");
set_text("123 + 456 * (10 + x);");
AssertThat(ts_node_string(root, doc), Equals(
"(program (product "
"(program (expression_statement (math_op "
"(number) "
"(exponent (number) (group (sum (number) (variable))))))"));
"(math_op (number) (math_op (number) (identifier))))))"));
insert_text(strlen("123"), " + 5");
});
insert_text(strlen("123"), " || 5");
it("updates the parse tree", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (sum "
"(program (expression_statement (bool_op "
"(number) "
"(product "
"(math_op "
"(number) "
"(exponent (number) (group (sum (number) (variable)))))))"));
});
"(math_op (number) (math_op (number) (identifier)))))))"));
it("re-reads only the changed portion of the input", [&]() {
AssertThat(input->strings_read, Equals(vector<string>({ "123 + 5 ", "" })));
AssertThat(input->strings_read, Equals(vector<string>({ "123 || 5 +", "" })));
});
});
describe("introducing an error", [&]() {
it("gives the error the right size", [&]() {
ts_document_set_language(doc, ts_language_javascript());
ts_document_set_language(doc, get_test_language("javascript"));
set_text("var x = y;");
@ -280,107 +267,103 @@ describe("Parser", [&]() {
});
describe("into the middle of an existing token", [&]() {
before_each([&]() {
set_text("abc * 123");
it("updates the parse tree", [&]() {
set_text("abc * 123;");
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (variable) (number)))"));
"(program (expression_statement (math_op (identifier) (number))))"));
insert_text(strlen("ab"), "XYZ");
});
it("updates the parse tree", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (variable) (number)))"));
"(program (expression_statement (math_op (identifier) (number))))"));
TSNode node = ts_node_named_descendant_for_range(root, 1, 1);
AssertThat(ts_node_name(node, doc), Equals("variable"));
AssertThat(ts_node_name(node, doc), Equals("identifier"));
AssertThat(ts_node_end_byte(node), Equals(strlen("abXYZc")));
});
});
describe("at the end of an existing token", [&]() {
before_each([&]() {
set_text("abc * 123");
it("updates the parse tree", [&]() {
set_text("abc * 123;");
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (variable) (number)))"));
"(program (expression_statement (math_op (identifier) (number))))"));
insert_text(strlen("abc"), "XYZ");
});
it("updates the parse tree", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (variable) (number)))"));
"(program (expression_statement (math_op (identifier) (number))))"));
TSNode node = ts_node_named_descendant_for_range(root, 1, 1);
AssertThat(ts_node_name(node, doc), Equals("variable"));
AssertThat(ts_node_name(node, doc), Equals("identifier"));
AssertThat(ts_node_end_byte(node), Equals(strlen("abcXYZ")));
});
});
describe("with non-ascii characters", [&]() {
before_each([&]() {
// αβδ + 1
set_text("\u03b1\u03b2\u03b4 + 1");
AssertThat(ts_node_string(root, doc), Equals(
"(program (sum (variable) (number)))"));
// αβδ + ψ1
insert_text(strlen("abd + "), "\u03c8");
});
it("inserts the text according to the UTF8 character index", [&]() {
// 'αβδ' + '1'
set_text("'\u03b1\u03b2\u03b4' + '1';");
AssertThat(ts_node_string(root, doc), Equals(
"(program (sum (variable) (variable)))"));
"(program (expression_statement (math_op (string) (string))))"));
// 'αβδ' + 'ψ1'
insert_text(strlen("'abd' + '"), "\u03c8");
AssertThat(ts_node_string(root, doc), Equals(
"(program (expression_statement (math_op (string) (string))))"));
});
});
describe("into a node containing a extra token", [&]() {
before_each([&]() {
it("updates the parse tree", [&]() {
set_text("123 *\n"
"# a-comment\n"
"abc");
"// a-comment\n"
"abc;");
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (number) (comment) (variable)))"));
"(program (expression_statement (math_op "
"(number) "
"(comment) "
"(identifier))))"));
insert_text(
strlen("123 *\n"
"# a-comment\n"
"// a-comment\n"
"abc"),
"XYZ");
});
it("updates the parse tree", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (number) (comment) (variable)))"));
"(program (expression_statement (math_op "
"(number) "
"(comment) "
"(identifier))))"));
});
});
});
describe("deleting text", [&]() {
describe("when a critical token is removed", [&]() {
before_each([&]() {
set_text("123 * 456");
it("updates the parse tree, creating an error", [&]() {
set_text("123 * 456;");
AssertThat(ts_node_string(root, doc), Equals(
"(program (product (number) (number)))"));
"(program (expression_statement (math_op (number) (number))))"));
delete_text(strlen("123 "), 2);
});
it("updates the parse tree, creating an error", [&]() {
AssertThat(ts_node_string(root, doc), Equals(
"(ERROR (number) (UNEXPECTED '4') (number))"));
"(program (expression_statement (ERROR (number) (UNEXPECTED '4') (number))))"));
});
});
});
describe("replacing text", [&]() {
it("does not try to re-use nodes that are within the edited region", [&]() {
ts_document_set_language(doc, ts_language_javascript());
ts_document_set_language(doc, get_test_language("javascript"));
set_text("{ x: (b.c) };");
@ -397,7 +380,7 @@ describe("Parser", [&]() {
});
it("updates the document's parse count", [&]() {
ts_document_set_language(doc, ts_language_javascript());
ts_document_set_language(doc, get_test_language("javascript"));
AssertThat(ts_document_parse_count(doc), Equals<size_t>(0));
set_text("{ x: (b.c) };");
@ -410,32 +393,32 @@ describe("Parser", [&]() {
describe("lexing", [&]() {
before_each([&]() {
ts_document_set_language(doc, ts_language_arithmetic());
ts_document_set_language(doc, get_test_language("javascript"));
});
describe("handling tokens containing wildcard patterns (e.g. comments)", [&]() {
it("terminates them at the end of the document", [&]() {
set_text("x # this is a comment");
set_text("x; // this is a comment");
AssertThat(ts_node_string(root, doc), Equals(
"(program (variable) (comment))"));
"(program (expression_statement (identifier)) (comment))"));
TSNode comment = ts_node_named_child(root, 1);
AssertThat(ts_node_start_byte(comment), Equals(strlen("x ")));
AssertThat(ts_node_end_byte(comment), Equals(strlen("x # this is a comment")));
AssertThat(ts_node_start_byte(comment), Equals(strlen("x; ")));
AssertThat(ts_node_end_byte(comment), Equals(strlen("x; // this is a comment")));
});
});
it("recognizes UTF8 characters as single characters", [&]() {
// x # ΩΩΩ — ΔΔ
set_text("x # \u03A9\u03A9\u03A9 \u2014 \u0394\u0394");
// 'ΩΩΩ — ΔΔ';
set_text("'\u03A9\u03A9\u03A9 \u2014 \u0394\u0394';");
AssertThat(ts_node_string(root, doc), Equals(
"(program (variable) (comment))"));
"(program (expression_statement (string)))"));
AssertThat(ts_node_end_char(root), Equals(strlen("x # OOO - DD")));
AssertThat(ts_node_end_byte(root), Equals(strlen("x # \u03A9\u03A9\u03A9 \u2014 \u0394\u0394")));
AssertThat(ts_node_end_char(root), Equals(strlen("'OOO - DD';")));
AssertThat(ts_node_end_byte(root), Equals(strlen("'\u03A9\u03A9\u03A9 \u2014 \u0394\u0394';")));
});
});
});

View file

@ -1,5 +1,5 @@
#include "runtime/runtime_spec_helper.h"
#include "runtime/helpers/tree_helpers.h"
#include "spec_helper.h"
#include "helpers/tree_helpers.h"
#include "runtime/stack.h"
#include "runtime/tree.h"
#include "runtime/length.h"

View file

@ -1,5 +1,5 @@
#include "runtime/runtime_spec_helper.h"
#include "runtime/helpers/tree_helpers.h"
#include "spec_helper.h"
#include "helpers/tree_helpers.h"
#include "runtime/tree.h"
#include "runtime/length.h"

View file

@ -1,13 +1,17 @@
#ifndef __tree_sitter_runtime_spec_helper_h__
#define __tree_sitter_runtime_spec_helper_h__
#ifndef SPEC_HELPER_
#define SPEC_HELPER_
#include "bandit/bandit.h"
#include "tree_sitter/compiler.h"
#include "tree_sitter/runtime.h"
namespace tree_sitter {}
using namespace std;
using namespace bandit;
using namespace tree_sitter;
#define START_TEST go_bandit([]() {
#define END_TEST });
#endif
#endif // SPEC_HELPER_

View file

@ -1,4 +1,4 @@
#include "runtime/runtime_spec_helper.h"
#include "spec_helper.h"
int main(int argc, char *argv[]) {
int seed;

View file

@ -223,7 +223,7 @@ ParseGrammarResult parse_grammar(const string &input) {
Grammar grammar;
json_value name_json, rules_json, extras_json, conflicts_json;
json_settings settings = { 0, 0, 0, 0, 0, 0 };
json_settings settings = { 0, json_enable_comments, 0, 0, 0, 0 };
char parse_error[json_error_max];
json_value *grammar_json =
json_parse_ex(&settings, input.c_str(), input.size(), parse_error);

115
tests.gyp
View file

@ -1,92 +1,63 @@
{
'targets': [
{
'target_name': 'compiler_specs',
'target_name': 'tests',
'type': 'executable',
'dependencies': [
'project.gyp:runtime',
'project.gyp:compiler'
],
'include_dirs': [
'src',
'spec',
'externals/bandit',
],
'sources': [
'<!@(find spec/compiler -name "*.cc")',
'<!@(find spec/fixtures/grammars -name "*.cc")',
],
},
{
'target_name': 'runtime_specs',
'type': 'executable',
'dependencies': [
'project.gyp:runtime'
],
'include_dirs': [
'src',
'examples',
'spec',
'externals/bandit',
'externals/utf8proc',
],
'sources': [
'spec/specs.cc',
'<!@(find spec/compiler -name "*.cc")',
'<!@(find spec/runtime -name "*.cc")',
'<!@(find spec/fixtures/parsers -name "*.c")',
'<!@(find spec/integration -name "*.cc")',
'<!@(find spec/helpers -name "*.cc")',
],
'variables': {
'USE_BOOST_REGEX%': 'false',
},
'conditions': [
['USE_BOOST_REGEX != "false"', {
'defines': ['USE_BOOST_REGEX'],
'libraries': ['-lboost_regex'],
}]
],
},
],
'target_defaults': {
'default_configuration': 'Debug',
'configurations': {'Debug': {}, 'Release': {}},
'cflags': [
'-g',
'-O0',
'-Wall',
'-Wextra',
'-Wno-unused-parameter',
'-Wno-unknown-pragmas',
],
'cflags_c': [
'-std=c99',
],
'cflags_cc': [
'-std=c++0x',
],
'ldflags': [
'-g',
],
'variables': {
'USE_LIBPROFILER%': 'true',
},
'conditions': [
['USE_LIBPROFILER != "false"', {
'libraries': ['-lprofiler'],
}]
],
'xcode_settings': {
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
'OTHER_LDFLAGS': ['-g'],
'GCC_OPTIMIZATION_LEVEL': '0',
'ALWAYS_SEARCH_USER_PATHS': 'NO',
'WARNING_CFLAGS': [
'default_configuration': 'Debug',
'configurations': {'Debug': {}, 'Release': {}},
'cflags': [
'-g',
'-O0',
'-Wall',
'-Wextra',
'-Wno-unused-parameter'
'-Wno-unused-parameter',
'-Wno-unknown-pragmas',
],
},
}
'cflags_c': [
'-std=c99',
],
'cflags_cc': [
'-std=c++0x',
],
'ldflags': [
'-g',
],
'variables': {
'USE_LIBPROFILER%': 'true',
},
'conditions': [
['USE_LIBPROFILER != "false"', {
'libraries': ['-lprofiler'],
}]
],
'xcode_settings': {
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
'OTHER_LDFLAGS': ['-g'],
'GCC_OPTIMIZATION_LEVEL': '0',
'ALWAYS_SEARCH_USER_PATHS': 'NO',
'WARNING_CFLAGS': [
'-Wall',
'-Wextra',
'-Wno-unused-parameter'
],
},
}
]
}