Skip to content

Commit eb73135

Browse files
committed
Initial commit
0 parents  commit eb73135

17 files changed

+3568
-0
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/src/** linguist-vendored

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
build
3+
*.log

.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
grammar_test
2+
build
3+
script

.travis.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: node_js
2+
sudo: false
3+
node_js:
4+
- "node"
5+
compiler: clang-3.6
6+
env:
7+
- CXX=clang-3.6
8+
addons:
9+
apt:
10+
sources:
11+
- llvm-toolchain-precise-3.6
12+
- ubuntu-toolchain-r-test
13+
packages:
14+
- clang-3.6

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Max Brunsfeld
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
tree-sitter-python
2+
================
3+
4+
[![Build Status](https://travis-ci.org/tree-sitter/tree-sitter-python.svg?branch=master)](https://travis-ci.org/tree-sitter/tree-sitter-python)
5+
6+
Python grammar for [tree-sitter][].
7+
8+
[tree-sitter]: https://github.com/tree-sitter/tree-sitter
9+
10+
#### References
11+
12+
* [Python 2 Grammar](https://docs.python.org/2/reference/grammar.html)
13+
* [Python 3 Grammar](https://docs.python.org/3/reference/grammar.html)

binding.gyp

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"targets": [
3+
{
4+
"target_name": "ts_language_python_binding",
5+
"include_dirs": [
6+
"<!(node -e \"require('nan')\")",
7+
"src"
8+
],
9+
"sources": [
10+
"src/parser.c",
11+
"src/scanner.cc",
12+
"src/binding.cc"
13+
],
14+
"cflags_c": [
15+
"-std=c99",
16+
]
17+
}
18+
]
19+
}

grammar.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
module.exports = grammar({
2+
name: 'python',
3+
4+
extras: $ => [
5+
$.comment,
6+
/\s/
7+
],
8+
9+
externals: $ => [
10+
$._newline,
11+
$._indent,
12+
$._dedent
13+
],
14+
15+
rules: {
16+
module: $ => optional(seq(
17+
repeat1($._statement),
18+
optional(choice(';', $._newline))
19+
)),
20+
21+
_statement: $ => choice(
22+
seq($._simple_statement, $._newline),
23+
$._compound_statement
24+
),
25+
26+
// Simple statements
27+
28+
_simple_statement: $ => choice(
29+
$.print_statement,
30+
$.expression_statement
31+
),
32+
33+
print_statement: $ => seq(
34+
'print',
35+
$._expression,
36+
repeat(seq(',', $._expression))
37+
),
38+
39+
expression_statement: $ => $._expression,
40+
41+
// Compount statements
42+
43+
_compound_statement: $ => choice(
44+
$.if_statement
45+
),
46+
47+
if_statement: $ => seq(
48+
'if',
49+
$._expression,
50+
':',
51+
$._suite,
52+
repeat($.elif_clause),
53+
optional($.else_clause)
54+
),
55+
56+
elif_clause: $ => seq(
57+
'elif',
58+
$._expression,
59+
':',
60+
$._suite
61+
),
62+
63+
else_clause: $ => seq(
64+
'else',
65+
':',
66+
$._suite
67+
),
68+
69+
_suite: $ => choice(
70+
$._simple_statement,
71+
seq(
72+
$._indent,
73+
optional(sep1($._statement, choice(';', $._newline))),
74+
$._dedent
75+
)
76+
),
77+
78+
// Expressions
79+
80+
_expression: $ => choice(
81+
$.identifier,
82+
$.binary_operator
83+
),
84+
85+
binary_operator: $ => choice(
86+
prec.left(seq($._expression, '+', $._expression))
87+
),
88+
89+
identifier: $ => /\a\w*/,
90+
91+
comment: $ => token(seq(
92+
'#',
93+
/.+/
94+
))
95+
}
96+
})
97+
98+
function sep1(rule, separator) {
99+
return seq(rule, repeat(seq(separator, rule)))
100+
}

grammar_test/statements.txt

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
======================================
2+
Print statements
3+
=====================================
4+
5+
print a
6+
print b, c
7+
8+
---
9+
10+
(module
11+
(print_statement (identifier))
12+
(print_statement (identifier) (identifier)))
13+
14+
======================================
15+
Expression statements
16+
=====================================
17+
18+
a
19+
b + c
20+
21+
---
22+
23+
(module
24+
(expression_statement (identifier))
25+
(expression_statement (binary_operator (identifier) (identifier))))
26+
27+
======================================
28+
If statements
29+
=====================================
30+
31+
if a:
32+
b
33+
34+
---
35+
36+
(module
37+
(if_statement (identifier)
38+
(expression_statement (identifier))))
39+
40+
======================================
41+
If else statements
42+
=====================================
43+
44+
if a:
45+
b
46+
elif c:
47+
d
48+
else:
49+
f
50+
51+
---
52+
53+
(module
54+
(if_statement (identifier)
55+
(expression_statement (identifier))
56+
(elif_clause (identifier)
57+
(expression_statement (identifier)))
58+
(else_clause
59+
(expression_statement (identifier)))))

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("./build/Release/ts_language_python_binding");

package.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "tree-sitter-python",
3+
"version": "0.0.1",
4+
"description": "Python grammar for tree-sitter",
5+
"main": "index.js",
6+
"keywords": [
7+
"parser",
8+
"lexer"
9+
],
10+
"author": "Max Brunsfeld",
11+
"license": "MIT",
12+
"dependencies": {
13+
"nan": "^2.4.0"
14+
},
15+
"devDependencies": {
16+
"tree-sitter-cli": ">= 0.3.7-0"
17+
},
18+
"scripts": {
19+
"build": "tree-sitter generate && node-gyp build",
20+
"test": "tree-sitter test"
21+
},
22+
"repository": "https://github.com/tree-sitter/tree-sitter-python"
23+
}

src/binding.cc

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "tree_sitter/parser.h"
2+
#include <node.h>
3+
#include "nan.h"
4+
5+
using namespace v8;
6+
7+
extern "C" TSLanguage * ts_language_python();
8+
9+
namespace tree_sitter_python {
10+
11+
NAN_METHOD(New) {}
12+
13+
void Init(Handle<Object> exports, Handle<Object> module) {
14+
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
15+
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
16+
tpl->InstanceTemplate()->SetInternalFieldCount(1);
17+
18+
Local<Function> constructor = tpl->GetFunction();
19+
Local<Object> instance = constructor->NewInstance(0, NULL);
20+
Nan::SetInternalFieldPointer(instance, 0, ts_language_python());
21+
22+
instance->Set(Nan::New("name").ToLocalChecked(), Nan::New("python").ToLocalChecked());
23+
module->Set(Nan::New("exports").ToLocalChecked(), instance);
24+
}
25+
26+
NODE_MODULE(ts_language_python_binding, Init)
27+
28+
} // namespace tree_sitter_python

0 commit comments

Comments
 (0)