5

**** Stephan による問題 1 の解決策 - 以下の回答を参照してください****

構文テーブルでエスケープ文字としてマーク\しますが、 のような Mathematica 構文要素の指定をオーバーライドします\[Infinity]。これが私のものsyntax-propertize-functionです:

(defconst math-syntax-propertize-function
  (syntax-propertize-rules
   ("\\\\\\[\\([A-Z][A-Za-z]*\\)]" (0 "_"))))

(defun math-node()次のように関数から参照しました。

  (set (make-local-variable 'syntax-propertize-function)
       math-syntax-propertize-function)

最初の試みでは、関数を使用しなかったためmake-local-variable、elisp バッファーの強調表示がうまくいかなかったので驚きました。

****問題 1 の解決策を終了****

Mathematica ファイルを編集するために、cc-mode から派生した Emacs にメジャーモードを実装しています。目標は、構文の強調表示とインデントです。Mathematica カーネルとのインターフェースは後回しにします。

基本的な機能は動作していますが、問題を引き起こしている問題がいくつかあります。

****問題 1** -\文字はエスケープ文字として使用され、複数文字の括弧で囲まれたキーワードの前に付けられます。**

多くの言語と同様に、 Mathematica は\文字をエスケープ"に使用し、他の\文字は文字列です。

Mathematic では、Mathematica で呼び出されているものに、Mathematica の演算子や定数を表す 、 、 など\[Times]\[Element]構文文字を話します。\[Infinity]

また、Mathematica は、関数の定義や呼び出しなどに[andの]代わりに(andを多用します。)

そのため、構文テーブルでエスケープ文字としてマーク\すると、構文文字を使用する場所で括弧が不一致になります。例えば、

    If[x < \[Pi], True, False]

もちろん、cc-mode は . の[直後を無視するつもり\です。Mathematica の機能的性質を考えると、モードがブラケットに一致しない場合、モードはほとんど役に立ちません。括弧のマッチングなしでLispを考えてください。

構文テーブルにエスケープ文字を入れない場合\、コメントや文字列でエスケープ シーケンスを処理するにはどうすればよいですか?

Times、Element、Infinity などをキーワード リストに入れ、すべてが正しく動作するようにできれば素晴らしいと思います。

****問題 2** - Mathematica の構文は、C、C++、Java、ObjC などとは十分に異なっているため、cc-mode の組み込みの構文解析が常に望ましい結果を生成するとは限りません。**

次のコード ブロックを検討してください。

    FooBar[expression1,
           expression2,
           expression3];

式が引数リストとして認識されるため、これは美しくフォーマットされます。

ただし、リストが引数として渡される場合、

    FooBar[{expression1,
                expression2,
                expression3}];

{式はand内の単一ステートメントの継続と見なされるため、結果はきれいではありません}。残念ながら、次のような実際の継続c-continuation-offsetを中断するように設定するという単純なハックは、0

    addMe[x_Real, y_Real] :=
        Plus[x, y];

インデントしたいもの。

問題は、Mathematica{}delineate リストであり、コード ブロックではありません。

私が使用している現在のelispファイルは次のとおりです。

(require 'cc-mode)

;; There are required at compile time to get the sources for the                                
;; language constants.                                                                          
(eval-when-compile
  (require 'cc-langs)
  (require 'cc-fonts))

;; Add math mode the the language constant system. This needs to be                             
;; done at compile time because that is when the language constants                             
;; are evaluated.                                                                               
(eval-and-compile
  (c-add-language 'math-mode 'c-mode))


;; Function names                                                                               
(c-lang-defconst c-cpp-matchers
  math (append
        (c-lang-const c-cpp-matchers c)
        ;; Abc[                                                                                 
        '(("\\<\\([A-Z][A-Za-z0-9]*\\)\\>\\[" 1 font-lock-type-face))
        ;; abc[                                                                                 
        '(("\\<\\([A-Za-z][A-Za-z0-9]*\\)\\>\\[" 1 font-lock-function-name-face))
        ;; Abc                                                                                  
        '(("\\<\\([A-Z][A-Za-z0-9]*\\)\\>" 1 font-lock-keyword-face))
        ;; abc_                                                                                 
        '(("\\<\\([a-z][A-Za-z0-9]*[_]\\)\\>" 1 font-lock-variable-name-face))
        ))

;; font-lock-comment-face                                                                       
;; font-lock-doc-face                                                                           
;; font-lock-string-face                                                                        
;; font-lock-keyword-fact                                                                       
;; font-lock-function-name-face                                                                 
;; font-lock-constant-face                                                                      
;; font-lock-type-face                                                                          
;; font-lock-builtin-face                                                                       
;; font-lock-reference-face                                                                     
;; font-lock-warning-face                                                                       


;; There is no line comment character.                                                          
(c-lang-defconst c-line-comment-starter
  math nil)

;; The block comment starter is (*.                                                             
(c-lang-defconst c-block-comment-starter
  math "(*")

;; The block comment ender is *).                                                               
(c-lang-defconst c-block-comment-ender
  math "*)")

;; The assignment operators.                                                                    
(c-lang-defconst c-assignment-operators
  math '("=" ":=" "+=" "-=" "*=" "/=" "->" ":>"))

;; The operators.                                                                               
(c-lang-defconst c-operators
  math `(
         ;; Unary.                                                                              
         (prefix "+" "-" "!")
         ;; Multiplicative.                                                                     
         (left-assoc "*" "/")
         ;; Additive.                                                                           
         (left-assoc "+" "-")
         ;; Relational.                                                                         
         (left-assoc "<" ">" "<=" ">=")
         ;; Equality.                                                                           
         (left-assoc "==" "=!=")  
         ;; Assignment.                                                                         
         (right-assoc ,@(c-lang-const c-assignment-operators))
         ;; Sequence.                                                                           
         (left-assoc ",")))


;; Syntax modifications necessary to recognize keywords with                                    
;; punctuation characters.                                                                      
;; (c-lang-defconst c-identifier-syntax-modifications                                           
;;   math (append '((?\\ . "w"))                                                                
;;             (c-lang-const c-identifier-syntax-modifications)))                               

;; Constants.                                                                                   
(c-lang-defconst c-constant-kwds
  math '( "False" "True" )) ;; "\\[Infinity]" "\\[Times]" "\\[Divide]" "\\[Sqrt]" "\\[Element]"\
))                                                                                              

(defcustom math-font-lock-extra-types nil
  "Extra types to recognize in math mode.")

(defconst math-font-lock-keywords-1 (c-lang-const c-matchers-1 math)
  "Minimal highlighting for math mode.")

(defconst math-font-lock-keywords-2 (c-lang-const c-matchers-2 math)
  "Fast normal highlighting for math mode.")

(defconst math-font-lock-keywords-3 (c-lang-const c-matchers-3 math)
  "Accurate normal highlighting for math mode.")

(defvar math-font-lock-keywords math-font-lock-keywords-3
  "Default expressions to highlight in math mode.")

(defvar math-mode-syntax-table nil
  "Syntax table used in math mode.")

(message "Setting math-mode-syntax-table to nil to force re-initialization")
(setq math-mode-syntax-table nil)

;; If a syntax table has not yet been set, allocate a new syntax table                          
;; and setup the entries.                                                                       
(unless math-mode-syntax-table
  (setq math-mode-syntax-table
        (funcall (c-lang-const c-make-mode-syntax-table math)))

  (message "Modifying the math-mode-syntax-table")

  ;; character (                                                                                
  ;; ( - open paren class                                                                       
  ;; ) - matching paren character                                                               
  ;; 1 - 1st character of comment delimitter (**)                                               
  ;; n - nested comments allowed                                                                
  (modify-syntax-entry ?\( "()1n" math-mode-syntax-table)

  ;; character )                                                                                
  ;; ) - close parent class                                                                     
  ;; ( - matching paren character                                                               
  ;; 4 - 4th character of comment delimitter (**)                                               
  ;; n - nested comments allowed                                                                
  (modify-syntax-entry ?\) ")(4n" math-mode-syntax-table)

  ;; character *                                                                                
  ;; . - punctuation class                                                                      
  ;; 2 - 2nd character of comment delimitter (**)    
  ;; 3 - 3rd character of comment delimitter (**)                                               
  (modify-syntax-entry ?\* ". 23n" math-mode-syntax-table)

  ;; character [                                                                                
  ;; ( - open paren class                                                                       
  ;; ] - matching paren character                                                               
  (modify-syntax-entry ?\[ "(]" math-mode-syntax-table)

  ;; character ]                                                                                
  ;; ) - close paren class                                                                      
  ;; [ - mathcing paren character                                                               
  (modify-syntax-entry ?\] ")[" math-mode-syntax-table)

  ;; character {                                                                                
  ;; ( - open paren class                                                                       
  ;; } - matching paren character                                                               
  (modify-syntax-entry ?\{ "(}" math-mode-syntax-table)

  ;; character }                                                                                
  ;; ) - close paren class                                                                      
  ;; { - matching paren character                                                               
  (modify-syntax-entry ?\} "){" math-mode-syntax-table)

  ;; The following characters are punctuation (i.e. they cannot appear                          
  ;; in identifiers).                                                                           
  ;;                                                                                            
  ;; / ' % & + - ^ < > = |                                                                      
  (modify-syntax-entry ?\/ "." math-mode-syntax-table)
  (modify-syntax-entry ?\' "." math-mode-syntax-table)
  (modify-syntax-entry ?% "." math-mode-syntax-table)
  (modify-syntax-entry ?& "." math-mode-syntax-table)
  (modify-syntax-entry ?+ "." math-mode-syntax-table)
  (modify-syntax-entry ?- "." math-mode-syntax-table)
  (modify-syntax-entry ?^ "." math-mode-syntax-table)
  (modify-syntax-entry ?< "." math-mode-syntax-table)
  (modify-syntax-entry ?= "." math-mode-syntax-table)
  (modify-syntax-entry ?> "." math-mode-syntax-table)
  (modify-syntax-entry ?| "." math-mode-syntax-table)

  ;; character $                                                                                
  ;; _ - word class (since $ is allowed in identifier names)                                    
  (modify-syntax-entry ?\$ "_" math-mode-syntax-table)

  ;; character \                                                                                
  ;; . - punctuation class (for now treat \ as punctuation                                      
  ;;     until we can fix the \[word] issue).                                                   
  (modify-syntax-entry ?\\ "." math-mode-syntax-table)

  ) ;; end of math-mode-syntax-table adjustments                                                

;;                                                                                              
;;                                                                                              
(defvar math-mode-abbrev-table nil
  "Abbrevation table used in math mode buffers.")

(defvar math-mode-map (let ((map (c-make-inherited-keymap)))
                        map)
  "Keymap used in math mode buffers.")

;; math-mode                                                                                    
;;                                                                                              
(defun math-mode ()
  "Major mode for editing Mathematica code."

  (interactive)
  (kill-all-local-variables)

  (c-initialize-cc-mode t)

  (set-syntax-table math-mode-syntax-table)

  (setq major-mode 'math-mode
        mode-name "Math"
        local-abbrev-table math-mode-abbrev-table
        abbrev-mode t)

  (use-local-map math-mode-map)

  (c-init-language-vars math-mode)
  (c-common-init 'math-mode)

  (run-hooks 'c-mode-common-hook)
  (run-hooks 'math-mode-hook)
  (c-update-modeline))

(provide 'math-mode)                   

そしていくつかのスクリーンショットフォーマットされたコード

4

1 に答える 1

5

cc-mode はさまざまな言語に適応できるように設計されていますが、構文が cc-mode で十分にサポートされている構文とはかけ離れているため、Mathematica でうまく機能するかどうかはわかりません。SMIE (Emacs-23.4 で登場したインデント エンジンで、元々は SML 用に作成されましたが、現在はさまざまな言語で使用されています) を試すことをお勧めします。cc-mode と同様に、SMIE もすべての言語に適しているわけではありませんが、あなたのケースで cc-mode よりもうまく機能しても驚かないでしょう。

バックスラッシュの問題については、特定のバックスラッシュのエスケープの性質を変更するために使用するのが最善の策ですsyntax-propertize-function(構文テーブルで \ をエスケープとして設定し、\[foo] の \ を非エスケープとしてマークするか、\ のままにします構文テーブルで非エスケープとしてマークし、それらの \" および \\ をエスケープとしてマークします)。

于 2013-03-11T19:24:25.273 に答える