Emacs/cc-ide: More flexible ccide-all-includes implementation
[emacsstuff.git] / cc-ide / cc-parse.el
diff --git a/cc-ide/cc-parse.el b/cc-ide/cc-parse.el
new file mode 100644 (file)
index 0000000..529eb56
--- /dev/null
@@ -0,0 +1,135 @@
+;;; cc-parse.el --- Generator for recursive-descent parsers
+;;
+;; Copyright (C) 2007 Stefan Bund
+
+;; cc-parse.el is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; cc-parse.el is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; This is a very rudimentary parser to parse a single C++ argument
+;; declaration. The goal of this parser is, given an argument
+;; declaration find the name of the argument and the position of that
+;; name within the declaration.
+;;
+;; The current version does not support string- or charachter literals
+;; and comments within an argument declaration.
+
+;;;; Code:
+
+(require 'recdesc)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun cc-parse-arg (arg)
+  ;; Returns a cons ( POSITION . NAME ) where POSITION is the position
+  ;; of the argument in ARG and NAME is the name of that
+  ;; argument. Will return 'nil, if the argument name is omitted in
+  ;; the declaration.
+  (recdesc-scan-string 'decl arg))
+
+(recdesc-declare
+
+ (term optional-whitespace ()
+   (match "[ \t\n\r]*"))
+
+ (term word ()
+   (match optional-whitespace)
+   (collect (match "\\w+\\b"))
+   (return (cons (- position (length (car elements)))
+                (car elements))))
+
+ (term symbol ()
+   (match optional-whitespace)
+   (match word)
+   (maybe (repeat (match optional-whitespace)
+                 (match "::")
+                 (match optional-whitespace)
+                 (match word)))
+   (match optional-whitespace)
+   (maybe (match "<")
+         (match tokens)
+         (match optional-whitespace)
+         (match ">")))
+
+ (term tokens ()
+   (match optional-whitespace)
+   (or (and (match "(") (commit) (match tokens) (match ")"))
+       (and (match "\\[") (commit) (match tokens) (match "\\]"))
+       (and (match "{") (commit) (match tokens) (match "}"))
+       (and (match "<") (commit) (match tokens) (match ">"))
+       (match "[^][(){}<>]*")))
+ (term decl ()
+   (match optional-whitespace)
+   (collect (or (match primary)
+               (match group)
+               (match member-pointer)
+               (match modifier)
+               (match word)))
+   (maybe (match arglist))
+   (maybe (repeat (match array)))
+   (match optional-whitespace)
+   (return (car elements)))
+
+ (term primary ()
+   (match optional-whitespace)
+   (match symbol)
+   (match optional-whitespace)
+   (collect (match decl))
+   (return (car elements)))
+
+ (term group ()
+   (match optional-whitespace)
+   (match "(")
+   (collect (match decl))
+   (match optional-whitespace)
+   (match ")")
+   (return (car elements)))
+
+ (term member-pointer ()
+   (match optional-whitespace)
+   (match symbol) 
+   (match optional-whitespace) 
+   (match "::")
+   (match optional-whitespace)
+   (match "*")
+   (commit)
+   (match decl))
+
+ (term modifier ()
+   (match optional-whitespace)
+   (match "const\\|volatile\\|\\*\\|&")
+   (commit)
+   (collect (match decl))
+   (return (car elements)))
+ (term array ()
+   (match optional-whitespace)
+   (match "\\[")
+   (commit)
+   (match tokens)
+   (match optional-whitespace)
+   (match "\\]")
+   (return (car elements)))
+ (term arglist ()
+   (match optional-whitespace)
+   (match "(")
+   (commit)
+   (match tokens)
+   (match optional-whitespace)
+   (match ")")))
+
+;; To debug a term, place the name of the term's function into 'fn',
+;; place the curor at the end of the line and presse C-x C-e. You may
+;; then use 'edebug-defun' on the declaration produced by this.
+;;
+;; (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))) 
+
+(provide cc-parse)