java.scm
| 1 | ;;; GNU Guix --- Functional package management for GNU |
| 2 | ;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu> |
| 3 | ;;; |
| 4 | ;;; This file is part of GNU Guix. |
| 5 | ;;; |
| 6 | ;;; GNU Guix is free software; you can redistribute it and/or modify it |
| 7 | ;;; under the terms of the GNU General Public License as published by |
| 8 | ;;; the Free Software Foundation; either version 3 of the License, or (at |
| 9 | ;;; your option) any later version. |
| 10 | ;;; |
| 11 | ;;; GNU Guix is distributed in the hope that it will be useful, but |
| 12 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | ;;; GNU General Public License for more details. |
| 15 | ;;; |
| 16 | ;;; You should have received a copy of the GNU General Public License |
| 17 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. |
| 18 | |
| 19 | (define-module (more build maven java) |
| 20 | #:use-module (ice-9 peg) |
| 21 | #:use-module (ice-9 textual-ports) |
| 22 | #:export (parse-java-file)) |
| 23 | |
| 24 | (define-peg-pattern java-file body (and (* WS) (* (and top-level-statement |
| 25 | (* WS))))) |
| 26 | (define-peg-pattern WS none (or " " "\n" "\t" "\r")) |
| 27 | (define-peg-pattern top-level-statement body (or package import-pat class-pat comment)) |
| 28 | (define-peg-pattern package all (and (ignore "package") (* WS) package-name |
| 29 | (* WS) (ignore ";"))) |
| 30 | (define-peg-pattern import-pat all (and (ignore "import") (* WS) package-name |
| 31 | (* WS) (ignore ";"))) |
| 32 | (define-peg-pattern comment all (and (ignore "/*") |
| 33 | comment-part)) |
| 34 | (define-peg-pattern comment-part body (or (ignore (and (* "*") "/")) |
| 35 | (and (* "*") (+ comment-chr) comment-part))) |
| 36 | (define-peg-pattern comment-chr body (or "\t" "\n" (range #\ #\)) (range #\+ #\xffff))) |
| 37 | (define-peg-pattern package-name body (* (or (range #\a #\z) (range #\A #\Z) |
| 38 | (range #\0 #\9) "_" "."))) |
| 39 | (define-peg-pattern class-pat all (and (? (and annotation-pat (* WS))) |
| 40 | (? (and (ignore "public") (* WS))) (ignore "class") |
| 41 | (* WS) package-name (* WS) |
| 42 | (? extends) |
| 43 | (? implements) |
| 44 | (ignore "{") class-body (ignore "}"))) |
| 45 | (define-peg-pattern extends all (? (and (ignore "extends") (* WS) |
| 46 | package-name (* WS)))) |
| 47 | (define-peg-pattern implements all (? (and (ignore "implements") (* WS) |
| 48 | package-name (* WS)))) |
| 49 | (define-peg-pattern annotation-pat all (and (ignore "@") package-name |
| 50 | (? (and |
| 51 | (ignore "(") (* WS) |
| 52 | annotation-attr |
| 53 | (* (and (ignore ",") (* WS) annotation-attr)) |
| 54 | (ignore ")"))))) |
| 55 | (define-peg-pattern annotation-attr all (and attr-name (* WS) (ignore "=") |
| 56 | (* WS) attr-value (* WS))) |
| 57 | (define-peg-pattern attr-name all (* (or (range #\a #\z) (range #\A #\Z) (range #\0 #\9) |
| 58 | "_"))) |
| 59 | (define-peg-pattern attr-value all (or "true" "false" |
| 60 | (+ (or (range #\0 #\9) (range #\a #\z) |
| 61 | (range #\A #\Z) "." "_")) |
| 62 | string-pat)) |
| 63 | (define-peg-pattern string-pat body (and (ignore "\"") (* string-chr) (ignore "\""))) |
| 64 | (define-peg-pattern string-chr body (or " " "!" (and (ignore "\\") "\"") |
| 65 | (and (ignore "\\") "\\") (range #\# #\xffff))) |
| 66 | |
| 67 | (define-peg-pattern class-body all (and (* WS) (* (and class-statement (* WS))))) |
| 68 | (define-peg-pattern class-statement body (or comment param-pat method-pat)) |
| 69 | (define-peg-pattern param-pat all (and (? (and annotation-pat (* WS))) |
| 70 | (? (and (ignore (or "private" "public" "protected")) |
| 71 | (* WS))) |
| 72 | type-name (* WS) param-name |
| 73 | (? (and (* WS) (ignore "=") (* WS) (+ valuechr))) |
| 74 | (ignore ";"))) |
| 75 | (define-peg-pattern valuechr none (or string-pat comment "\n" "\t" "\r" |
| 76 | (range #\ #\:) (range #\< #\xffff))) |
| 77 | (define-peg-pattern param-name all (* (or (range #\a #\z) (range #\A #\Z) (range #\0 #\9) |
| 78 | "_"))) |
| 79 | (define-peg-pattern type-name all (* (or (range #\a #\z) (range #\A #\Z) (range #\0 #\9) |
| 80 | "_" "<" ">"))) |
| 81 | (define-peg-pattern method-pat all (and (? (and annotation-pat (* WS))) |
| 82 | (? (and (ignore (or "private" "public" "protected")) |
| 83 | (* WS))) |
| 84 | type-name (* WS) param-name (* WS) |
| 85 | (ignore "(") |
| 86 | param-list (ignore ")") (* WS) |
| 87 | (? (and (ignore "throws") (* WS) package-name (* WS) |
| 88 | (* (and (ignore ",") (* WS) package-name |
| 89 | (* WS))))) |
| 90 | (ignore "{") (* WS) (? (and method-statements (* WS))) |
| 91 | (ignore "}"))) |
| 92 | (define-peg-pattern param-list all (and (* WS) (* (and type-name (* WS) param-name (* WS) |
| 93 | (? (ignore ",")) (* WS))))) |
| 94 | (define-peg-pattern method-statements none (and (or (+ method-chr) |
| 95 | (and "{" method-statements "}") |
| 96 | string-pat) |
| 97 | (? method-statements))) |
| 98 | (define-peg-pattern method-chr none (or "\t" "\n" "\r" " " "!" (range #\# #\z) "|" |
| 99 | (range #\~ #\xffff))) |
| 100 | |
| 101 | |
| 102 | (define (parse-java-file file) |
| 103 | (peg:tree (match-pattern java-file (call-with-input-file file get-string-all)))) |
| 104 |