PageRenderTime 186ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/parse-js.ss

http://github.com/yinwang0/ydiff
Scheme | 694 lines | 370 code | 230 blank | 94 comment | 0 complexity | d9a870b5e6d2c82b12954b8549900cc9 MD5 | raw file
Possible License(s): GPL-3.0
  1. ;; ydiff - a language-aware tool for comparing programs
  2. ;; Copyright (C) 2011 Yin Wang (yinwang0@gmail.com)
  3. ;; This program is free software: you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. (load "parsec.ss")
  14. ;-------------------------------------------------------------
  15. ; scanner settings
  16. ;-------------------------------------------------------------
  17. (define *delims* (list "(" ")" "[" "]" "{" "}" "," "`" ";"))
  18. (define *operators*
  19. (list
  20. ">>>="
  21. "<<=" ">>=" ">>>" "===" "!=="
  22. "==" "!=" ">=" "<=" "&&" "||" ">>" "<<" "++" "--"
  23. "+=" "-=" "*=" "/=" "%=" "&=" "^=" "|="
  24. "=" "+" "-" "*" "/" "%" "~" "!" ":" "?" "." ">" "<"
  25. ))
  26. (define *line-comment* (list "//"))
  27. (define *comment-start* "/*")
  28. (define *comment-end* "*/")
  29. (define *quotation-marks* '(#\" #\'))
  30. (define *significant-whitespaces*
  31. (list #\newline #\linefeed #\u2028 #\u2029))
  32. (define alpha?
  33. (predor char-alphabetic?
  34. (lambda (x) (char=? x #\$))))
  35. ;-------------------------------------------------------------
  36. ; primitive parsers
  37. ;-------------------------------------------------------------
  38. (:: $identifier
  39. ($pred
  40. (lambda (t)
  41. (and (Token? t)
  42. (id? (Token-text t))))))
  43. (:: $numeral-literal
  44. ($pred
  45. (lambda (t)
  46. (and (Token? t)
  47. (numeral? (Token-text t))))))
  48. (:: $string-literal ($pred Str?))
  49. (:: $newline ($pred Newline?))
  50. (:: $comment ($pred Comment?))
  51. ;; delimeters
  52. (:: |,| (@_ ","))
  53. (:: |;| (@~ ";"))
  54. (:: |:| (@_ ":"))
  55. (:: |(| (@~ "("))
  56. (:: |)| (@~ ")"))
  57. (:: |[| (@~ "["))
  58. (:: |]| (@~ "]"))
  59. (:: |{| (@~ "{"))
  60. (:: |}| (@~ "}"))
  61. ;; $glob^ and $*^ needed to define |\n|, because the
  62. ;; definition of |\n| must not contain any call to @seq
  63. ;; otherwise the parser will go into infinite loop
  64. (:: |\n| ($glob^ (@*^ $newline)))
  65. (:: |;\n| (@or |;| |\n|))
  66. ;; Redefine sequence to get over newlines
  67. (define old-seq @seq)
  68. (define @seq
  69. (lambda ps
  70. (let ([psj (join ps |\n|)])
  71. (apply old-seq `(,|\n| ,@psj ,|\n|)))))
  72. ;; ($eval (@seq ($$ "foo") ($$ "bar"))
  73. ;; (scan "
  74. ;; foo
  75. ;; bar "))
  76. ;-------------------------------------------------------------
  77. ; compound parsers
  78. ;-------------------------------------------------------------
  79. (::= $program 'program
  80. (@* $statement))
  81. (:: $statement
  82. (@or $statement-block
  83. $empty-statement
  84. $function-definition
  85. $variable-statement
  86. $with-statement
  87. $if-statement
  88. $switch-statement
  89. $do-while-statement
  90. $while-statement
  91. $for-statement
  92. $for-in-statement
  93. $continue-statement
  94. $break-statement
  95. $try-statement
  96. $throw-statement
  97. $return-statement
  98. $labelled-statement
  99. $expression-statement
  100. ))
  101. (::= $statement-block 'block
  102. |{| (@* $statement) |}|
  103. )
  104. (:: $empty-statement |;|)
  105. (::= $function-definition 'function
  106. ($$ "function") (@= 'name $identifier) $formal-parameter-list
  107. $function-body)
  108. ;; function-expression can be unnamed
  109. (::= $function-expression 'function
  110. ($$ "function") (@= 'name (@? $identifier)) $formal-parameter-list
  111. $function-body)
  112. (::= $formal-parameter-list 'parameters
  113. (@or (@... |(| (@? (@.@ $identifier |,|)) |)| )
  114. $identifier))
  115. (::= $function-body 'body
  116. $statement-block
  117. )
  118. ;;---------------- variable statement -----------------
  119. (::= $variable-statement 'variable-declaration
  120. ($$ "var") (@.@ $variable-declaration |,|) |;\n|
  121. )
  122. (::= $variable-declaration 'variable-declaration
  123. $identifier (@? $initializer))
  124. (::= $initializer 'initializer
  125. (@... ($$ "=") $assignment-expression))
  126. ;;--------------------------------------------
  127. (::= $with-statement 'with
  128. ($$ "with") (@= 'obj |(| $expression |)|)
  129. $statement
  130. )
  131. ;;--------------------------------------------
  132. (::= $if-statement 'if
  133. ($$ "if") (@= 'test |(| $expression |)|) $statement
  134. (@? (@= 'else ($$ "else") $statement
  135. )))
  136. ;;--------------------------------------------
  137. (::= $do-while-statement 'do-while
  138. ($$ "do") $statement
  139. (@= 'while-do ($$ "while") (@= 'test |(| $expression |)| ))
  140. |;\n|
  141. )
  142. ;;--------------------------------------------
  143. (::= $while-statement 'while
  144. ($$ "while") (@= 'test |(| $expression |)| )
  145. $statement
  146. )
  147. ;;--------------------------------------------
  148. (::= $for-statement 'for
  149. ($$ "for") (@= 'iter
  150. |(| (@? $for-initaliser) |;|
  151. (@? $expression) |;|
  152. (@? $expression)
  153. |)|
  154. )
  155. $statement
  156. )
  157. (::= $for-initaliser 'for-initializer
  158. (@or (@= 'variable-declaration
  159. ($$ "var") (@.@ $variable-declaration |,|))
  160. $expression
  161. ))
  162. ;;--------------------------------------------
  163. (::= $for-in-statement 'for-in
  164. ($$ "for") (@= 'iter
  165. |(| (@? $for-in-initalizer) ($$ "in") $expression |)|)
  166. $statement
  167. )
  168. (::= $for-in-initalizer 'for-in-initializer
  169. (@or (@= 'variable-declaration
  170. ($$ "var") (@.@ $variable-declaration |,|))
  171. $expression
  172. ))
  173. ;;--------------------------------------------
  174. (::= $continue-statement 'continue
  175. ($$ "continue") (@= 'label (@? $identifier)) |;\n|
  176. )
  177. ;;--------------------------------------------
  178. (::= $break-statement 'break
  179. ($$ "break") (@= 'label (@? $identifier)) |;\n|
  180. )
  181. ;;--------------------------------------------
  182. (::= $return-statement 'return
  183. ($$ "return") (@= 'value (@? $expression)) |;\n|
  184. )
  185. ;;--------------------------------------------
  186. (::= $labelled-statement 'labelled-statement
  187. $identifier |:| $statement
  188. )
  189. ;;--------------------------------------------
  190. (::= $switch-statement 'switch-statement
  191. ($$ "switch") |(| $expression |)|
  192. |{| (@* $case-clause)
  193. (@? $default-clause
  194. (@* $case-clause))
  195. |}|
  196. )
  197. (::= $case-clause 'case-clause
  198. ($$ "case") $expression |:| (@* $statement)
  199. )
  200. (::= $default-clause 'default
  201. ($$ "default") |:| (@* $statement)
  202. )
  203. ;;--------------------------------------------
  204. (::= $throw-statement 'throw
  205. ($$ "throw") $expression |;\n|
  206. )
  207. ;;--------------------------------------------
  208. (::= $try-statement 'try
  209. ($$ "try") $statement-block
  210. (@or $finally-clause
  211. (@... $catch-clause (@? $finally-clause)))
  212. )
  213. (::= $catch-clause 'catch
  214. ($$ "catch") |(| $identifier |)| $statement-block
  215. )
  216. (::= $finally-clause 'finally
  217. ($$ "finally") $statement-block
  218. )
  219. ;;--------------------------------------------
  220. (::= $expression-statement 'expression-statement
  221. $expression |;\n|
  222. )
  223. ;-------------------------------------------------------------
  224. ; expressions
  225. ;-------------------------------------------------------------
  226. ;; utility for constructing operators
  227. (define op
  228. (lambda (s)
  229. (@= 'op ($$ s))))
  230. (:: $expression
  231. $comma-expression)
  232. ;; 18. comma
  233. ;;--------------------------------------------
  234. (::= $comma-expression 'comma
  235. (@.@ $assignment-expression |,|))
  236. ;; 16. assignment
  237. ;;--------------------------------------------
  238. (:: $assignment-expression
  239. (@or (@= 'assignment
  240. $conditional-expression
  241. $assignment-operator
  242. $assignment-expression)
  243. $conditional-expression
  244. ))
  245. (:: $assignment-operator
  246. (@or (op "=")
  247. (op "*=")
  248. (op "/=")
  249. (op "%=")
  250. (op "+=")
  251. (op "-=")
  252. (op "<<=")
  253. (op ">>=")
  254. (op ">>>=")
  255. (op "&=")
  256. (op "^=")
  257. (op "|=")
  258. ))
  259. ;; 15. ?: Ternary conditional
  260. ;;--------------------------------------------
  261. (:: $conditional-expression
  262. (@or (@= 'conditional-expression
  263. (@= 'test $logical-or-expression)
  264. (@~ "?") (@= 'then $conditional-expression)
  265. (@~ ":") (@= 'else $conditional-expression))
  266. $logical-or-expression
  267. ))
  268. ; ($eval $conditional-expression (scan "x > 0? x-1 : x"))
  269. ;; 14. || Logical OR
  270. ;;--------------------------------------------
  271. (:: $logical-or-expression
  272. (@or (@infix-left 'binop
  273. $logical-and-expression
  274. (op "||"))
  275. $logical-and-expression
  276. ))
  277. ; ($eval $logical-or-expression (scan "x || y"))
  278. ;; 13. && Logical AND
  279. ;;--------------------------------------------
  280. (:: $logical-and-expression
  281. (@or (@infix-left 'binop
  282. $bitwise-or-expression
  283. (op "&&"))
  284. $bitwise-or-expression
  285. ))
  286. ;; 12. | Bitwise OR (inclusive or)
  287. ;;--------------------------------------------
  288. (:: $bitwise-or-expression
  289. (@or (@infix-left 'binop
  290. $bitwise-xor-expression
  291. (op "|"))
  292. $bitwise-xor-expression
  293. ))
  294. ;; 11. ^ Bitwise XOR (exclusive or)
  295. ;;--------------------------------------------
  296. (:: $bitwise-xor-expression
  297. (@or (@infix-left 'binop
  298. $bitwise-and-expression
  299. (op "^"))
  300. $bitwise-and-expression
  301. ))
  302. ;; 10. & Bitwise AND
  303. ;;--------------------------------------------
  304. (:: $bitwise-and-expression
  305. (@or (@infix-left 'binop
  306. $equality-expression
  307. (op "&"))
  308. $equality-expression
  309. ))
  310. ;; 9. equality
  311. ;;--------------------------------------------
  312. (:: $equality-expression
  313. (@or (@infix-left 'binop
  314. $relational-expression
  315. $equality-operator)
  316. $relational-expression
  317. ))
  318. (:: $equality-operator
  319. (@or (op "==")
  320. (op "!=")
  321. (op "===")
  322. (op "!==")
  323. ))
  324. ;; 8. relational
  325. ;;--------------------------------------------
  326. (:: $relational-expression
  327. (@or (@infix-left 'binop
  328. $bitwise-shift-expression
  329. $relational-operator)
  330. $bitwise-shift-expression
  331. ))
  332. (:: $relational-operator
  333. (@or (op "<")
  334. (op "<=")
  335. (op ">")
  336. (op ">=")
  337. (op "instanceof")
  338. (op "in")
  339. ))
  340. ;; 7. bitwise shift
  341. ;;--------------------------------------------
  342. (:: $bitwise-shift-expression
  343. (@or (@infix-left 'binop
  344. $additive-expression
  345. $bitwise-shift-operator)
  346. $additive-expression
  347. ))
  348. (:: $bitwise-shift-operator
  349. (@or (op "<<")
  350. (op ">>")
  351. (op ">>>")
  352. ))
  353. ;; 6. additive
  354. ;;--------------------------------------------
  355. (:: $additive-expression
  356. (@or (@infix-left 'binop
  357. $multiplicative-expression
  358. $additive-operator)
  359. $multiplicative-expression
  360. ))
  361. (:: $additive-operator
  362. (@or (op "+")
  363. (op "-")))
  364. ;; ($eval $additive-expression (scan "x + y + z"))
  365. ;; 5. multiplicative
  366. ;;--------------------------------------------
  367. (:: $multiplicative-expression
  368. (@or (@infix-left 'binop
  369. $unary-expression
  370. $multiplicative-operator)
  371. $unary-expression))
  372. (:: $multiplicative-operator
  373. (@or (op "*")
  374. (op "/")
  375. (op "%")))
  376. ;; 3. prefix
  377. ;; 2. postfix
  378. ;;--------------------------------------------
  379. (:: $unary-expression
  380. $prefix-expression)
  381. (:: $prefix-expression
  382. (@or (@prefix 'prefix
  383. $postfix-expression
  384. $prefix-operator)
  385. $postfix-expression))
  386. (:: $postfix-expression
  387. (@or (@postfix 'postfix
  388. $primary-expression
  389. $postfix-operator)
  390. $primary-expression))
  391. (:: $prefix-operator
  392. (@or (op "new")
  393. (op "delete")
  394. (op "void")
  395. (op "typeof")
  396. (op "++")
  397. (op "--")
  398. (op "+")
  399. (op "-")
  400. (op "~")
  401. (op "!")
  402. ))
  403. (:: $postfix-operator
  404. (@or $index-suffix
  405. $property-reference-suffix
  406. $arguments
  407. (op "++")
  408. (op "--")))
  409. (::= $index-suffix 'index
  410. |[| $expression |]|
  411. )
  412. (::= $property-reference-suffix 'property
  413. (@_ ".") $identifier)
  414. (::= $arguments 'arguments
  415. |(| (@? (@.@ $assignment-expression |,|)) |)|
  416. )
  417. (::= $new-expression 'new
  418. ($$ "new") $postfix-expression)
  419. ;; 1. primary
  420. ;;--------------------------------------------
  421. (:: $primary-expression
  422. (@or $function-expression
  423. $identifier
  424. $literal
  425. (@= 'expression |(| $expression |)| )
  426. ))
  427. ;;-----------
  428. (::= $array-literal 'array-literal
  429. |[| (@? (@.@ $assignment-expression |,|)) |]|
  430. )
  431. ;;-----------
  432. (::= $object-literal 'object-literal
  433. |{| $property-name-value (@* |,| $property-name-value) |}|
  434. )
  435. (::= $property-name-value 'property-name-value
  436. $property-name |:| $assignment-expression)
  437. (:: $property-name
  438. (@or $identifier
  439. $string-literal
  440. $numeral-literal))
  441. ;;-----------
  442. (:: $literal
  443. (@or ($$ "null")
  444. ($$ "true")
  445. ($$ "false")
  446. (@= 'this ($$ "this"))
  447. $string-literal
  448. $numeral-literal
  449. $array-literal
  450. $object-literal
  451. ))
  452. ;-------------------------------------------------------------
  453. ; parse-js
  454. ;-------------------------------------------------------------
  455. (define parse-js
  456. (lambda (s)
  457. (first-val
  458. ($eval $program
  459. (filter (lambda (x) (not (Comment? x)))
  460. (scan s))))))
  461. ;-------------------------------------------------------------
  462. ; tests
  463. ;-------------------------------------------------------------
  464. ;; (parse-js (read-file "nav-div.js"))