2 * Copyright (c) 2016, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
11 module type Grammar
= sig
22 val grammar
: nonterm
-> symbol list list
24 val to_string
: term
-> string
26 val nonterm_to_string
: nonterm
-> string
30 module HackGrammarTypeDef
= struct
31 module TokenKind
= Full_fidelity_token_kind
33 type term
= TokenKind.t
34 and nonterm
= string * (unit -> symbol list list
)
40 module HackGrammarHelper
= struct
43 let text = String.lowercase_ascii
text in
44 match Full_fidelity_token_kind.from_string
text with
48 (* generate a random name *)
50 let var_length_max = 8 in
51 let alpha_size = 26 in (* 26 English alphabet *)
52 let postfix_size = Random.int var_length_max in
53 let first_symbol = int_of_char 'a'
+ Random.int alpha_size in
54 let second_symbol = int_of_char 'A'
+ Random.int alpha_size in
56 match Random.int (2 * alpha_size) with
57 | n
when n
< 26 -> int_of_char 'a'
+ n
58 | n
-> int_of_char 'A'
+ n
- 26
61 char_of_int
(if i
= 0 then first_symbol
62 else if i
= 1 then second_symbol
64 let result = String.init
(postfix_size + 2) init_fun in
65 if is_keyword result then gen_name() else result
67 (* create the powerset of the given set in lists. For our use case, the
68 * original and the resultant sets are ordered and the function should
69 * preserve the order *)
71 let folder acc el
= [] :: List.map
(fun lst
-> el
:: lst
) acc
in
72 List.fold_left
folder [[]] (List.rev lst
)
74 (* return the combinations of all pairs from each of list1 and list2
75 * The pair is ordered so that the element in list 1 is the first argument to
77 let cross lst1 lst2 combinor
=
79 (List.map
(fun x
-> List.map
(fun y
-> combinor x y
) lst2
) lst1
)
82 module HackGrammarTermSpec
= struct
83 include HackGrammarTypeDef
84 include HackGrammarHelper
88 (************************ Definition of terms ****************************)
89 let term_array = Term Array
90 let term_list = Term List
92 let equal = Term Equal
93 let backslash = Term Backslash
94 let equal_equal = Term EqualEqual
95 let equal_equal_equal = Term EqualEqualEqual
96 let equal_greater_than = Term EqualGreaterThan
97 let equal_equal_greater_than = Term EqualEqualGreaterThan
98 let dollar = Term Dollar
99 let dollar_dollar = Term DollarDollar
100 let star_star_equal = Term StarStarEqual
101 let star_equal = Term StarEqual
102 let slash_equal = Term SlashEqual
103 let percent_equal = Term PercentEqual
104 let plus_equal = Term PlusEqual
105 let plus_plus = Term PlusPlus
106 let minus_minus = Term MinusMinus
109 let minus = Term Minus
111 let slash = Term Slash
112 let percent = Term Percent
114 let ampersand = Term Ampersand
115 let ampersand_ampersand = Term AmpersandAmpersand
116 let carat = Term Carat
118 let bar_bar = Term BarBar
119 let exclamation = Term Exclamation
120 let exclamation_equal = Term ExclamationEqual
121 let exclamation_equal_equal = Term ExclamationEqualEqual
122 let tilde = Term Tilde
123 let minus_equal = Term MinusEqual
124 let dot_equal = Term DotEqual
125 let dot_dot_dot = Term DotDotDot
126 let less_than = Term LessThan
127 let less_than_equal = Term LessThanEqual
128 let less_than_less_than = Term LessThanLessThan
129 let less_less_equal = Term LessThanLessThanEqual
130 let greater_than = Term GreaterThan
131 let greater_than_equal = Term GreaterThanEqual
132 let greater_than_greater_than = Term GreaterThanGreaterThan
133 let greater_greater_equal = Term GreaterThanGreaterThanEqual
134 let ampersand_equal = Term AmpersandEqual
135 let carat_equal = Term CaratEqual
136 let bar_equal = Term BarEqual
137 let bar_greater_than = Term BarGreaterThan
138 let minus_greater_than = Term MinusGreaterThan
139 let colon_colon = Term ColonColon
140 let star_star = Term StarStar
141 let question = Term Question
142 let question_question = Term QuestionQuestion
143 let question_minus_greater_than = Term QuestionMinusGreaterThan
144 let clone = Term Clone
145 let require = Term Require
146 let require_once = Term Require_once
147 let term_function = Term Function
148 let abstract = Term Abstract
149 let final = Term Final
151 let interface = Term Interface
152 let trait = Term Trait
153 let term_class = Term Class
154 let namespace = Term Namespace
155 let implements = Term Implements
156 let extends = Term Extends
158 let const = Term Const
159 let destruct = Term Destruct
160 let construct = Term Construct
161 let term_public = Term Public
162 let term_private = Term Private
163 let term_protected = Term Protected
164 let term_new = Term New
165 let instanceof = Term Instanceof
166 let async = Term Async
168 let default = Term Default
169 let colon = Term Colon
170 let comma = Term Comma
171 let left_paren = Term LeftParen
172 let right_paren = Term RightParen
173 let left_brace = Term LeftBrace
174 let right_brace = Term RightBrace
175 let left_bracket = Term LeftBracket
176 let right_bracket = Term RightBracket
177 let static = Term Static
178 let semicolon = Term Semicolon
179 let continue = Term Continue
180 let break = Term Break
181 let return = Term Return
182 let throw = Term Throw
183 let term_try = Term Try
184 let finally = Term Finally
185 let yield = Term Yield
186 let switch = Term Switch
187 let term_if = Term If
188 let term_else = Term Else
189 let elseif = Term Elseif
190 let term_do = Term Do
191 let term_while = Term While
192 let term_for = Term For
193 let foreach = Term Foreach
194 let await = Term Await
195 let term_as = Term As
196 let catch = Term Catch
199 let parent = Term Parent
200 let term_type = Term Type
201 let newtype = Term Newtype
203 let term_bool = Term Bool
204 let term_int = Term Int
205 let term_float = Term Float
206 let term_string = Term String
207 let noreturn = Term Noreturn
208 let arraykey = Term Arraykey
210 let resource = Term Resource
211 let classname = Term Classname
212 let mixed = Term Mixed
213 let boolean_literal = Term BooleanLiteral
214 let floating_literal = Term FloatingLiteral
215 let null_literal = Term NullLiteral
216 let decimal_literal = Term DecimalLiteral
217 let octal_literal = Term OctalLiteral
218 let hexadecimal_literal = Term HexadecimalLiteral
219 let binary_literal = Term BinaryLiteral
220 let single_quoted_string_literal = Term SingleQuotedStringLiteral
221 let double_quoted_string_literal = Term DoubleQuotedStringLiteral
222 let heredoc_string_literal = Term HeredocStringLiteral
223 let nowdoc_string_literal = Term NowdocStringLiteral
225 (* TODO should be exit but doesnt exits, use echo for now *)
226 let term_exit = Term Echo
227 let tuple = Term Tuple
228 let shape = Term Shape
229 let xhp_element_name = Term XHPElementName
230 let xhp_string_literal = Term XHPStringLiteral
231 let xhp_body_text = Term XHPBody
232 let xhp_comment = Term XHPComment
233 let slash_greater_than = Term SlashGreaterThan
234 let less_than_slash = Term LessThanSlash
235 let inout = Term Inout
237 let rec qualified_name = NonTerm
("QualifiedName", fun () -> [
238 [name; backslash; name];
239 [qualified_name; backslash; name]])
241 (* For keywords, use TokenKind to_string. For names, use gen_name to generate
243 let to_string = function
244 | Dollar
-> "$" ^
(gen_name ())
246 (* TODO more general approach *)
247 (* | QualifiedName -> (gen_name ()) ^ "/" ^ (gen_name ()) *)
248 | BooleanLiteral
-> "true"
249 | FloatingLiteral
-> "42.42"
250 | NullLiteral
-> "null"
251 | HexadecimalLiteral
-> "0x16"
252 | DecimalLiteral
-> "12"
253 | OctalLiteral
-> "0123"
254 | BinaryLiteral
-> "0b101010"
256 (* | HeredocStringLiteral -> Printf.sprintf "<<<HSL\nsome string\nHSL;"
257 | NowdocStringLiteral -> Printf.sprintf "<<<'NSL'\nsome string\nNSL;" *)
258 | HeredocStringLiteral
-> "\"heredoc\""
259 | NowdocStringLiteral
-> "\"nowdoc\""
260 | DoubleQuotedStringLiteral
-> "\"double string\""
261 | SingleQuotedStringLiteral
-> "'single string'"
262 | XHPElementName
-> "<" ^
(gen_name())
263 | XHPStringLiteral
-> "\"xhp string literal\""
264 | XHPBody
-> "just some body text" (*TODO better test coverage *)
265 | XHPComment
-> "<!-- some comments -->"
266 | x
-> TokenKind.to_string x