Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/lipsum/code/PhutilCLikeCodeSnippetContextFreeGrammar.php
12262 views
1
<?php
2
3
/**
4
* Generates valid context-free code for most programming languages that could
5
* pass as C. Except for PHP. But includes Java (mostly).
6
*/
7
abstract class PhutilCLikeCodeSnippetContextFreeGrammar
8
extends PhutilCodeSnippetContextFreeGrammar {
9
10
protected function buildRuleSet() {
11
return array(
12
$this->getStmtTerminationGrammarSet(),
13
$this->getVarNameGrammarSet(),
14
$this->getNullExprGrammarSet(),
15
$this->getNumberGrammarSet(),
16
$this->getExprGrammarSet(),
17
$this->getCondGrammarSet(),
18
$this->getLoopGrammarSet(),
19
$this->getStmtGrammarSet(),
20
$this->getAssignmentGrammarSet(),
21
$this->getArithExprGrammarSet(),
22
$this->getBoolExprGrammarSet(),
23
$this->getBoolValGrammarSet(),
24
$this->getTernaryExprGrammarSet(),
25
26
$this->getFuncNameGrammarSet(),
27
$this->getFuncCallGrammarSet(),
28
$this->getFuncCallParamGrammarSet(),
29
$this->getFuncDeclGrammarSet(),
30
$this->getFuncParamGrammarSet(),
31
$this->getFuncBodyGrammarSet(),
32
$this->getFuncReturnGrammarSet(),
33
);
34
}
35
36
protected function getStartGrammarSet() {
37
$start_grammar = parent::getStartGrammarSet();
38
39
$start_grammar['start'][] = '[funcdecl]';
40
41
return $start_grammar;
42
}
43
44
protected function getStmtTerminationGrammarSet() {
45
return $this->buildGrammarSet('term', array(';'));
46
}
47
48
protected function getFuncCallGrammarSet() {
49
return $this->buildGrammarSet('funccall',
50
array(
51
'[funcname]([funccallparam])',
52
));
53
}
54
55
protected function getFuncCallParamGrammarSet() {
56
return $this->buildGrammarSet('funccallparam',
57
array(
58
'',
59
'[expr]',
60
'[expr], [expr]',
61
));
62
}
63
64
protected function getFuncDeclGrammarSet() {
65
return $this->buildGrammarSet('funcdecl',
66
array(
67
'function [funcname]([funcparam]) '.
68
'{[funcbody, indent, block, trim=right]}',
69
));
70
}
71
72
protected function getFuncParamGrammarSet() {
73
return $this->buildGrammarSet('funcparam',
74
array(
75
'',
76
'[varname]',
77
'[varname], [varname]',
78
'[varname], [varname], [varname]',
79
));
80
}
81
82
protected function getFuncBodyGrammarSet() {
83
return $this->buildGrammarSet('funcbody',
84
array(
85
"[stmt]\n[stmt]\n[funcreturn]",
86
"[stmt]\n[stmt]\n[stmt]\n[funcreturn]",
87
"[stmt]\n[stmt]\n[stmt]\n[stmt]\n[funcreturn]",
88
));
89
}
90
91
protected function getFuncReturnGrammarSet() {
92
return $this->buildGrammarSet('funcreturn',
93
array(
94
'return [expr][term]',
95
'',
96
));
97
}
98
99
// Not really C, but put it here because of the curly braces and mostly shared
100
// among Java and PHP
101
protected function getClassDeclGrammarSet() {
102
return $this->buildGrammarSet('classdecl',
103
array(
104
'[classinheritancemod] class [classname] {[classbody, indent, block]}',
105
'class [classname] {[classbody, indent, block]}',
106
));
107
}
108
109
protected function getClassNameGrammarSet() {
110
return $this->buildGrammarSet('classname',
111
array(
112
'MuffinHouse',
113
'MuffinReader',
114
'MuffinAwesomizer',
115
'SuperException',
116
'Librarian',
117
'Book',
118
'Ball',
119
'BallOfCode',
120
'AliceAndBobsSharedSecret',
121
'FileInputStream',
122
'FileOutputStream',
123
'BufferedReader',
124
'BufferedWriter',
125
'Cardigan',
126
'HouseOfCards',
127
'UmbrellaClass',
128
'GenericThing',
129
));
130
}
131
132
protected function getClassBodyGrammarSet() {
133
return $this->buildGrammarSet('classbody',
134
array(
135
'[methoddecl]',
136
"[methoddecl]\n\n[methoddecl]",
137
"[propdecl]\n[propdecl]\n\n[methoddecl]\n\n[methoddecl]",
138
"[propdecl]\n[propdecl]\n[propdecl]\n\n[methoddecl]\n\n[methoddecl]".
139
"\n\n[methoddecl]",
140
));
141
}
142
143
protected function getVisibilityGrammarSet() {
144
return $this->buildGrammarSet('visibility',
145
array(
146
'private',
147
'protected',
148
'public',
149
));
150
}
151
152
protected function getClassInheritanceModGrammarSet() {
153
return $this->buildGrammarSet('classinheritancemod',
154
array(
155
'final',
156
'abstract',
157
));
158
}
159
160
// Keeping this separate so we won't give abstract methods a function body
161
protected function getMethodInheritanceModGrammarSet() {
162
return $this->buildGrammarSet('methodinheritancemod',
163
array(
164
'final',
165
));
166
}
167
168
protected function getMethodDeclGrammarSet() {
169
return $this->buildGrammarSet('methoddecl',
170
array(
171
'[visibility] [methodfuncdecl]',
172
'[visibility] [methodfuncdecl]',
173
'[methodinheritancemod] [visibility] [methodfuncdecl]',
174
'[abstractmethoddecl]',
175
));
176
}
177
178
protected function getMethodFuncDeclGrammarSet() {
179
return $this->buildGrammarSet('methodfuncdecl',
180
array(
181
'function [funcname]([funcparam]) '.
182
'{[methodbody, indent, block, trim=right]}',
183
));
184
}
185
186
protected function getMethodBodyGrammarSet() {
187
return $this->buildGrammarSet('methodbody',
188
array(
189
"[methodstmt]\n[methodbody]",
190
"[methodstmt]\n[funcreturn]",
191
));
192
}
193
194
protected function getMethodStmtGrammarSet() {
195
$stmts = $this->getStmtGrammarSet();
196
197
return $this->buildGrammarSet('methodstmt',
198
array_merge(
199
$stmts['stmt'],
200
array(
201
'[methodcall][term]',
202
)));
203
}
204
205
protected function getMethodCallGrammarSet() {
206
// Java/JavaScript
207
return $this->buildGrammarSet('methodcall',
208
array(
209
'this.[funccall]',
210
'[varname].[funccall]',
211
'[classname].[funccall]',
212
));
213
}
214
215
protected function getAbstractMethodDeclGrammarSet() {
216
return $this->buildGrammarSet('abstractmethoddecl',
217
array(
218
'abstract function [funcname]([funcparam])[term]',
219
));
220
}
221
222
protected function getPropDeclGrammarSet() {
223
return $this->buildGrammarSet('propdecl',
224
array(
225
'[visibility] [varname][term]',
226
));
227
}
228
229
protected function getClassRuleSets() {
230
return array(
231
$this->getClassInheritanceModGrammarSet(),
232
$this->getMethodInheritanceModGrammarSet(),
233
$this->getClassDeclGrammarSet(),
234
$this->getClassNameGrammarSet(),
235
$this->getClassBodyGrammarSet(),
236
$this->getMethodDeclGrammarSet(),
237
$this->getMethodFuncDeclGrammarSet(),
238
$this->getMethodBodyGrammarSet(),
239
$this->getMethodStmtGrammarSet(),
240
$this->getMethodCallGrammarSet(),
241
$this->getAbstractMethodDeclGrammarSet(),
242
$this->getPropDeclGrammarSet(),
243
$this->getVisibilityGrammarSet(),
244
);
245
}
246
247
public function generateClass() {
248
$rules = array_merge($this->getRules(), $this->getClassRuleSets());
249
$rules['start'] = array('[classdecl]');
250
$count = 0;
251
return $this->applyRules('[start]', $count, $rules);
252
}
253
254
}
255
256