-;;; ebnf-yac --- Parser for Yacc/Bison
+;;; ebnf-yac.el --- parser for Yacc/Bison
-;; Copyright (C) 1999 Vinicius Jose Latorre
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; Free Software Foundation, Inc.
-;; Author: Vinicius Jose Latorre <vinicius@cpqd.com.br>
-;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
-;; Keywords: wp, ebnf, PostScript
-;; Time-stamp: <99/11/20 18:02:43 vinicius>
-;; Version: 1.0
+;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
+;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
+;; Keywords: wp, ebnf, PostScript
+;; Version: 1.4
-;; This file is *NOT* (yet?) part of GNU Emacs.
+;; This file is part of GNU Emacs.
-;; This program is free software; you can redistribute it and/or modify
+;; GNU Emacs 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)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
-;; This program is distributed in the hope that it will be useful,
+;; GNU Emacs 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.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; YACC = { YACC-Definitions }* "%%" { YACC-Rule }* [ "%%" [ YACC-Code ] ].
;;
-;; YACC-Definitions = "%token" [ "<" Name ">" ] Name-List
+;; YACC-Definitions = ( "%token" | "%left" | "%right" | "%nonassoc" )
+;; [ "<" Name ">" ] Name-List
+;; | "%prec" Name
;; | "any other Yacc definition"
;; .
;;
;; Name = "[A-Za-z][A-Za-z0-9_.]*".
;;
;; Comment = "/*" "any character, but the sequence \"*/\"" "*/"
-;; | "//" "any character" "\\n".
+;; | "//" "any character, but the newline \"\\n\"" "\\n".
+;;
+;;
+;; In other words, a valid Name begins with a letter (upper or lower case)
+;; followed by letters, decimal digits, underscore (_) or point (.). For
+;; example: this_is_a_valid.name, Another_EXAMPLE, mIxEd.CaSe.
+;;
+;;
+;; Acknowledgements
+;; ----------------
+;;
+;; Thanks to Matthew K. Junker <junker@alum.mit.edu> for the suggestion to deal
+;; with %right, %left and %prec pragmas. His suggestion was extended to deal
+;; with %nonassoc pragma too.
;;
;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; code:
+;;; Code:
(require 'ebnf-otz)
(defvar ebnf-yac-error nil
- "Non-nil means \"error\" occured.")
+ "Non-nil means \"error\" occurred.")
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Syntatic analyzer
+;; Syntactic analyzer
;;; YACC = { YACC-Definitions }* "%%" { YACC-Rule }* [ "%%" [ YACC-Code ] ].
(goto-char start)
(setq token (ebnf-yac-lex))
(and (eq token 'end-of-input)
- (error "Invalid Yacc/Bison file format."))
+ (error "Invalid Yacc/Bison file format"))
(or (eq (ebnf-yac-definitions token) 'yac-separator)
- (error "Missing `%%%%'."))
+ (error "Missing `%%%%'"))
(setq token (ebnf-yac-lex))
(while (not (memq token '(end-of-input yac-separator)))
(ebnf-message-float
syntax-list))
-;;; YACC-Definitions = "%token" [ "<" Name ">" ] Name-List
+;;; YACC-Definitions = ( "%token" | "%left" | "%right" | "%nonassoc" )
+;;; [ "<" Name ">" ] Name-List
+;;; | "%prec" Name
;;; | "any other Yacc definition"
;;; .
(while (not (memq token '(yac-separator end-of-input)))
(setq token
(cond
- ;; "%token" [ "<" Name ">" ] Name-List
+ ;; ( "%token" | "%left" | "%right" | "%nonassoc" )
+ ;; [ "<" Name ">" ] Name-List
((eq token 'yac-token)
(setq token (ebnf-yac-lex))
(when (eq token 'open-angle)
(or (eq (ebnf-yac-lex) 'non-terminal)
- (error "Missing type name."))
+ (error "Missing type name"))
(or (eq (ebnf-yac-lex) 'close-angle)
- (error "Missing `>'."))
+ (error "Missing `>'"))
(setq token (ebnf-yac-lex)))
(setq token (ebnf-yac-name-list token)
ebnf-yac-token-list (nconc (cdr token)
ebnf-yac-token-list))
(car token))
- ;; "any other Yacc definition"
+ ;; "%prec" Name
+ ((eq token 'yac-prec)
+ (or (eq (ebnf-yac-lex) 'non-terminal)
+ (error "Missing prec name"))
+ (ebnf-yac-lex))
+ ;; "any other Yacc definition"
(t
(ebnf-yac-lex))
)))
body)
(setq ebnf-action nil)
(or (eq token 'non-terminal)
- (error "Invalid rule name."))
+ (error "Invalid rule name"))
(or (eq (ebnf-yac-lex) 'colon)
- (error "Invalid rule: missing `:'."))
+ (error "Invalid rule: missing `:'"))
(setq body (ebnf-yac-alternative))
(or (eq (car body) 'period)
- (error "Invalid rule: missing `;'."))
+ (error "Invalid rule: missing `;'"))
(setq body (cdr body))
(ebnf-eps-add-production header)
(cons (ebnf-yac-lex)
factor (ebnf-yac-factor token))
(setq seq (cons factor seq)))
(cons token
- (cond
- ;; ignore error recovery
- ((and ebnf-yac-ignore-error-recovery ebnf-yac-error)
- nil)
- ;; null sequence
- ((null seq)
- (ebnf-make-empty))
- ;; sequence with only one element
- ((= (length seq) 1)
- (car seq))
- ;; a real sequence
- (t
- (ebnf-make-sequence (nreverse seq)))
- ))))
+ (if (and ebnf-yac-ignore-error-recovery ebnf-yac-error)
+ ;; ignore error recovery
+ nil
+ (ebnf-token-sequence seq)))))
;;; Factor = Name
token (ebnf-yac-lex))
(eq token 'comma))
(or (eq (ebnf-yac-lex) 'non-terminal)
- (error "Missing token name."))))
+ (error "Missing token name"))))
(cons token names)))
\f
(defun ebnf-yac-lex ()
- "Lexical analyser for Yacc/Bison.
+ "Lexical analyzer for Yacc/Bison.
Return a lexical token.
'end-of-input)
;; error
((eq token 'error)
- (error "Illegal character."))
+ (error "Invalid character"))
;; "string"
((eq token 'string)
(setq ebnf-yac-lex (ebnf-get-string))
((eq (following-char) ?%)
(forward-char)
'yac-separator)
- ;; %TOKEN
- ((string= (upcase (ebnf-buffer-substring "0-9A-Za-z_")) "TOKEN")
- 'yac-token)
+ ;; %TOKEN, %RIGHT, %LEFT, %PREC, %NONASSOC
+ ((cdr (assoc (upcase (ebnf-buffer-substring "0-9A-Za-z_"))
+ '(("TOKEN" . yac-token)
+ ("RIGHT" . yac-token)
+ ("LEFT" . yac-token)
+ ("NONASSOC" . yac-token)
+ ("PREC" . yac-prec)))))
;; other Yacc pragmas
(t
'yac-pragma)
(< (point) ebnf-limit))
+;; replace the range "\177-\377" (see `ebnf-range-regexp').
+(defconst ebnf-yac-skip-chars
+ (ebnf-range-regexp "^{}/'\"\000-\010\013\016-\037" ?\177 ?\377))
+
+
(defun ebnf-yac-skip-code ()
(forward-char)
(let ((pair 1))
(while (> pair 0)
- (skip-chars-forward "^{}/'\"\000-\010\013\016-\037\177-\377" ebnf-limit)
+ (skip-chars-forward ebnf-yac-skip-chars ebnf-limit)
(cond
((= (following-char) ?{)
(forward-char)
((= (following-char) ?\')
(ebnf-string " -&(-~" ?\' "character"))
(t
- (error "Illegal character."))
+ (error "Invalid character"))
)))
(ebnf-yac-skip-spaces))
))
-(defconst ebnf-yac-comment-chars "^*\000-\010\013\016-\037\177-\237")
+;; replace the range "\177-\237" (see `ebnf-range-regexp').
+(defconst ebnf-yac-comment-chars
+ (ebnf-range-regexp "^*\000-\010\013\016-\037" ?\177 ?\237))
(defun ebnf-yac-skip-comment ()
;; close EPS file
((and ebnf-eps-executing (= (following-char) ?\]))
(ebnf-eps-remove-context (ebnf-yac-eps-filename)))
+ ;; EPS header
+ ((and ebnf-eps-executing (= (following-char) ?H))
+ (ebnf-eps-header-comment (ebnf-yac-eps-filename)))
+ ;; EPS footer
+ ((and ebnf-eps-executing (= (following-char) ?F))
+ (ebnf-eps-footer-comment (ebnf-yac-eps-filename)))
;; any other action in comment
(t
(setq ebnf-action (aref ebnf-comment-table (following-char))))
(while not-end
(skip-chars-forward ebnf-yac-comment-chars ebnf-limit)
(cond ((>= (point) ebnf-limit)
- (error "Missing end of comment: `*/'."))
+ (error "Missing end of comment: `*/'"))
((= (following-char) ?*)
(skip-chars-forward "*" ebnf-limit)
(when (= (following-char) ?/)
(forward-char)
(setq not-end nil)))
(t
- (error "Illegal character."))
+ (error "Invalid character"))
))))
(provide 'ebnf-yac)
+;;; arch-tag: 8a96989c-0b1d-42ba-a020-b2901f9a2a4d
;;; ebnf-yac.el ends here