add keybinding (C-c ; f f) for ccide-format-buffer
[emacsstuff.git] / cc-ide / cc-parse.el
1 ;;; cc-parse.el --- Generator for recursive-descent parsers
2 ;;
3 ;; Copyright (C) 2007 Stefan Bund
4
5 ;; cc-parse.el is free software; you can redistribute it and/or
6 ;; modify it under the terms of the GNU General Public License as
7 ;; published by the Free Software Foundation; either version 2, or (at
8 ;; your option) any later version.
9
10 ;; cc-parse.el is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ;; General Public License for more details.
14
15 ;; This is a very rudimentary parser to parse a single C++ argument
16 ;; declaration. The goal of this parser is, given an argument
17 ;; declaration find the name of the argument and the position of that
18 ;; name within the declaration.
19 ;;
20 ;; The current version does not support string- or charachter literals
21 ;; and comments within an argument declaration.
22
23 ;;;; Code:
24
25 (require 'recdesc)
26
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28
29 (defun cc-parse-arg (arg)
30   ;; Returns a cons ( POSITION . NAME ) where POSITION is the position
31   ;; of the argument in ARG and NAME is the name of that
32   ;; argument. Will return 'nil, if the argument name is omitted in
33   ;; the declaration.
34   (recdesc-scan-string 'decl arg))
35
36 (recdesc-declare
37
38  (term optional-whitespace ()
39    (match "[ \t\n\r]*"))
40
41  (term word ()
42    (match optional-whitespace)
43    (collect (match "\\w+\\b"))
44    (return (cons (- position (length (car elements)))
45                  (car elements))))
46
47  (term symbol ()
48    (match optional-whitespace)
49    (match word)
50    (maybe (repeat (match optional-whitespace)
51                   (match "::")
52                   (match optional-whitespace)
53                   (match word)))
54    (match optional-whitespace)
55    (maybe (match "<")
56           (match tokens)
57           (match optional-whitespace)
58           (match ">")))
59
60  (term tokens ()
61    (match optional-whitespace)
62    (or (and (match "(") (commit) (match tokens) (match ")"))
63        (and (match "\\[") (commit) (match tokens) (match "\\]"))
64        (and (match "{") (commit) (match tokens) (match "}"))
65        (and (match "<") (commit) (match tokens) (match ">"))
66        (match "[^][(){}<>]*")))
67  
68  (term decl ()
69    (match optional-whitespace)
70    (collect (or (match primary)
71                 (match group)
72                 (match member-pointer)
73                 (match modifier)
74                 (match word)))
75    (maybe (match arglist))
76    (maybe (repeat (match array)))
77    (match optional-whitespace)
78    (return (car elements)))
79
80  (term primary ()
81    (match optional-whitespace)
82    (match symbol)
83    (match optional-whitespace)
84    (collect (match decl))
85    (return (car elements)))
86
87  (term group ()
88    (match optional-whitespace)
89    (match "(")
90    (collect (match decl))
91    (match optional-whitespace)
92    (match ")")
93    (return (car elements)))
94
95  (term member-pointer ()
96    (match optional-whitespace)
97    (match symbol) 
98    (match optional-whitespace) 
99    (match "::")
100    (match optional-whitespace)
101    (match "*")
102    (commit)
103    (match decl))
104
105  (term modifier ()
106    (match optional-whitespace)
107    (match "const\\|volatile\\|\\*\\|&")
108    (commit)
109    (collect (match decl))
110    (return (car elements)))
111  
112  (term array ()
113    (match optional-whitespace)
114    (match "\\[")
115    (commit)
116    (match tokens)
117    (match optional-whitespace)
118    (match "\\]")
119    (return (car elements)))
120  
121  (term arglist ()
122    (match optional-whitespace)
123    (match "(")
124    (commit)
125    (match tokens)
126    (match optional-whitespace)
127    (match ")")))
128
129 ;; To debug a term, place the name of the term's function into 'fn',
130 ;; place the curor at the end of the line and presse C-x C-e. You may
131 ;; then use 'edebug-defun' on the declaration produced by this.
132 ;;
133 ;; (let ((fn 'recdesc@@decl)) (save-excursion (insert (prin1-to-string (symbol-function fn)))) (insert "\n\n") (forward-char 1) (delete-char 6) (insert "defun " (symbol-name fn)) (forward-sexp) (insert "\n") (let ((start (point))) (forward-line 1) (replace-string ")" ")\n" nil start (point)) (indent-region (save-excursion (goto-char start) (forward-line -1) (point)) (point) nil))) 
134
135 (provide cc-parse)