1 ;;; cc-parse.el --- Generator for recursive-descent parsers
3 ;; Copyright (C) 2007 Stefan Bund
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.
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.
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.
20 ;; The current version does not support string- or charachter literals
21 ;; and comments within an argument declaration.
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
34 (recdesc-scan-string 'decl arg))
38 (term optional-whitespace ()
42 (match optional-whitespace)
43 (collect (match "\\w+\\b"))
44 (return (cons (- position (length (car elements)))
48 (match optional-whitespace)
50 (maybe (repeat (match optional-whitespace)
52 (match optional-whitespace)
54 (match optional-whitespace)
57 (match optional-whitespace)
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 "[^][(){}<>]*")))
69 (match optional-whitespace)
70 (collect (or (match primary)
72 (match member-pointer)
75 (maybe (match arglist))
76 (maybe (repeat (match array)))
77 (match optional-whitespace)
78 (return (car elements)))
81 (match optional-whitespace)
83 (match optional-whitespace)
84 (collect (match decl))
85 (return (car elements)))
88 (match optional-whitespace)
90 (collect (match decl))
91 (match optional-whitespace)
93 (return (car elements)))
95 (term member-pointer ()
96 (match optional-whitespace)
98 (match optional-whitespace)
100 (match optional-whitespace)
106 (match optional-whitespace)
107 (match "const\\|volatile\\|\\*\\|&")
109 (collect (match decl))
110 (return (car elements)))
113 (match optional-whitespace)
117 (match optional-whitespace)
119 (return (car elements)))
122 (match optional-whitespace)
126 (match optional-whitespace)
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.
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)))