Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9561ece

Browse files
committedMay 8, 2018
cEP-0018: Integration of ANTLR in coala
Propose integration of ANTLR in coala Closes #118
1 parent f0c598f commit 9561ece

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
 

‎cEP-0018.md

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Integration of ANTLR into coala core
2+
3+
| Metadata | |
4+
| ------------ |-----------------------------------------|
5+
| cEP | 0018 |
6+
| Version | 0.1.0 |
7+
| Title | Integration of ANTLR into coala core |
8+
| Authors | Viresh Gupta <viresh16118@iiitd.ac.in> |
9+
| Status | Proposed |
10+
| Type | Feature |
11+
12+
# Abstract
13+
14+
This document describes how an API based on ANTLR will be constructed and
15+
maintained.
16+
17+
# Introduction
18+
19+
ANTLR provides parsers for various language grammars and thus we can provide
20+
an interface from within coala and make it available to bear writers so that
21+
they can write advanced linting bears. This will aim at supporting the more
22+
flexible visitor based method of AST traversal (as opposed to listener based
23+
mechanisms).
24+
25+
The proposal is to introduce a parallel concept to the coala-bears library,
26+
which will be called the coala-ast hereon.
27+
28+
# Proposed Change
29+
30+
Here is the detailed implementation stepwise:
31+
32+
1. There will be a separate repository named as coala-ast which will be
33+
installable via ```pip install coala-ast```.
34+
2. A new interface would be introduced in coala-core (```coala/coalib```),
35+
which would be the new ast package. This would be the ```coalib.ast``` package
36+
3. The ```coalib.ast``` package will provide endpoints relevant to the visitor
37+
model of traversing the ast generated via ANTLR.
38+
4. The coala-ast repository will hold parser generated (with python targe)
39+
beforehand for the supported set of grammars.
40+
5. ```coalib.ast``` will have an AST loader class that will be responsible for
41+
loading the AST of a given file depending on the extension.
42+
For e.g, a .c file will be loaded using the parser from ```coala-ast``` for c
43+
language.
44+
6. Another AST walker class will be responsible for providing endpoints for
45+
traversing the AST using methods such as ```get_next_node``` and
46+
```get_previous_node```.
47+
48+
# Management of the new ```coala-ast``` repository
49+
50+
Managing a new repository is a heavy task, and this will be highly automated as
51+
follows:
52+
53+
1. The parsers in coala-ast would be generated and pushed via travis-builds
54+
whenever a new grammar is pushed.
55+
2. The cib tool can be enhanced to deal with the installation of bears that
56+
require only some specified parsers (for e.g a PyUnusedVarBear would only
57+
require parser for python)
58+
3. The cib tool can also trigger specialised builds and download the newly
59+
generated parser on the fly
60+
61+
# Code Samples/Prototypes
62+
Here is a prototype for the implementations within coalib.ast:
63+
64+
```python
65+
import parsers
66+
import antlr4
67+
68+
class ASTLoader():
69+
lexerMapping = {
70+
'c' : parser.clexer,
71+
'py' : parser.pylexer,
72+
'js' : parser.jslexer,
73+
...
74+
}
75+
parserMapping = {
76+
'c' : parser.cparser,
77+
'py' : parser.pyparser,
78+
'js' : parser.jsparser,
79+
...
80+
}
81+
82+
@staticmethod
83+
def loadFile(file,filename):
84+
""" Loads file's AST into memory """
85+
ext = get_extension(filename)
86+
if ext is None:
87+
raise FileExtensionNotSupported
88+
inputStream = file.readlines()
89+
lexer = lexerMapping[ext](inputStream)
90+
parser = parserMapping[ext](lexer)
91+
return parser
92+
93+
class ASTWalker():
94+
treeRoot = None
95+
tree = None
96+
def __init__(file,filename):
97+
self.tree = ASTLoader.load(file, filename)
98+
self.treeRoot = self.tree
99+
100+
def get_next_node(self):
101+
""" Modify the internal tree variable and return the next node """
102+
103+
def get_prev_node(self):
104+
""" Modify the internal tree variable and return prev node """
105+
106+
def reset(self):
107+
""" Reset the internal tree variable to tree root """
108+
109+
def isTerminalNode(node):
110+
""" Determine if the node is terminal """
111+
return isinstance(node, antlr4.tree.Tree.TerminalNode)
112+
113+
...
114+
115+
```
116+
117+
118+
### Prototype of `ASTBear` class implementation:
119+
120+
```python
121+
from coalib.bears.LocalBear import Bear
122+
from coalaib.ast import ASTWalker
123+
124+
class ASTBear(LocalBear):
125+
walker = None
126+
127+
def initialise(file, filename):
128+
walker = ASTWalker(file, filename)
129+
130+
def run(self,
131+
filename,
132+
file,
133+
tree,
134+
*args,
135+
dependency_results=None,
136+
**kwargs):
137+
raise NotImplementedError # Needs to be done by bear
138+
139+
```
140+
141+
A test bear:
142+
143+
```python
144+
from coalib.results.Result import Result
145+
from coalib.bears.ASTBear import ASTBear
146+
147+
class TestBear(ASTBear):
148+
def run(self,
149+
filename,
150+
file,
151+
tree,
152+
*args,
153+
dependency_results=None,
154+
**kwargs):
155+
self.initialise(file, filename)
156+
num_nodes = 0
157+
while(tree.get_next_node() != None):
158+
num_nodes += 1
159+
yield Result(self, 'File {} has {} nodes '
160+
' in AST.'.format(filename, num_nodes))
161+
162+
```

0 commit comments

Comments
 (0)
Please sign in to comment.