X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/984ae001715c945ef1e81fba2d80607f486332f2..f4ff3e5cc0e873be609cf6172386c56587a83f31:/lisp/progmodes/ebnf-yac.el diff --git a/lisp/progmodes/ebnf-yac.el b/lisp/progmodes/ebnf-yac.el index bbe135e45e..c1b00bdddf 100644 --- a/lisp/progmodes/ebnf-yac.el +++ b/lisp/progmodes/ebnf-yac.el @@ -1,29 +1,29 @@ -;;; 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 -;; Maintainer: Vinicius Jose Latorre -;; Keywords: wp, ebnf, PostScript -;; Time-stamp: <99/11/20 18:02:43 vinicius> -;; Version: 1.0 +;; Author: Vinicius Jose Latorre +;; Maintainer: Vinicius Jose Latorre +;; 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: @@ -42,7 +42,9 @@ ;; ;; 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" ;; . ;; @@ -65,12 +67,25 @@ ;; 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 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) @@ -89,11 +104,11 @@ (defvar ebnf-yac-error nil - "Non-nil means \"error\" occured.") + "Non-nil means \"error\" occurred.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Syntatic analyzer +;; Syntactic analyzer ;;; YACC = { YACC-Definitions }* "%%" { YACC-Rule }* [ "%%" [ YACC-Code ] ]. @@ -109,9 +124,9 @@ (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 @@ -126,7 +141,9 @@ syntax-list)) -;;; YACC-Definitions = "%token" [ "<" Name ">" ] Name-List +;;; YACC-Definitions = ( "%token" | "%left" | "%right" | "%nonassoc" ) +;;; [ "<" Name ">" ] Name-List +;;; | "%prec" Name ;;; | "any other Yacc definition" ;;; . @@ -135,20 +152,26 @@ (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)) ))) @@ -163,12 +186,12 @@ 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) @@ -194,20 +217,10 @@ 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 @@ -243,7 +256,7 @@ 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))) @@ -298,7 +311,7 @@ (defun ebnf-yac-lex () - "Lexical analyser for Yacc/Bison. + "Lexical analyzer for Yacc/Bison. Return a lexical token. @@ -332,7 +345,7 @@ See documentation for variable `ebnf-yac-lex'." 'end-of-input) ;; error ((eq token 'error) - (error "Illegal character.")) + (error "Invalid character")) ;; "string" ((eq token 'string) (setq ebnf-yac-lex (ebnf-get-string)) @@ -360,9 +373,13 @@ See documentation for variable `ebnf-yac-lex'." ((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) @@ -383,11 +400,16 @@ See documentation for variable `ebnf-yac-lex'." (< (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) @@ -402,7 +424,7 @@ See documentation for variable `ebnf-yac-lex'." ((= (following-char) ?\') (ebnf-string " -&(-~" ?\' "character")) (t - (error "Illegal character.")) + (error "Invalid character")) ))) (ebnf-yac-skip-spaces)) @@ -423,7 +445,9 @@ See documentation for variable `ebnf-yac-lex'." )) -(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 () @@ -435,6 +459,12 @@ See documentation for variable `ebnf-yac-lex'." ;; 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)))) @@ -443,7 +473,7 @@ See documentation for variable `ebnf-yac-lex'." (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) ?/) @@ -451,7 +481,7 @@ See documentation for variable `ebnf-yac-lex'." (forward-char) (setq not-end nil))) (t - (error "Illegal character.")) + (error "Invalid character")) )))) @@ -484,4 +514,5 @@ See documentation for variable `ebnf-yac-lex'." (provide 'ebnf-yac) +;;; arch-tag: 8a96989c-0b1d-42ba-a020-b2901f9a2a4d ;;; ebnf-yac.el ends here