Start work on javascript grammar
This commit is contained in:
parent
fd226a6bfe
commit
671f1a1ddc
11 changed files with 1695 additions and 10 deletions
|
|
@ -3,7 +3,7 @@
|
|||
namespace tree_sitter {
|
||||
namespace examples {
|
||||
using namespace tree_sitter::rules;
|
||||
|
||||
|
||||
Grammar arithmetic() {
|
||||
return Grammar("expression", {
|
||||
{ "expression", choice({
|
||||
|
|
|
|||
72
examples/grammars/javascript.cc
Normal file
72
examples/grammars/javascript.cc
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include "tree_sitter/compiler.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace examples {
|
||||
using namespace tree_sitter::rules;
|
||||
|
||||
static rule_ptr comma_sep(const rule_ptr &element) {
|
||||
return choice({
|
||||
seq({
|
||||
element,
|
||||
repeat(seq({ str(","), element })),
|
||||
}),
|
||||
blank(),
|
||||
});
|
||||
}
|
||||
|
||||
Grammar javascript() {
|
||||
return Grammar("program", {
|
||||
{ "program", repeat(sym("statement")) },
|
||||
{ "terminator", choice({ str(";"), str("\n") }) },
|
||||
{ "statement", choice({
|
||||
sym("if"),
|
||||
seq({ sym("expression"), _sym("terminator") }),
|
||||
seq({ sym("assignment"), _sym("terminator") }) }) },
|
||||
{ "if", seq({
|
||||
str("if"),
|
||||
str("("),
|
||||
sym("expression"),
|
||||
str(")"),
|
||||
sym("block")
|
||||
}) },
|
||||
{ "block", seq({
|
||||
str("{"),
|
||||
repeat(sym("statement")),
|
||||
str("}")
|
||||
}) },
|
||||
{ "assignment", seq({
|
||||
str("var"),
|
||||
sym("identifier"),
|
||||
str("="),
|
||||
sym("expression") })},
|
||||
{ "expression", choice({
|
||||
sym("literal") }) },
|
||||
{ "literal", choice({
|
||||
sym("object"),
|
||||
sym("array"),
|
||||
sym("string"),
|
||||
sym("number"),
|
||||
sym("true"),
|
||||
sym("false"),
|
||||
sym("null"), }) },
|
||||
{ "object", seq({
|
||||
str("{"),
|
||||
comma_sep(err(seq({
|
||||
sym("string"),
|
||||
str(":"),
|
||||
sym("expression") }))),
|
||||
str("}"), }) },
|
||||
{ "array", seq({
|
||||
str("["),
|
||||
comma_sep(err(sym("expression"))),
|
||||
str("]") }) },
|
||||
{ "string", pattern("\"([^\"]|\\\\\")+\"") },
|
||||
{ "identifier", pattern("[\\w_$]+") },
|
||||
{ "number", pattern("\\d+(.\\d+)?") },
|
||||
{ "null", str("null") },
|
||||
{ "true", str("true") },
|
||||
{ "false", str("false") },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
namespace tree_sitter {
|
||||
namespace examples {
|
||||
using namespace tree_sitter::rules;
|
||||
|
||||
|
||||
static rule_ptr comma_sep(const rule_ptr &rule) {
|
||||
return choice({
|
||||
seq({
|
||||
|
|
@ -13,13 +13,13 @@ namespace tree_sitter {
|
|||
blank(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Grammar json() {
|
||||
return Grammar("value", {
|
||||
{ "value", choice({
|
||||
sym("object"),
|
||||
sym("array"),
|
||||
sym("string"),
|
||||
sym("string"),
|
||||
sym("number"),
|
||||
sym("true"),
|
||||
sym("false"),
|
||||
|
|
|
|||
1580
examples/parsers/javascript.c
Normal file
1580
examples/parsers/javascript.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
find src spec include -type f | xargs perl -pi -e 's/ +$//'
|
||||
find src spec include examples/grammars -type f | xargs perl -pi -e 's/ +$//'
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ static string src_dir() {
|
|||
namespace tree_sitter {
|
||||
namespace examples {
|
||||
Grammar arithmetic();
|
||||
Grammar javascript();
|
||||
Grammar json();
|
||||
}
|
||||
}
|
||||
|
|
@ -24,9 +25,10 @@ describe("compiling the example grammars", []() {
|
|||
ofstream(example_parser_dir + language + ".c") << compile(grammar, language);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
compile_grammar(examples::arithmetic(), "arithmetic");
|
||||
compile_grammar(examples::json(), "json");
|
||||
compile_grammar(examples::javascript(), "javascript");
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "runtime_spec_helper.h"
|
||||
#include "helpers/read_test_entries.h"
|
||||
|
||||
extern "C" ts_parser ts_parser_javascript();
|
||||
extern "C" ts_parser ts_parser_json();
|
||||
extern "C" ts_parser ts_parser_arithmetic();
|
||||
|
||||
|
|
@ -41,6 +42,14 @@ describe("Languages", [&]() {
|
|||
|
||||
run_tests_for_language("arithmetic");
|
||||
});
|
||||
|
||||
describe("javascript", [&]() {
|
||||
before_each([&]() {
|
||||
ts_document_set_parser(doc, ts_parser_javascript());
|
||||
});
|
||||
|
||||
run_tests_for_language("javascript");
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
20
spec/runtime/languages/javascript/main.txt
Normal file
20
spec/runtime/languages/javascript/main.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
==========================================
|
||||
parses multiple statements
|
||||
==========================================
|
||||
var x = {};
|
||||
{};
|
||||
---
|
||||
(program
|
||||
(statement (assignment (identifier) (expression (literal (object)))))
|
||||
(statement (expression (literal (object)))))
|
||||
|
||||
==========================================
|
||||
parses if statements
|
||||
==========================================
|
||||
if (1) { var x = 2; }
|
||||
---
|
||||
(program
|
||||
(statement (if
|
||||
(expression (literal (number)))
|
||||
(block (statement (assignment (identifier) (expression (literal (number)))))))))
|
||||
|
||||
|
|
@ -75,6 +75,8 @@ namespace tree_sitter {
|
|||
return "\\0";
|
||||
case '"':
|
||||
return "\\\"";
|
||||
case '\n':
|
||||
return "\\n";
|
||||
case '\\':
|
||||
return "\\\\";
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ size_t ts_stack_right_position(const ts_stack *stack) {
|
|||
ts_tree * ts_stack_reduce(ts_stack *stack, ts_symbol symbol, int immediate_child_count, const int *collapse_flags) {
|
||||
size_t new_stack_size = stack->size - immediate_child_count;
|
||||
size_t size = 0, offset = 0;
|
||||
|
||||
|
||||
int child_count = 0;
|
||||
for (int i = 0; i < immediate_child_count; i++) {
|
||||
ts_tree *child = stack->entries[new_stack_size + i].node;
|
||||
|
|
@ -84,7 +84,7 @@ ts_tree * ts_stack_reduce(ts_stack *stack, ts_symbol symbol, int immediate_child
|
|||
size_t child_index = 0;
|
||||
ts_tree **children = malloc((child_count + immediate_child_count) * sizeof(ts_tree *));
|
||||
ts_tree **immediate_children = children + child_count;
|
||||
|
||||
|
||||
for (int i = 0; i < immediate_child_count; i++) {
|
||||
ts_tree *child = stack->entries[new_stack_size + i].node;
|
||||
immediate_children[i] = child;
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ int ts_tree_equals(const ts_tree *node1, const ts_tree *node2) {
|
|||
size_t count1, count2;
|
||||
ts_tree **children1 = ts_tree_children(node1, &count1);
|
||||
ts_tree **children2 = ts_tree_children(node2, &count2);
|
||||
if (count1 != count2) return 0;
|
||||
if (count1 != count2) return 0;
|
||||
for (size_t i = 0; i < count1; i++)
|
||||
if (!ts_tree_equals(children1[i], children2[i])) return 0;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ static size_t tree_write_to_string(const ts_tree *tree, const char **symbol_name
|
|||
cursor += tree_write_to_string(children[i], symbol_names, *destination, limit);
|
||||
}
|
||||
cursor += snprintf(*destination, limit, ")");
|
||||
|
||||
|
||||
return cursor - string;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue