PageRenderTime 87ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/parse-cpp.ss

http://github.com/yinwang0/ydiff
Scheme | 873 lines | 503 code | 277 blank | 93 comment | 0 complexity | 8b3fdadce0c129b47e460caa6744216b 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. "^" "|" "&" "~"
  27. ))
  28. (define *line-comment* (list "//"))
  29. (define *comment-start* "/*")
  30. (define *comment-end* "*/")
  31. (define *quotation-marks* '(#\" #\'))
  32. (define *significant-whitespaces*
  33. (list #\newline #\linefeed #\u2028 #\u2029))
  34. ;-------------------------------------------------------------
  35. ; parsers
  36. ;-------------------------------------------------------------
  37. ;; literals
  38. (:: $id
  39. ($pred
  40. (lambda (t)
  41. (and (Token? t)
  42. (id? (Token-text t))))))
  43. (::= $identifier 'identifier
  44. (@? ($$ "::"))
  45. (@* $id (@* $type-parameter) ($$ "::"))
  46. (@= 'id (@? ($$ "~")) $id))
  47. ;; (::= $identifier 'identifier
  48. ;; (@? ($$ "::")) $scope-resolution (@? ($$ "~")) $id)
  49. (:: $numeral-literal
  50. ($pred
  51. (lambda (t)
  52. (and (Token? t)
  53. (numeral? (Token-text t))))))
  54. (:: $char-literal ($pred Char?))
  55. (:: $string-literal ($pred Str?))
  56. (:: $newline ($pred Newline?))
  57. (:: $comment ($pred Comment?))
  58. ;; delimeters
  59. (:: |,| (@_ ","))
  60. (:: |;| (@~ ";"))
  61. (:: |:| (@_ ":"))
  62. (:: |(| (@~ "("))
  63. (:: |)| (@~ ")"))
  64. (:: |[| (@~ "["))
  65. (:: |]| (@~ "]"))
  66. (:: |{| (@~ "{"))
  67. (:: |}| (@~ "}"))
  68. (:: |\n| ($glob^ (@*^ $newline)))
  69. (:: |;\n| (@or |;| |\n|))
  70. (define old-seq @seq)
  71. (define @seq
  72. (lambda ps
  73. (let ([psj (join ps |\n|)])
  74. (apply old-seq `(,|\n| ,@psj ,|\n|)))))
  75. ;; a hacky definition for macros
  76. ;; will fix later
  77. (::= $macro-defintion 'macro
  78. (@~ "#")
  79. (@*^ (old-seq (@*^ (@and (@!^ ($$ "\\")) (@!^ $newline))) ($$ "\\") (@*^ $newline)))
  80. (old-seq (@*^ (@!^ $newline)) ($glob^ $newline) ($glob^ (@*^ $newline)))
  81. )
  82. (:: $directive
  83. (@or ($$ "ifdef")
  84. ($$ "define")
  85. ($$ "undef")
  86. ($$ "endif")))
  87. ;;------------------ starting point -----------------
  88. (::= $program 'program
  89. (@* $statement)
  90. )
  91. (:: $statement
  92. (@or $macro-defintion
  93. $empty-statement
  94. $access-label
  95. $statement-block
  96. $if-statement
  97. $switch-statement
  98. $do-while-statement
  99. $while-statement
  100. $for-statement
  101. $continue-statement
  102. $break-statement
  103. $return-statement
  104. $labelled-statement
  105. $try-statement
  106. $namespace-definition
  107. $using-namespace
  108. $class-definition
  109. $function-definition
  110. $function-declaration
  111. $variable-definition
  112. $enum-declaration
  113. $extended-assembly
  114. $inline-assembly
  115. $expression-statement
  116. ))
  117. (:: $empty-statement |;|)
  118. (::= $enum-declaration 'enum
  119. (@~ "enum") (@? $identifier)
  120. |{|
  121. (@? (@.@ (@= 'name-value $identifier (@? $initializer)) |,|))
  122. |}|
  123. |;|
  124. )
  125. (::= $access-label 'access-label
  126. $access-specifier (@~ ":"))
  127. (::= $statement-block 'block
  128. |{| (@* $statement) |}|
  129. )
  130. (::= $namespace-definition 'namespace
  131. ($$ "namespace") $identifier
  132. |{| (@* $statement) |}|
  133. )
  134. (::= $using-namespace 'using-namespace
  135. ($$ "using") ($$ "namespace") $identifier)
  136. ;;--------------------------------------------
  137. (::= $class-definition 'class
  138. (@or ($$ "class")
  139. ($$ "struct")
  140. ($$ "union"))
  141. (@* (@= 'declspec
  142. (@or ($$ "_declspec") ($$ "__declspec")) |(| $expression |)|))
  143. (@or (@= 'name $identifier |;| )
  144. (@...
  145. (@= 'name (@? $identifier)) (@? (@... (@_ ":") $base-clause))
  146. (@= 'body |{| (@* $statement) |}|) )
  147. ))
  148. (::= $base-clause 'bases
  149. (@.@ $base-specifier |,|)
  150. )
  151. (::= $base-specifier 'base-specifier
  152. (@? $access-specifier) $identifier)
  153. (::= $access-specifier 'access-specifier
  154. (@or ($$ "public")
  155. ($$ "protected")
  156. ($$ "private")
  157. ($$ "virtual")))
  158. ;;---------- function definition and declaration ------------
  159. (::= $function-declaration 'function-declaration
  160. (@? ($$ "typedef"))
  161. (@? $access-specifier) (@? $modifiers) (@? $type)
  162. (@= 'name (@or $identifier
  163. (@... |(| ($$ "*") $identifier |)|)) )
  164. $formal-parameter-list
  165. (@? ($$ "const"))
  166. (@? $initializer)
  167. )
  168. (::= $function-definition 'function
  169. (@or (@... (@? $modifiers) $type
  170. (@= 'name $identifier ) $formal-parameter-list)
  171. (@... (@= 'name $identifier ) $formal-parameter-list))
  172. (@? $initializer)
  173. $function-body)
  174. (::= $type 'type
  175. (@? $modifiers) (@or $primitive-type
  176. $ctype
  177. $identifier)
  178. (@* $type-parameter) (@* $ptr-suffix))
  179. (::= $type-parameter 'type-parameter
  180. (@~ "<") (@.@ (@or $type $numeral-literal) |,|) (@~ ">"))
  181. (::= $ptr-suffix 'suffix
  182. (@or ($$ "*")
  183. ($$ "&")))
  184. (::= $formal-parameter-list 'parameters
  185. |(| (@? (@.@ $type-variable |,|)) (@? |,| ($$ "...")) |)|
  186. )
  187. (::= $type-variable 'type-variable
  188. (@? $modifiers) $type (@? $identifier) (@? $array-suffix))
  189. (::= $function-body 'body
  190. |{| (@* $statement) |}|
  191. )
  192. (::= $variable-definition 'variable-definition
  193. $variable-declaration-list |;|
  194. )
  195. (:: $variable-declaration-list
  196. (@... (@? $modifiers) $type (@.@ $variable-declaration |,|)))
  197. (::= $variable-declaration 'variable-declaration
  198. $identifier (@? $variable-declaration-suffix)
  199. (@? $initializer))
  200. (::= $modifiers 'modifiers
  201. (@+ (@or ($$ "const")
  202. ($$ "static")
  203. ($$ "inline"))))
  204. (:: $primitive-type
  205. (@or (@...
  206. (@or ($$ "signed")
  207. ($$ "unsigned"))
  208. (@or ($$ "int")
  209. ($$ "char")
  210. ($$ "long")
  211. ($$ "double")
  212. ($$ "float")))
  213. (@or ($$ "signed")
  214. ($$ "unsigned"))))
  215. (::= $ctype 'ctype
  216. (@or ($$ "struct")
  217. ($$ "enum"))
  218. $identifier
  219. )
  220. (::= $variable-declaration-suffix 'suffix
  221. (@or (@... |[| $expression |]|))
  222. )
  223. (::= $initializer 'initializer
  224. (@or (@... (@_ "=") $expression)
  225. (@... (@_ ":") $expression)
  226. (@... (@_ "(") $expression (@_ ")"))))
  227. (::= $if-statement 'if
  228. ($$ "if") (@= 'test |(| $expression |)|) $statement
  229. (@? (@= 'else ($$ "else") $statement))
  230. )
  231. (::= $do-while-statement 'do-while
  232. ($$ "do") $statement
  233. (@= 'while-do ($$ "while") (@= 'test |(| $expression |)| ))
  234. |;|
  235. )
  236. (::= $while-statement 'while
  237. ($$ "while") (@= 'test |(| $expression |)| )
  238. $statement
  239. )
  240. (::= $for-statement 'for
  241. ($$ "for") (@= 'iter
  242. |(| (@? $for-initaliser) |;|
  243. (@? $expression) |;|
  244. (@? $expression)
  245. |)|
  246. )
  247. $statement
  248. )
  249. (::= $for-initaliser 'for-initializer
  250. (@or (@= 'variable-declaration
  251. $variable-declaration-list)
  252. $expression
  253. ))
  254. (::= $continue-statement 'continue
  255. ($$ "continue") (@= 'label (@? $identifier)) |;|
  256. )
  257. (::= $break-statement 'break
  258. ($$ "break") (@= 'label (@? $identifier)) |;|
  259. )
  260. (::= $return-statement 'return
  261. ($$ "return") (@= 'value (@? $expression)) |;|
  262. )
  263. (::= $labelled-statement 'labelled-statement
  264. $identifier |:| $statement
  265. )
  266. (::= $switch-statement 'switch
  267. ($$ "switch") |(| $expression |)|
  268. |{| (@* $case-clause)
  269. (@? (@... $default-clause
  270. (@* $case-clause)))
  271. |}|
  272. )
  273. (::= $case-clause 'case-clause
  274. ($$ "case") $expression |:| (@* $statement)
  275. )
  276. (::= $default-clause 'default-clause
  277. ($$ "default") |:| (@* $statement)
  278. )
  279. ;; throw is an expression in C++
  280. ;; (::= $throw-statement 'throw
  281. ;; ($$ "throw") $expression |;|
  282. ;; )
  283. (::= $try-statement 'try
  284. ($$ "try") $statement-block
  285. (@or $finally-clause
  286. (@... $catch-clause (@? $finally-clause))))
  287. (::= $catch-clause 'catch
  288. ($$ "catch") |(| $identifier |)| $statement-block)
  289. (::= $finally-clause 'finally
  290. ($$ "finally") $statement-block)
  291. (::= $expression-statement 'expression-statement
  292. $expression |;|)
  293. ;-------------------------------------------------------------
  294. ; expressions
  295. ;-------------------------------------------------------------
  296. ;; utility for constructing operators
  297. (define op
  298. (lambda (s)
  299. (@= 'op ($$ s))))
  300. (:: $expression
  301. $comma-expression
  302. )
  303. ;; 18. comma
  304. ;;--------------------------------------------
  305. (::= $comma-expression 'comma
  306. (@.@ $assignment-expression |,|))
  307. ;; 17. throw
  308. ;;--------------------------------------------
  309. (::= $throw-expression 'throw
  310. (@or (@... (@~ "throw")) $expression
  311. $assignment-expression)
  312. )
  313. ;; 16. assignment
  314. ;;--------------------------------------------
  315. (:: $assignment-expression
  316. (@or (@= 'assignment
  317. $conditional-expression
  318. $assignment-operator
  319. $assignment-expression)
  320. $conditional-expression
  321. ))
  322. (:: $assignment-operator
  323. (@or (op "=")
  324. (op "*=")
  325. (op "/=")
  326. (op "%=")
  327. (op "+=")
  328. (op "-=")
  329. (op "<<=")
  330. (op ">>=")
  331. (op ">>>=")
  332. (op "&=")
  333. (op "^=")
  334. (op "|=")))
  335. ;; 15. ?: Ternary conditional
  336. ;;--------------------------------------------
  337. (:: $conditional-expression
  338. (@or (@= 'conditional-expression
  339. (@= 'test $logical-or-expression)
  340. (@~ "?") (@= 'then $conditional-expression)
  341. (@~ ":") (@= 'else $conditional-expression))
  342. $logical-or-expression
  343. ))
  344. ; ($eval $conditional-expression (scan "x > 0? x-1 : x"))
  345. ;; 14. || Logical OR
  346. ;;--------------------------------------------
  347. (:: $logical-or-expression
  348. (@or (@infix-left 'binop
  349. $logical-and-expression
  350. (op "||"))
  351. $logical-and-expression
  352. ))
  353. ;; 13. && Logical AND
  354. ;;--------------------------------------------
  355. (:: $logical-and-expression
  356. (@or (@infix-left 'binop
  357. $bitwise-or-expression
  358. (op "&&"))
  359. $bitwise-or-expression
  360. ))
  361. ;; 12. | Bitwise OR (inclusive or)
  362. ;;--------------------------------------------
  363. (:: $bitwise-or-expression
  364. (@or (@infix-left 'binop
  365. $bitwise-xor-expression
  366. (op "|"))
  367. $bitwise-xor-expression
  368. ))
  369. ;; 11. ^ Bitwise XOR (exclusive or)
  370. ;;--------------------------------------------
  371. (:: $bitwise-xor-expression
  372. (@or (@infix-left 'binop
  373. $bitwise-and-expression
  374. (op "^"))
  375. $bitwise-and-expression
  376. ))
  377. ;; 10. & Bitwise AND
  378. ;;--------------------------------------------
  379. (:: $bitwise-and-expression
  380. (@or (@infix-left 'binop
  381. $equality-expression
  382. (op "&"))
  383. $equality-expression
  384. ))
  385. ;; 9. equality
  386. ;;--------------------------------------------
  387. (:: $equality-expression
  388. (@or (@infix-left 'binop
  389. $relational-expression
  390. $equality-operator)
  391. $relational-expression
  392. ))
  393. (:: $equality-operator
  394. (@or (op "==")
  395. (op "!=")
  396. (op "===")
  397. (op "!==")
  398. ))
  399. ;; 8. relational
  400. ;;--------------------------------------------
  401. (:: $relational-expression
  402. (@or (@infix-left 'binop
  403. $bitwise-shift-expression
  404. $relational-operator)
  405. $bitwise-shift-expression
  406. ))
  407. (:: $relational-operator
  408. (@or (op "<")
  409. (op "<=")
  410. (op ">")
  411. (op ">=")
  412. (op "instanceof")
  413. (op "in")
  414. ))
  415. ;; 7. bitwise shift
  416. ;;--------------------------------------------
  417. (:: $bitwise-shift-expression
  418. (@or (@infix-left 'binop
  419. $additive-expression
  420. $bitwise-shift-operator)
  421. $additive-expression
  422. ))
  423. (:: $bitwise-shift-operator
  424. (@or (op "<<")
  425. (op ">>")
  426. (op ">>>")
  427. ))
  428. ;; 6. additive
  429. ;;--------------------------------------------
  430. (:: $additive-expression
  431. (@or (@infix-left 'binop
  432. $multiplicative-expression
  433. $additive-operator)
  434. $multiplicative-expression
  435. ))
  436. (:: $additive-operator
  437. (@or (op "+")
  438. (op "-")))
  439. ;; ($eval $additive-expression (scan "x + y + z"))
  440. ;; 5. multiplicative
  441. ;;--------------------------------------------
  442. (:: $multiplicative-expression
  443. (@or (@infix-left 'binop
  444. $unary-expression
  445. $multiplicative-operator)
  446. $unary-expression))
  447. (:: $multiplicative-operator
  448. (@or (op "*")
  449. (op "/")
  450. (op "%")))
  451. ;; unary =
  452. ;; 3. prefix
  453. ;; 2. postfix
  454. ;;--------------------------------------------
  455. (:: $unary-expression
  456. $prefix-expression)
  457. ;; 3. prefix
  458. ;;--------------------------------------------
  459. (:: $prefix-expression
  460. (@or (@prefix 'prefix
  461. $postfix-expression
  462. $prefix-operator)
  463. $postfix-expression))
  464. (:: $prefix-operator
  465. (@or (@= 'new (op "new") (@? $array-suffix))
  466. (@= 'delete (op "delete") (@? $array-suffix))
  467. (@= 'cast |(| $type |)| )
  468. (op "void")
  469. (op "sizeof")
  470. (op "++")
  471. (op "--")
  472. (op "+")
  473. (op "-")
  474. (op "~")
  475. (op "!")
  476. (op "*") ; indirection
  477. (op "&") ; address of
  478. (op "::")
  479. ))
  480. (::= $array-suffix 'array-suffix
  481. |[| |]|)
  482. ;; 2. postfix
  483. ;;--------------------------------------------
  484. (:: $postfix-expression
  485. (@or (@postfix 'postfix
  486. $primary-expression
  487. $postfix-operator)
  488. $primary-expression))
  489. (:: $postfix-operator
  490. (@or (op "++")
  491. (op "--")
  492. $index-suffix
  493. $property-reference-suffix
  494. $type-parameter
  495. $arguments))
  496. (::= $arguments 'argument
  497. |(| (@? (@.@ $expression |,|)) |)|
  498. )
  499. (::= $index-suffix 'index
  500. |[| $expression |]|
  501. )
  502. (::= $property-reference-suffix 'field-access
  503. (@or (@~ ".") (@~ "->")) $identifier)
  504. ;; scope resolution ::
  505. ;---------------------------------------------
  506. (:: $scope-resolution
  507. (@or (@infix-left 'scope
  508. $id
  509. ($$ "::"))
  510. $primary-expression
  511. ))
  512. ;; 1. primary
  513. ;;--------------------------------------------
  514. (:: $primary-expression
  515. (@or (@= 'this ($$ "this"))
  516. $type-cast
  517. $ctype ; could be used in a macro argument
  518. $identifier
  519. $literal
  520. $array-literal
  521. $object-literal
  522. (@= #f |(| $expression |)|)
  523. ))
  524. (::= $type-cast 'type-cast
  525. (@or ($$ "typeid")
  526. ($$ "const_cast")
  527. ($$ "dynamic_cast")
  528. ($$ "reinterpret_cast")
  529. ($$ "static_cast")))
  530. ;; literal
  531. ;;--------------------------------------------
  532. (:: $literal
  533. (@or ($$ "null")
  534. ($$ "true")
  535. ($$ "false")
  536. $string-concat
  537. $float-literal
  538. $numeral-literal
  539. $string-literal
  540. $char-literal))
  541. (::= $array-literal 'array-literal
  542. |{| (@? (@.@ $expression |,|)) |}|
  543. )
  544. (::= $object-literal 'object-literal
  545. |{| $property-name-value (@* (@... |,| $property-name-value)) |}|
  546. )
  547. (::= $property-name-value 'property-name-value
  548. $property-name |:| $assignment-expression)
  549. (:: $property-name
  550. (@or $identifier
  551. $string-literal
  552. $numeral-literal))
  553. (::= $float-literal 'float-literal
  554. $numeral-literal ($$ ".") $numeral-literal)
  555. (::= $string-concat 'string-concat
  556. $string-literal (@* (@or $string-literal $expression)))
  557. ;-------------------------------------------------------------
  558. ; inline assembly
  559. ;-------------------------------------------------------------
  560. (::= $inline-assembly 'inline-assembly
  561. (@or (@~ "asm")
  562. (@~ "__asm__"))
  563. (@? (@or ($$ "volatile")
  564. ($$ "__volatile__")))
  565. |(| $string-concat |)|
  566. |;|
  567. )
  568. (::= $extended-assembly 'extended-assembly
  569. (@or (@~ "asm")
  570. (@~ "__asm__"))
  571. (@? (@or ($$ "volatile")
  572. ($$ "__volatile__")))
  573. |(| $string-concat
  574. |:| (@= 'output-operands (@* $string-literal |(| $identifier |)| ))
  575. |:| (@= 'input-operands (@* $string-literal |(| $identifier |)| ))
  576. |:| (@= 'clobbered-registers (@? (@.@ $string-literal |,|)))
  577. |)|
  578. |;|
  579. )
  580. (define parse-cpp
  581. (lambda (s)
  582. (first-val
  583. ($eval $program
  584. (filter (lambda (x) (not (Comment? x)))
  585. (scan s))))))
  586. ;-------------------------------------------------------------
  587. ; tests
  588. ;-------------------------------------------------------------
  589. ;; (test-file "tests/simulator-arm.cc"
  590. ;; "tests/simulator-mips.cc"
  591. ;; "tests/d8-3404.cc"
  592. ;; "tests/d8-8424.cc"
  593. ;; "tests/assembler-arm-2.cc"
  594. ;; "tests/assembler-arm-7.cc"
  595. ;; "tests/assembler-arm-8309.cc"
  596. ;; )