-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathocaml-tree-sitter-gen-c
executable file
·84 lines (72 loc) · 2.69 KB
/
ocaml-tree-sitter-gen-c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#! /usr/bin/env bash
#
# Copy tree-sitter grammars from the semgrep-grammars repo into the current
# language directory.
#
set -eu
name=$(basename "$(pwd)")
# Location of pre-generated grammar.json. This is required
# if we're using a tree-sitter grammar.
#
# It is ignored if 'grammar.js' exists locally.
#
import_from=../semgrep-grammars/lang/"$name"
error() {
cat >&2 <<EOF
Error: $*
EOF
exit 1
}
# Generate C source code for the grammar, in two passes:
#
# 1. Import files from semgrep-grammars
# 2. Simplify grammar.json so it's compatible with ocaml-tree-sitter.
# 3. Generate 'parser.c' from the simplified 'grammar.json'.
#
if [[ -e grammar.js ]]; then
# This mechanism is used for ocaml-tree-sitter test grammars, which just
# consist of a local 'grammar.json' file.
echo "$name: Generating initial 'grammar.json' from 'grammar.js'."
tree-sitter generate --no-bindings
mkdir -p src
if [[ -e orig/LICENSE ]]; then cp -L orig/LICENSE src; fi
if [[ -e orig/scanner.c ]]; then cp -L orig/scanner.c src; fi
if [[ -e orig/scanner.cc ]]; then cp -L orig/scanner.cc src; fi
else
# This mechanism is used with languages whose base grammar is defined
# in a tree-sitter-* submodule.
# tree-sitter 0.22.6 creates a dummy 'grammar.js' file if
# there isn't one already. This creates confusing situations
# because our input grammar as created by ocaml-tree-sitter is
# 'src/grammar.json', not the usual 'grammar.js'. Creating our
# own unparseable 'grammar.js' is a protection against using
# the wrong grammar.
# Tracked at https://github.com/tree-sitter/tree-sitter/issues/3415
echo "..... not the input grammar! Use 'tree-sitter generate src/grammar.json'" \
> grammar.js
orig_grammar_json="$import_from"/src/grammar.json
if [[ ! -e "$orig_grammar_json" ]]; then
cat >&2 <<EOF
Missing local 'grammar.js' and missing '$orig_grammar_json'.
One of these files must exist.
EOF
exit 1
else
echo "$name: Importing initial 'grammar.json'."
mkdir -p src
cp -RL "$import_from"/src/* src/
rm -f src/parser.c
fi
fi
echo "$name: Simplifying 'grammar.json' for ocaml-tree-sitter."
mv src/grammar.json src/grammar.json.orig
ocaml-tree-sitter simplify src/grammar.json.orig src/grammar.json
echo "$name: Recovering informational JS grammars from JSON."
ocaml-tree-sitter to-js src/grammar.json.orig grammar-rev.js.orig
ocaml-tree-sitter to-js src/grammar.json grammar-rev.js
echo "$name: Generating definitive 'parser.c'."
tree-sitter generate src/grammar.json --no-bindings
# Make sure we get an error in case of OOM leading to no src/parser.c
test -f src/parser.c || error \
"tree-sitter didn't generate src/parser.c." \
"This may happen when not enough memory is available."