diff options
| author | Christoph Wedler | 2025-12-08 20:02:33 +0100 |
|---|---|---|
| committer | Christoph Wedler | 2025-12-09 07:52:20 +0100 |
| commit | 37468d244962dedc7ab760ffb19e15121975c1f0 (patch) | |
| tree | 705fd02c3a8e4f93ef3caf7f0c8f78ac0f2233ab | |
| parent | d10a649e1b3737524f64e14e6a033eec5d0ab17d (diff) | |
| download | emacs-feature/antlr-mode.tar.gz emacs-feature/antlr-mode.zip | |
Update progmodes/antlr-mode.el from v2.2c to v3.2.0feature/antlr-mode
For the ChangeLog with timeline,
see https://sourceforge.net/projects/antlr-mode/files/
The following is the ChangeLog between v2.2c to v3.2.0
without (intermediate) version numbers and changes already in the Emacs
repository.
* antlr-mode.el: Command `antlr-run-tool' now runs on the file for
the current buffer by default.
(antlr-run-tool-on-buffer-file): New user option.
(antlr-run-tool-interactive): Use it.
* antlr-mode.el: Allow `antlr-tool-version' and `antlr-language'
be set in the Local Variables section of a file.
(antlr-hack-local-variables-hook): New function.
(antlr-set-tool-version-and-mode-line): Adapt
(antlr-delayed-mode-hook): Renamed from `antlr-after-body-hook'.
(antlr-font-lock-keywords): Correctly call `font-lock-value-in-major-mode'.
* antlr-mode.el: Miscellaneous corrections and other changes.
(antlr-insert-keyword-rule): Make it work in v2 and v4, too.
(antlr-indent-line): Correctly calculate beginning of action.
(antlr-grammar-header-regexp): Has a value which is valid for v3 and v4.
(antlr-v4-grammar-header-regexp, antlr-v3-grammar-header-regexp):
Delete.
(antlr-tool-version-variables): tool-dependent variable for
`antlr-grammar-header-regexp`' is optional.
(antlr-upcase-p): Delete XEmacs bug workaround.
* antlr-mode.el: Enhance options, add v4 language "Cpp".
(antlr-v4-language-list): Add "Cpp".
(antlr-v4-options-alists, antlr-v3-options-alists)
(antlr-v2-options-alists): Do not hard-code languages.
(antlr-read-language): New function used instead.
(antlr-v4-options-alists): Add grammar option "contextSuperClass"
and Cpp-only "exportMacro".
(antlr-insert-option-do): Call the "right" antlr-mode for v4 grammars.
(antlr-option-spec): Delete function.
(antlr-insert-option-do): Do not use it.
* antlr-mode.el: Correct command `antlr-insert-options'.
(antlr-try-rule-or-grammar-option): New function.
(antlr-option-level): Use it, correcting v3 and v4 behavior.
(antlr-v2-options-alists): Correct "language" option.
(antlr-syntactic-grammar-depth): Correct calculation
(antlr-options-style): Make it really obsolete.
(antlr-read-value): Do not use it.
* antlr-mode.el: Disable command `antlr-show-makefile-rules' for
ANTLR v3 and v4, these have "-depend" to show Makefile deps.
(antlr-show-makefile-rules): User error when used with v3 or v4.
* antlr-mode.el: Adapt command `antlr-run-tool' to ANTLR v3 and
v4, do not calculate v2 option "-glib" for file dependencies.
(antlr-tool-command): Make it tool-version dependent
(antlr-v4-tool-command, antlr-v3-tool-command)
(antlr-v2-tool-command): New user option.
(antlr-run-tool-interactive): Only add "-glib" option with v2.
(antlr-directory-dependencies): Only calculate deps with v2.
(antlr-compilation-error-regexp-alist)
(antlr-v4-compilation-error-regexp-alist): New variable.
(antlr-tool-version-variables, antlr-run-tool): Use it.
* antlr-mode.el: Cleanup, miscellaneous. Replace `match-string'
by `match-string-no-properties' (see vc history).
(antlr-grammar-file): New function.
(antlr-insert-keyword-rule): New command.
(antlr-mode-map): Use it.
(antlr-font-lock-late-keywords): Correct face name.
* antlr-mode.el: Allow to write a derived mode for grammars - like
for PEG.js - whose rule header and body is separated by an
operator other than ":" and other similar deviations. Also
prepare for messages without file name in "*compilation*" buffer.
(antlr-rule-body-start-op): New variable.
(antlr-end-of-body, antlr-indent-line): Use it.
(antlr-grammar-file): New variable.
(antlr-run-tool): Set it local in *compilation*" to FILE.
(antlr-font-lock-attribute-regexp, antlr-ruleref-assign-regexp):
(antlr-v2-ruleref-assign-regexp, antlr-font-lock-negation-regexp):
(antlr-font-lock-syntax-spec): New variables.
(antlr-font-lock-additional-keywords):
(antlr-font-lock-late-keywords): Use them here.
(antlr-tool-version-variables): Add `antlr-ruleref-assign-regexp'.
* antlr-mode.el: Adaptation to Emacs-25.1, cleanup.
(antlr-insert-makefile-rules): Set variable properly.
(antlr-syntax-propertize-template-literals): Using << inside an
unclosed code block could lead to error during font-locking.
(antlr-slow-cache-enabling-symbol): Delete variable.
* antlr-mode.el: Adopt change below and other changes in the Emacs
repository to current antlr-mode version.
* antlr-mode.el: Use syntax-ppss. Check "are we in the grammar or
action code?" does not use extra action syntax-table anymore, but
9th element of syntax-ppss / parse-partial-sexp, whose value is
"subject to change" but has not changed since decades.
(antlr-action-syntax-table): Delete variable.
(antlr-font-lock-defaults): Do not give parentheses symbol syntax.
(antlr-slow-context-cache): Delete variable.
(antlr-invalidate-context-cache): Delete function.
(antlr-syntactic-context): Use syntax-ppss, new optional arg PPSS.
Now returns nil instead 0 if in normal grammar code.
(antlr-syntax-propertize-template-literals, antlr-re-search-forward)
(antlr-search-result, antlr-syntax-propertize-charsets)
(antlr-electric-character): Simplify.
(antlr-do-syntax-propertize): New variable.
* antlr-mode.el: Code is not run under extra syntax table anymore.
(antlr-syntax-propertize-wholerule, antlr-indent-at-bol-alist)
(antlr-v4-grammar-header-regexp, antlr-v3-grammar-header-regexp)
(antlr-v2-grammar-header-regexp, antlr-rule-postlude-skip-regexp)
(antlr-skip-file-prelude, antlr-font-lock-additional-keywords)
(antlr-imenu-create-index-function, antlr-inside-rule-p)
(antlr-end-of-rule, antlr-beginning-of-rule antlr-end-of-body)
(antlr-hide-actions, antlr-insert-option, antlr-option-level)
(antlr-downcase-literals, antlr-file-dependencies)
(antlr-guess-tool-version, antlr-indent-line):
Do not call deleted function, do not use deleted variables, use
regexp \\_> instead \\>., use both \\s_ and \\sw.
* antlr-mode.el: Minor changes.
(antlr-action-face, antlr-symbol-face): New face.
(antlr-token-identifier-p): New variable.
(antlr-font-lock-late-keywords): Use it, use
antlr-grammar-header-regexp, use new faces.
(antlr-syntax-propertize-charsets): Ignore @actionscope::name when
searching for lexer rules.
(antlr-syntax-propertize-template-literals): Change handling if
the template literal does not end before eob.
(antlr-font-lock-keywords): Use font-lock-eval-keywords.
(antlr-rule-postlude-skip-regexp): Allow scope name to begin with
underscore.
* antlr-mode.el: Make antlr-mode more modular - allow to add new
target languages without changing existing code.
(antlr-language-variables, antlr-language-mode-name)
(antlr-java-language-mode-name, antlr-action-mode)
(antlr-java-action-mode, antlr-init-cc-mode)
(antlr-java-init-cc-mode, antlr-init-submode)
(antlr-indent-action-line, antlr-action-font-lock-keywords)
(antlr-java-action-font-lock-keywords, antlr-action-scope-names)
(antlr-action-names, antlr-java-action-names): New variables.
(antlr-c-language-mode-name, antlr-cpp-language-mode-name)
(antlr-objc-language-mode-name, antlr-c-action-mode)
(antlr-cpp-action-mode, antlr-objc-action-mode)
(antlr-c-init-cc-mode, antlr-cpp-init-cc-mode)
(antlr-obj-init-cc-mode, antlr-cpp-action-font-lock-keywords)
(antlr-c-action-font-lock-keywords)
(antlr-objc-action-font-lock-keywords)
(antlr-js-language-mode-name, antlr-js-action-mode)
(antlr-js-init-submode, antlr-js-action-font-lock-keywords)
(antlr-js-indent-action-line, antlr-delphi-language-mode-name)
(antlr-delphi-action-mode, antlr-delphi-init-submode)
(antlr-delphi-action-font-lock-keywords)
(antlr-delphi-indent-action-line, antlr-ruby-language-mode-name)
(antlr-ruby-action-mode, antlr-ruby-init-submode)
(antlr-ruby-action-font-lock-keywords)
(antlr-ruby-indent-action-line, antlr-python-language-mode-name)
(antlr-python-action-mode, antlr-python-action-font-lock-keywords)
(antlr-python-indent-action-line, antlr-python-init-submode): New
variables.
(antlr-init-js, antlr-js-indent-action-line, antlr-init-delphi)
(antlr-delphi-indent-action-line, antlr-init-ruby)
(antlr-ruby-indent-action-line, antlr-init-python)
(antlr-python-indent-action-line): New functions.
(antlr-font-lock-keywords-alist): Remove variable.
(antlr-guess-language): Rename from anlr-language-option, use
antlr-language-list, use cl function.
* antlr-mode.el: Make antlr-mode more modular - allow to add new
ANTLR versions/flavors without changing existing code.
(antlr-tool-version): Is a symbol now, default to nil = automatic.
For backward compatibility, numbers between 20000 and 29999 are
set to antlr-v2 in antlr-set-tool-version-and-mode-line. This
variable should not be customized anymore - change :type spec.
(antlr-tool-version-variables, antlr-tool-mode-name)
(antlr-v4-tool-mode-name, antlr-v3-tool-mode-name)
(antlr-v2-tool-mode-name, antlr-language-list)
(antlr-v4-language-list, antlr-v3-language-list)
(antlr-v2-language-list, antlr-syntax-propertize)
(antlr-v4-syntax-propertize, antlr-v3-syntax-propertize)
(antlr-v2-syntax-propertize, antlr-v2-options-alist)
(antlr-v4-skip-line-regexp, antlr-v3-skip-line-regexp)
(antlr-font-lock-symbol-regexp)
(antlr-v4-font-lock-symbol-regexp)
(antlr-v3-font-lock-symbol-regexp)
(antlr-v4-grammar-header-regexp, antlr-v3-grammar-header-regexp)
New variables.
(antlr-options-alist): Make it tool-dependent. Remove sub-version
specific settings for ANTLR v2. Remove function.
(antlr-v2-grammar-header-regexp): Rename from
antlr-class-header-regexp.
(antlr-grammar-header-regexp): Make it tool-version dependent.
(antlr-mode-menu, antlr-insert-option-interactive)
(antlr-options-menu-filter, antlr-option-level)
(antlr-insert-option-do): Use tool specific variable.
(antlr-option-spec): ...and do not support sub versions.
(antlr-guess-tool-version): Rename from antlr-tool-version.
(antlr-set-local-variables): New function
(antlr-set-tool-version-and-mode-line): Use them.
* antlr-mode.el: Remove XEmacs and old Emacs compatibility code.
(require): require cl-lib instead cl at compile time.
(antlr-run-tool-interactive, antlr-insert-makefile-rules)
(antlr-set-tabs, antlr-next-rule, antlr-downcase-literals)
(antlr-file-dependencies): Use cl- prefix for cXXXr, cXXXXr, incf,
decf, list*.
(cond-emacs-xemacs, cond-emacs-xemacs-macfn, defunx)
(ignore-errors-x, save-buffer-state-x): Delete functions/macros.
(antlr-skip-sexps, antlr-hide-actions, antlr-option-kind): Adopt.
(antlr-mode-menu): Do not test for Emacs below 21.0.
(antlr-with-syntax-table): Delete, use with-syntax-table instead.
(antlr-imenu-create-index-function, antlr-inside-rule-p)
(antlr-end-of-rule, antlr-beginning-of-rule, antlr-end-of-body)
(antlr-downcase-literals, antlr-hide-actions)
(antlr-option-level, antlr-file-dependencies, antlr-indent-line)
(antlr-electric-character, antlr-tool-version): Adopt.
(antlr-default-directory): Delete function. Actually XEmacs'
default-directory as a function is quite useful...
(antlr-run-tool-interactive, antlr-insert-makefile-rules): Adopt.
(antlr-read-shell-command): Delete, use read-shell-command.
(antlr-run-tool-interactive): Adopt.
(antlr-with-displaying-help-buffer): Delete.
(antlr-show-makefile-rules): Use with-output-to-temp-buffer.
(antlr-invalidate-context-cache)
(antlr-syntactic-context): Remove XEmacs code.
(antlr-end-of-rule, antlr-beginning-of-rule, antlr-end-of-body)
(antlr-beginning-of-body): use interactive "^" for "_" in XEmacs.
(antlr-mode): Do not consider cc-mode below 5.30.
* antlr-mode.el: Scope references inside a v3 rule and import
statements in a v4 grammar do not confuse the navigation anymore.
(antlr-skip-line-regexp): New variable, contains regexp for v3
"scope" / v4 "import" up to the semicolon.
(antlr-set-tool-version-and-mode-line): Set it.
(antlr-search-result): New function.
(antlr-search-forward, antlr-search-backward): Use it. Add extra
regexp parameter for occurrences which should be skipped.
(antlr-imenu-create-index-function, antlr-next-rule)
(antlr-beginning-of-rule, antlr-indent-line): Provide
`antlr-skip-line-regexp' when searching for ";".
(antlr-rule-postlude-skip-alist): Make it a `defconst',
re-compilation would use previous value. Add "import".
(antlr-skip-rule-postlude): Allow function as SKIP.
(antlr-skip-import-statement): New function for postlude skip.
* antlr-mode.el: Correctly recognize ANTLR v4 lexer charsets,
[...], and v3 templates, <<...>>, as literals.
(antlr-syntax-propertize-wholerule)
(antlr-syntax-propertize-charsets)
(antlr-syntax-propertize-template-literals): New function
(antlr-set-tool-version-and-mode-line): Use them.
(antlr-imenu-create-index-function): Call `syntax-propertize'.
* antlr-mode.el (antlr-end-of-defun-is-next): New option. If
non-nil, both `antlr-end-of-rule' and `antlr-end-of-rule' jump to
beginning of a rule with no or positive prefix arg, and to the end
of a rule with negative prefix arg. Default nil means:
`antlr-end-of-rule' jumps to beginning of a rule,
`antlr-end-of-rule' jumps to end of a rule.
(antlr-end-of-rule): Use it.
(antlr-beginning-of-rule): Use it
* antlr-mode.el: Options support for ANTLR v3 and v4.
(antlr-v3-options-alists): Correct prompts.
(antlr-v4-options-alists): New variable.
(antlr-options-alists): Use it.
(antlr-read-boolean): Use `y-or-n-p' without TABLE.
(antlr-mode-menu): Do not include empty option menus.
(antlr-option-level): Consider non-existent file/subrule options.
Correctly recognize v3/v4 grammar definitions.
* antlr-mode.el: Imenu and syntax-highlighting corrections.
(antlr-font-lock-late-keywords): Correct syntax-highlighting of
rule definitions with modifiers in same line.
(antlr-grammar-header-regexp): New regexp for v3 and v4.
(antlr-class-header-regexp): New function.
(antlr-imenu-create-index-function): Also collect v4 scanner
modes. Correctly scan fragment rules.
* antlr-mode.el: Correctly skip the part of the rule which comes
after the semicolon. To simplify things, consider v2 class
preamble actions as belonging to the previous definition.
(antlr-skip-file-prelude): Skip final ACTION.
(antlr-rule-postlude-skip-alist)
(antlr-rule-postlude-skip-regexp): New variables.
(antlr-skip-rule-postlude): Use them. Rename from
`antlr-skip-exception-part'.
(antlr-beginning-of-body): Tool version-dependent error message.
(antlr-options-alists): Consider v4 options.
* antlr-mode.el (antlr-indent-line): For indentation cycling in
Python, do not require a patched python.el anymore, but
prog-mode.el and python.el from Emacs-24.5. Do not touch
multi-line python actions which do not start in its own line -
they are a bad idea anyway.
* antlr-mode.el: Experimental indentation cycling for Python
actions. Requires a patched python.el. Note: this patch is just
a first proposal by me - things will change.
(antlr-indent-line): Bind `python-submode-indentation-context'
while calling `python-indent-line'.
* antlr-mode.el: Use much less intrusive face settings, some minor
font-lock changes.
(antlr-syntax): Just inherit from `font-lock-keyword-face', face
is now only used for AST-relevant operators (!, ^, ->), not
parentheses, colons etc anymore - see below.
(antlr-keyword): Just inherit from `font-lock-keyword-face'.
(antlr-ruledef): Just inherit from `font-lock-function-name-face'.
(antlr-tokendef): Just inherit from `font-lock-function-name-face'.
(antlr-ruleref): Just inherit from `font-lock-type-face'.
(antlr-tokenref): Just inherit from `font-lock-constant-face'.
(antlr-attribute): Just inherit from `font-lock-preprocessor-face'.
(antlr-literal): Just inherit from `font-lock-string-face' and
specify :weight bold.
(antlr-grammardef-face): Delete variable introduced in v3.0.2.
(antlr-grammardef): Delete face, use `font-lock-type-face'.
(antlr-font-lock-late-keywords): Change according to semantic
change of `antlr-syntax', properly highlight scope definitions.
(antlr-font-lock-additional-keywords): Change highlighting
according to ANTLR change concerning grammar element labels, ANTLR
v3/v4 only. Use `font-lock-negation-char-face' for ~, single dot.
* antlr-mode.el: Be more robust / fix bug introduced with v3.0.5 -
class definitions in ANTLR v2 grammars would look strange,
makefile dependencies would not work even with ANTLR v2 grammars.
(antlr-class-header-regexp): Revert accidentally change in regexp.
(antlr-insert-makefile-rules): Be more robust against incomplete
grammar files, i.e. those without any extracted dependency.
* antlr-mode.el: Indentation for non-cc-based languages:
JavaScript, Delphi, Ruby - Python actions are left as they are.
(antlr-indent-line): For a line starting with the closing brace of
bracket of an action / parameter section, use our own indentation
engine, not that of the grammar language.
(antlr-indent-line): Run indentation functions of `js-mode',
`opascal-mode' and `ruby-mode' with buffer restriction starts
after the opening brace/bracket.
(antlr-indent-command): Preparation for future support for
indentation cycling used by Python - do not insert a TAB with
repeated call of this command.
(antlr-set-tool-version-and-mode-line): Locally set indentation
offsets/levels of grammar language according to offset used in the
ANTLR grammar.
* antlr-mode.el: Correct indentation of rule headers.
(antlr-indent-line): When looking for the end of a rule header, do
not stop at colon if that is followed by another one, because this
the scope name of a preceeding grammar action.
* antlr-mode.el: Support more action languages.
(antlr-language-alist): Add entries for C, Delphi, JavaScript,
ObjC, Python and Ruby, additional to Java and Cpp.
(antlr-language-limit-n-regexp): Allow language name to contain
digits.
(antlr-font-lock-keywords-alist): Add font-lock specifications for
the newly supported languages.
(antlr-set-tool-version-and-mode-line): Handle non-cc-based
languages, currently hard-coded.
* antlr-mode.el: Preparation for non-cc-mode-based indentation.
(antlr-indent-line): With non-cc-based languages, do not touch
lines in braces and brackets, i.e. mainly actions.
* antlr-mode.el: Bug fixes and minor changes.
(antlr-indent-line): Introduced 3.0.4: lines starting with a colon
would be incorrectly indented.
(antlr-tool-version): v3 grammars with a class definition in a
header action or containing a rule called "header" or "class"
would be incorrectly categorized as v2 grammar.
(antlr-set-tool-version-and-mode-line, antlr-mode): Set
`indent-line-function' and friends after initializing cc-mode.
(antlr-java-action-names): Renamed from `antlr-action-names',
only include action names used with language Java.
(antlr-font-lock-late-keywords): Check action names only in Java.
* antlr-mode.el: Preparation for v3/v4 options support.
(antlr-v3-options-alists): New variable.
(antlr-options-alists): New function.
(antlr-insert-option-interactive, antlr-options-menu-filter)
(antlr-insert-option-do): Use it.
(antlr-option-spec): Allow options-alist not to specify ANTLR
subversions.
* antlr-mode.el: More flexible tool invocation.
(antlr-tool-path): New variable.
(antlr-run-tool): Use it.
(antlr-tool-command): Can now be a function.
(antlr-run-tool-interactive): Change accordingly.
* antlr-mode.el: Emacs-corrected and more flexible indentation.
(antlr-syntactic-context): Bind `parse-sexp-ignore-comments' to t,
parentheses inside comments would bring Emacs out of sync.
(antlr-base-offset-alist): New user option.
(antlr-indent-line): Use it.
* antlr-mode.el: Delay language recognition and tab settings.
(antlr-tool-version): Correctly recognize v2 grammars without
header{...}.
(antlr-set-tool-version-and-mode-line): Set language here.
(antlr-mode): Do not set language here.
* antlr-mode.el: Bug fixes.
(antlr-language-limit-n-regexp): Also recognize 'LANG'.
(antlr-imenu-create-index-function): in ANTLR v2 grammars,
`which-function-mode' would not work, classes would not appear.
(antlr-font-lock-checked-face): action names would not be
highlighted, the doc string was inserted at the wrong place...
* antlr-mode.el: Use "Antlr2"/"Antlr3"/"Antlr4" in mode line.
(antlr-tool-version): Set default value to nil = automatic.
(antlr-tool-version): New function.
(antlr-set-tool-version-and-mode-line): New function.
(antlr-after-body-hook): New variable.
(antlr-mode): Run it as mode hook.
(antlr-v4-mode): Do not update mode line anymore.
* antlr-mode.el: Minor font-lock changes.
(antlr-font-lock-literal-regexp): Also match strings surrounded by
single quotes, and symbols and punctuation.
(antlr-font-lock-late-keywords): Highlight regexp group 2 of that.
* antlr-mode.el: Preparation for further v3 and v4 support.
(antlr-v4-mode): New major mode for file suffix "g4".
* antlr-mode.el: Adopt imenu and navigation to ANTLR v3 and v4.
(antlr-imenu-create-index-function): Recognize fragment
specification and named actions.
(antlr-skip-exception-part): With v3 and v4, there is no
'exception' keyword, but an additional optional 'finally'.
* antlr-mode.el: Adopt font-lock to ANTLR v3 and v4.
(antlr-grammardef, antlr-attribute): New faces.
(antlr-action-names, antlr-action-scope-names): New variables
(antlr-font-lock-late-keywords): Recognize new elements.
(antlr-font-lock-additional-keywords): Changed font-lock for $attr
constructs.
* antlr-mode.el: Newer cc-mode fontification is very eager,
i.e. would overwrite that of antlr-mode.
(antlr-font-lock-late-keywords): New variable, also using
OVERRIDE in MATCH-HIGHLIGHT.
(antlr-font-lock-keywords): Add at end of keywords.
(antlr-font-lock-additional-keywords): Delete keywords here.
* antlr-mode.el: Checked ANTLR up to latest v2.
(antlr-tool-version): Set for ANTLR v2.7.7.
(antlr-options-alists): Added options introduced with ANTLR
v2.7.2, "classHeaderPrefix" and "noConstructors".
* antlr-mode.el: redisplay during font-lock could signal
"c-where-wrt-brace-construct: c-beginning-of-decl-1 returned
label".
(antlr-font-lock-defaults): Do not set `beginning-of-defun'.
* antlr-mode.el: Delete support for old cc-mode versions.
(antlr-c-init-language-vars): Delete function.
(antlr-mode): Do not call it anymore.
(antlr-mode-syntax-table): Adopt docstring to changed init.
* antlr-mode.el: imenu creation could signal
"c-where-wrt-brace-construct: c-beginning-of-decl-1 returned
label".
(antlr-slow-cache-diff-threshold): Delete variable.
(antlr-syntactic-context): Do not use it here, do not call
`beginning-of-defun' anymore.
(antlr-mode): Allow /// etc as `comment-start-skip'. Still set
`require-final-newline'.
* antlr-mode.el (antlr-electric-character): With Emacs, use
`last-command-event' instead `last-command-char'.
* antlr-mode.el: imenu creation could signal
"c-where-wrt-brace-construct: c-beginning-of-decl-1 returned
label".
(antlr-slow-cache-diff-threshold): Deletia.
(antlr-syntactic-context): Do not use it here, do not call
`beginning-of-defun' anymore.
| -rw-r--r-- | lisp/progmodes/antlr-mode.el | 2838 |
1 files changed, 1890 insertions, 948 deletions
diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index 4f17dd77b2a..d68476d9a64 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | ;;; antlr-mode.el --- major mode for ANTLR grammar files -*- lexical-binding: t; -*- | 1 | ;;; antlr-mode.el --- major mode for ANTLR grammar files -*- lexical-binding: t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1999-2025 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1999-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Christoph Wedler <Christoph.Wedler@sap.com> | 5 | ;; Author: Christoph Wedler <Christoph.Wedler@sap.com> |
| 6 | ;; Keywords: languages, ANTLR, code generator | 6 | ;; Keywords: languages, ANTLR, code generator |
| 7 | ;; Version: 2.2c | 7 | ;; Version: 3.2.0 |
| 8 | ;; URL: https://antlr-mode.sourceforge.net/ | 8 | ;; URL: https://antlr-mode.sourceforge.net/ |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -27,58 +27,88 @@ | |||
| 27 | ;; The Emacs package ANTLR-Mode provides: syntax highlighting for ANTLR grammar | 27 | ;; The Emacs package ANTLR-Mode provides: syntax highlighting for ANTLR grammar |
| 28 | ;; files, automatic indentation, menus containing rule/token definitions and | 28 | ;; files, automatic indentation, menus containing rule/token definitions and |
| 29 | ;; supported options and various other things like running ANTLR from within | 29 | ;; supported options and various other things like running ANTLR from within |
| 30 | ;; Emacs. | 30 | ;; Emacs. It works for ANTLR v2, v3 and v4. |
| 31 | 31 | ||
| 32 | ;; For details, check <https://antlr-mode.sourceforge.net/> or, if you prefer | 32 | ;; For details, check <https://antlr-mode.sourceforge.net/> or, if you prefer |
| 33 | ;; the manual style, follow all commands mentioned in the documentation of | 33 | ;; the manual style, follow all commands mentioned in the documentation of |
| 34 | ;; `antlr-mode'. ANTLR is a LL(k)-based recognition tool which generates | 34 | ;; `antlr-mode'. ANTLR is a LL(k)-based recognition tool which generates |
| 35 | ;; lexers, parsers and tree transformers in Java, C++ or Sather and can be | 35 | ;; lexers, parsers and tree transformers in Java, C++ or other languages and |
| 36 | ;; found at <https://www.antlr.org/>. | 36 | ;; can be found at <https://www.antlr.org/>. |
| 37 | 37 | ||
| 38 | ;; Bug fixes, bug reports, improvements, and suggestions for the newest version | 38 | ;; Topics for 3.2 or later: |
| 39 | ;; are strongly appreciated. | ||
| 40 | |||
| 41 | ;; To-do/Wish-list: | ||
| 42 | ;; | 39 | ;; |
| 43 | ;; * Next Version [C-c C-w]. Produce HTML document with syntax highlighted | 40 | ;; * Special support for `indent-region': faster and better for Python ELP |
| 44 | ;; and hyper-links (using htmlize). | ||
| 45 | ;; * Next Version [C-c C-u]. Insert/update special comments: each rule lists | ||
| 46 | ;; all rules which use the current rule. With font-lock update. | ||
| 47 | ;; * Next Version. Make hiding much more customizable. | ||
| 48 | ;; * Planned [C-c C-j]. Jump to generated coding. | ||
| 49 | ;; * Planned. Further support for imenu, i.e., include entries for method | ||
| 50 | ;; definitions at beginning of grammar class. | ||
| 51 | ;; * Planned [C-c C-p]. Pack/unpack rule/subrule & options (one/multi-line). | ||
| 52 | ;; | ||
| 53 | ;; * Probably. Show rules/dependencies for ANT like for Makefile (does ANT | ||
| 54 | ;; support vocabularies and grammar inheritance?), I have to look at | ||
| 55 | ;; jde-ant.el: https://jakarta.apache.org/ant/manual/OptionalTasks/antlr.html | ||
| 56 | ;; * Probably. Make `indent-region' faster, especially in actions. ELP | ||
| 57 | ;; profiling in a class init action shows half the time is spent in | 41 | ;; profiling in a class init action shows half the time is spent in |
| 58 | ;; `antlr-next-rule', the other half in `c-guess-basic-syntax'. | 42 | ;; `antlr-next-rule', the other half in `c-guess-basic-syntax'. |
| 59 | ;; * Unlikely. Sather as generated language with syntax highlighting etc/. | 43 | ;; Do not define a indent command, just a function to be put into |
| 60 | ;; Questions/problems: is sather-mode.el the standard mode for sather, is it | 44 | ;; indent-line/region-function. |
| 61 | ;; still supported, what is its relationship to eiffel3.el? Requirement: | 45 | ;; * In v4, highlight lexer commands after "->" |
| 62 | ;; this mode must not depend on a Sather mode. | 46 | ;; * Test: in `antlr-imenu-create-index-function', can we use |
| 63 | ;; * Unlikely. Faster syntax highlighting: sectionize the buffer into Antlr | 47 | ;; (or antlr-skip-line-regexp antlr-grammar-header-regexp) |
| 64 | ;; and action code and run special highlighting functions on these regions. | 48 | ;; * Use native menu bindings instead easymenu (and use :help) |
| 65 | ;; Problems: code size, this mode would depend on font-lock internals. | 49 | ;; * Support v4 rule element options |
| 50 | ;; * Define minor mode for `antlr-hide-actions' functionality. | ||
| 51 | ;; * [C-c C-u]. *Help* for current rule / all rules: used-By list (at least | ||
| 52 | ;; for single-file grammars) | ||
| 53 | ;; * [C-c C-j]. Jump to generated coding. | ||
| 54 | |||
| 55 | ;; Eventually: | ||
| 56 | ;; | ||
| 57 | ;; * Support for one of the multi-mode imenu extensions mentioned in | ||
| 58 | ;; https://www.emacswiki.org/emacs-test/ImenuMode - if necessary | ||
| 59 | ;; * [C-c C-w]. Produce HTML document with syntax highlighted and | ||
| 60 | ;; hyper-links. With htmfontify: invisible actions did not really work | ||
| 61 | ;; (only w/o spaces?, default invisible would be better anyway) - we need to | ||
| 62 | ;; set <a> tags afterwards ourselves... Firefox does not understand | ||
| 63 | ;; encoding via XML declaration - use HTML meta tag. | ||
| 64 | ;; * Support for outline-minor-mode. | ||
| 65 | |||
| 66 | ;; The following topics and suggestions are unlikely to be implemented: | ||
| 67 | ;; | ||
| 68 | ;; * Some constructs of languages (in actions) which are highly un-C-ish might | ||
| 69 | ;; bring Emacs (and ANTLR!) out of sync: e.g. regexp literals in Perl, | ||
| 70 | ;; character and percent literals in Ruby. | ||
| 71 | ;; * Faster syntax highlighting: sectionize the buffer into Antlr and action | ||
| 72 | ;; code and run special highlighting functions on these regions. UNLIKELY | ||
| 73 | ;; due to: code size, this mode would depend on font-lock internals. | ||
| 74 | ;; * Set the syntax-table of the inner mode before calling the indentation | ||
| 75 | ;; engine of the inner mode (possible? - BUT: actions should still end at | ||
| 76 | ;; the same place!). Probably not worth the effort. | ||
| 77 | |||
| 78 | ;; Bug fixes, bug reports, improvements, and suggestions for the newest version | ||
| 79 | ;; are strongly appreciated. | ||
| 66 | 80 | ||
| 67 | ;;; Installation: | 81 | ;;; Installation: |
| 68 | 82 | ||
| 69 | ;; If antlr-mode is not part of your distribution, put this file into your | 83 | ;; This file requires Emacs-24.3 or higher which already includes a version of |
| 70 | ;; load-path and the following into your init file: | 84 | ;; antlr-mode. If you want to use this (hopefully newer) version instead, put |
| 71 | ;; (autoload 'antlr-mode "antlr-mode" nil t) | 85 | ;; this file into a directory early in `load-path' (or `push' a new one to it) |
| 72 | ;; (setq auto-mode-alist (cons '("\\.g\\'" . antlr-mode) auto-mode-alist)) | 86 | ;; and M-x byte-compile-file this file file. |
| 73 | ;; (add-hook 'speedbar-load-hook ; would be too late in antlr-mode.el | 87 | |
| 74 | ;; (lambda () (speedbar-add-supported-extension ".g"))) | 88 | ;; If you want to use this mode with ANTLR v4 files, put the following into |
| 89 | ;; your init file: | ||
| 90 | ;; (autoload 'antlr-v4-mode "antlr-mode" nil t) | ||
| 91 | ;; (push '("\\.g4\\'" . antlr-v4-mode) auto-mode-alist) | ||
| 75 | 92 | ||
| 76 | ;; To customize, use menu item "Antlr" -> "Customize Antlr". | 93 | ;; To customize, use menu item "Antlr" -> "Customize Antlr". |
| 77 | 94 | ||
| 78 | ;;; Code: | 95 | ;;; Development resources: |
| 96 | |||
| 97 | ;; Good examples for different action languages (for syntax coloring, ...), but | ||
| 98 | ;; there are almost no examples with rule parameters and return values... | ||
| 79 | 99 | ||
| 80 | (eval-when-compile (require 'cl-lib)) | 100 | ;; * examples-v3-master/Delphi: C/C.g, IslandGrammar/Simple.g, Python/Python.g |
| 101 | ;; * examples-v3-master/JavaScript: island-grammar/Simple.g, python/Python.g | ||
| 102 | ;; * examples-v3-master/Python: C/C.g, island-grammar/Simple.g, python/Python.g | ||
| 103 | ;; * Ruby in antlr3-master/samples/standard: ../CPP.g, ../JavaScript.g, C/C.g, | ||
| 104 | ;; python/Python.g | ||
| 105 | ;; * grammars-v4-master/ | ||
| 81 | 106 | ||
| 107 | ;;; Code: | ||
| 108 | |||
| 109 | (eval-when-compile | ||
| 110 | (require 'cl-lib) | ||
| 111 | (require 'compile)) | ||
| 82 | (when (< emacs-major-version 28) ; preloaded in Emacs 28 | 112 | (when (< emacs-major-version 28) ; preloaded in Emacs 28 |
| 83 | (require 'easymenu)) | 113 | (require 'easymenu)) |
| 84 | (require 'cc-mode) | 114 | (require 'cc-mode) |
| @@ -87,13 +117,6 @@ | |||
| 87 | (defvar imenu-use-markers) | 117 | (defvar imenu-use-markers) |
| 88 | (defvar imenu-create-index-function) | 118 | (defvar imenu-create-index-function) |
| 89 | 119 | ||
| 90 | ;; We cannot use `c-forward-syntactic-ws' directly since it is a macro since | ||
| 91 | ;; cc-mode-5.30 => antlr-mode compiled with older cc-mode would fail (macro | ||
| 92 | ;; call) when used with newer cc-mode. Also, antlr-mode compiled with newer | ||
| 93 | ;; cc-mode would fail (undefined `c-forward-sws') when used with older cc-mode. | ||
| 94 | ;; Additional to the `defalias' below, we must set `antlr-c-forward-sws' to | ||
| 95 | ;; `c-forward-syntactic-ws' when `c-forward-sws' is not defined after requiring | ||
| 96 | ;; cc-mode. | ||
| 97 | (defalias 'antlr-c-forward-sws #'c-forward-sws) | 120 | (defalias 'antlr-c-forward-sws #'c-forward-sws) |
| 98 | 121 | ||
| 99 | 122 | ||
| @@ -109,10 +132,97 @@ | |||
| 109 | :link '(url-link "https://antlr-mode.sourceforge.net/") | 132 | :link '(url-link "https://antlr-mode.sourceforge.net/") |
| 110 | :prefix "antlr-") | 133 | :prefix "antlr-") |
| 111 | 134 | ||
| 112 | (defconst antlr-version "2.2c" | 135 | (defconst antlr-version "3.2.0" |
| 113 | "ANTLR major mode version number. | 136 | "ANTLR major mode version number. |
| 114 | Check <https://antlr-mode.sourceforge.net/> for the newest.") | 137 | Check <https://antlr-mode.sourceforge.net/> for the newest.") |
| 115 | 138 | ||
| 139 | (defcustom antlr-language-limit-n-regexp ; TODO: rename? (also for tool-version) | ||
| 140 | ;; actually, it is in v2 "L" only, in v3/v4 'L' only | ||
| 141 | '(30000 . "\\<language[ \t]*=[ \t]*[\"']?\\([A-Z][A-Za-z_0-9]*\\)[\"']?") | ||
| 142 | "Used to set a reasonable value for `antlr-language'. | ||
| 143 | Looks like \(LIMIT . REGEXP). Search for REGEXP from the beginning of | ||
| 144 | the buffer to LIMIT and use the first group in the matched string to set | ||
| 145 | the language according to `antlr-language-list'." | ||
| 146 | :type '(cons (choice :tag "Limit" (const :tag "No" nil) (integer :value 0)) | ||
| 147 | regexp)) | ||
| 148 | |||
| 149 | |||
| 150 | ;;;=========================================================================== | ||
| 151 | ;;; Controlling the tool to use, automatically deduced | ||
| 152 | ;;;=========================================================================== | ||
| 153 | |||
| 154 | (defcustom antlr-tool-version nil | ||
| 155 | "The version symbol of the Antlr tool. DO NOT CUSTOMIZE. | ||
| 156 | Set as buffer-local in buffers using `antlr-mode'. Supported local | ||
| 157 | values are `antlr-v2', `antlr-v3' and`antlr-v4'. The value is used to | ||
| 158 | set other variables, see `antlr-tool-version-variables'." | ||
| 159 | :type '(radio (const :tag "Automatic" nil) | ||
| 160 | (sexp :tag "Do not choose this" :value nil))) | ||
| 161 | |||
| 162 | (defvar antlr-tool-version-variables | ||
| 163 | '(antlr-tool-mode-name | ||
| 164 | antlr-tool-command | ||
| 165 | antlr-language-list | ||
| 166 | antlr-syntax-propertize | ||
| 167 | antlr-options-alists | ||
| 168 | &optional | ||
| 169 | antlr-grammar-header-regexp | ||
| 170 | antlr-compilation-error-regexp-alist | ||
| 171 | antlr-skip-line-regexp | ||
| 172 | antlr-rule-postlude-skip-alist | ||
| 173 | antlr-rule-postlude-skip-regexp | ||
| 174 | antlr-ruleref-assign-regexp | ||
| 175 | antlr-font-lock-symbol-regexp) | ||
| 176 | "List of variables which have a tool-dependent value. | ||
| 177 | For each antlr-VAR in this list, function `antlr-set-local-variables' | ||
| 178 | makes it buffer-local and uses the variable VERSION-VAR, i.e., | ||
| 179 | antlr-v2-VAR, antlr-v3-VAR or antlr-v4-VAR to set its value, | ||
| 180 | dependending on the value VERSION of `antlr-tool-version'. | ||
| 181 | |||
| 182 | If that variable VERSION-VAR does not exist, ignore antlr-VAR if it is | ||
| 183 | listed after the symbol &optional, or issue an error otherwise.") | ||
| 184 | |||
| 185 | (defvar antlr-tool-mode-name nil | ||
| 186 | "The first part of the mode name used in the mode line. | ||
| 187 | The value is tool-dependent, see `antlr-tool-version-variables'.") | ||
| 188 | |||
| 189 | (defvar antlr-v4-tool-mode-name "Antlr4" | ||
| 190 | "Value for `antlr-tool-mode-name' when using ANTLR v4.") | ||
| 191 | (defvar antlr-v3-tool-mode-name "Antlr3" | ||
| 192 | "Value for `antlr-tool-mode-name' when using ANTLR v3.") | ||
| 193 | (defvar antlr-v2-tool-mode-name "Antlr2" | ||
| 194 | "Value for `antlr-tool-mode-name' when using ANTLR v2.") | ||
| 195 | |||
| 196 | (defvar antlr-language-list nil | ||
| 197 | "Alist of supported action languages. | ||
| 198 | Each element in this list looks like (LANG-SYMBOL STRING...) where | ||
| 199 | LANG-SYMBOL is made the value of `antlr-language' and one of the STRINGs | ||
| 200 | is used in ANTLR's `language` grammar/file option to specify that | ||
| 201 | language. | ||
| 202 | The value is tool-dependent, see `antlr-tool-version-variables'.") | ||
| 203 | |||
| 204 | (defvar antlr-v4-language-list | ||
| 205 | '((antlr-java "Java") (antlr-cpp "Cpp") ; +CSharp | ||
| 206 | (antlr-js "JavaScript") (antlr-python "Python2" "Python3")) | ||
| 207 | ;; in ANTLR4-codegen/runtime, but not here | ||
| 208 | ;; - no standard Emacs major modes: CSharp, Go, Swift | ||
| 209 | "Value for `antlr-language-list' when using ANTLR v4.") | ||
| 210 | |||
| 211 | (defvar antlr-v3-language-list | ||
| 212 | '((antlr-java "Java") (antlr-cpp "Cpp") (antlr-c "C") | ||
| 213 | (antlr-objc "ObjC") ; + CSharp | ||
| 214 | (antlr-js "JavaScript") (antlr-delphi "Delphi") ; + Perl | ||
| 215 | (antlr-python "Python" "Python3") (antlr-ruby "Ruby")) | ||
| 216 | ;; in ANTLR3-codegen/runtime, but not here | ||
| 217 | ;; - no standard Emacs major modes: ActionScript, CSharp2, CSharp3 | ||
| 218 | ;; - I didn't spend time for it (and do not plan to do so): Perl5 | ||
| 219 | "Value for `antlr-language-list' when using ANTLR v3.") | ||
| 220 | |||
| 221 | (defvar antlr-v2-language-list | ||
| 222 | '((antlr-java "Java") (antlr-cpp "Cpp") (antlr-python "Python") | ||
| 223 | (nil "HTML") (nil "Diagnostic")) ; + CSharp | ||
| 224 | "Value for `antlr-language-list' when using ANTLR v2.") | ||
| 225 | |||
| 116 | 226 | ||
| 117 | ;;;=========================================================================== | 227 | ;;;=========================================================================== |
| 118 | ;;; Controlling ANTLR's code generator (language option) | 228 | ;;; Controlling ANTLR's code generator (language option) |
| @@ -120,15 +230,62 @@ Check <https://antlr-mode.sourceforge.net/> for the newest.") | |||
| 120 | 230 | ||
| 121 | (defvar antlr-language nil | 231 | (defvar antlr-language nil |
| 122 | "Major mode corresponding to ANTLR's \"language\" option. | 232 | "Major mode corresponding to ANTLR's \"language\" option. |
| 123 | Set via `antlr-language-alist'. The only useful place to change this | 233 | Set via `antlr-language-list'. The only useful place to change this |
| 124 | buffer-local variable yourself is in `antlr-mode-hook' or in the \"local | 234 | buffer-local variable yourself is in `antlr-mode-hook' or in the \"local |
| 125 | variable list\" near the end of the file, see | 235 | variable list\" near the end of the file, see |
| 126 | `enable-local-variables'.") | 236 | `enable-local-variables'. |
| 127 | 237 | The value is used to set other variables, see `antlr-language-variables'.") | |
| 128 | (defcustom antlr-language-alist | 238 | |
| 129 | '((java-mode "Java" nil "\"Java\"" "Java") | 239 | (defvar antlr-language-variables |
| 130 | (c++-mode "C++" "\"Cpp\"" "Cpp")) | 240 | '(antlr-language-mode-name |
| 131 | "List of ANTLR's supported languages. | 241 | antlr-action-mode |
| 242 | &optional | ||
| 243 | antlr-init-cc-mode | ||
| 244 | antlr-init-submode | ||
| 245 | antlr-indent-action-line | ||
| 246 | antlr-action-font-lock-keywords | ||
| 247 | antlr-action-names) | ||
| 248 | "List of variables which have a language-dependent value. | ||
| 249 | For each antlr-VAR in this list, function `antlr-set-local-variables' | ||
| 250 | makes it buffer-local and uses the variable LANGUAGE-VAR, i.e., | ||
| 251 | antlr-java-VAR, antlr-cpp-VAR, and so on to set its value, | ||
| 252 | dependending on the value LANGUAGE of `antlr-language'. | ||
| 253 | |||
| 254 | If that variable LANGUAGE-VAR does not exist, ignore antlr-VAR if it is | ||
| 255 | listed after the symbol &optional, or issue an error otherwise.") | ||
| 256 | |||
| 257 | ;; Languages other than Java are defined at the end -------------------------- | ||
| 258 | |||
| 259 | (defvar antlr-language-mode-name "txt" | ||
| 260 | "The second part of the mode name used in the mode line. | ||
| 261 | The value is language-dependent, see `antlr-language-variables'.") | ||
| 262 | |||
| 263 | (defvar antlr-java-language-mode-name "Java" | ||
| 264 | "Value for `antlr-language-mode-name' when using language `antlr-java'.") | ||
| 265 | |||
| 266 | (defvar antlr-action-mode nil | ||
| 267 | "Major-mode for code in actions of the grammar. | ||
| 268 | The value is language-dependent, see `antlr-language-variables'.") | ||
| 269 | |||
| 270 | (defvar antlr-java-action-mode 'java-mode | ||
| 271 | "Value for `antlr-action-mode' when using language `antlr-java'.") | ||
| 272 | |||
| 273 | (defvar antlr-init-cc-mode 'java-mode | ||
| 274 | "Major-mode used to initialize the language variables of CC Mode. | ||
| 275 | Used as argument for `c-init-language-vars-for'. | ||
| 276 | The value is language-dependent, see `antlr-language-variables'.") | ||
| 277 | |||
| 278 | (defvar antlr-java-init-cc-mode 'java-mode | ||
| 279 | "Value for `antlr-init-cc-mode' when using language `antlr-java'.") | ||
| 280 | |||
| 281 | (defvar antlr-init-submode 'antlr-set-tabs | ||
| 282 | "Function used to initialize the action language. | ||
| 283 | Important for languages which do not depend on CC Mode. | ||
| 284 | The value is language-dependent, see `antlr-language-variables'.") | ||
| 285 | |||
| 286 | (defcustom antlr-language-alist ; is obsolete now | ||
| 287 | nil | ||
| 288 | "List of ANTLR's supported languages. Variable is UNUSED. | ||
| 132 | Each element in this list looks like | 289 | Each element in this list looks like |
| 133 | (MAJOR-MODE MODELINE-STRING OPTION-VALUE...) | 290 | (MAJOR-MODE MODELINE-STRING OPTION-VALUE...) |
| 134 | 291 | ||
| @@ -137,21 +294,7 @@ value of `antlr-language' if the first group in the string matched by | |||
| 137 | REGEXP in `antlr-language-limit-n-regexp' is one of the OPTION-VALUEs. | 294 | REGEXP in `antlr-language-limit-n-regexp' is one of the OPTION-VALUEs. |
| 138 | An OPTION-VALUE of nil denotes the fallback element. MODELINE-STRING is | 295 | An OPTION-VALUE of nil denotes the fallback element. MODELINE-STRING is |
| 139 | also displayed in the mode line next to \"Antlr\"." | 296 | also displayed in the mode line next to \"Antlr\"." |
| 140 | :type '(repeat (group :value (java-mode "") | 297 | :type '(sexp :tag "DO NOT CUSTOMIZE" :value nil)) |
| 141 | (function :tag "Major mode") | ||
| 142 | (string :tag "Mode line string") | ||
| 143 | (repeat :tag "ANTLR language option" :inline t | ||
| 144 | (choice (const :tag "Default" nil) | ||
| 145 | string ))))) | ||
| 146 | |||
| 147 | (defcustom antlr-language-limit-n-regexp | ||
| 148 | '(8192 . "language[ \t]*=[ \t]*\\(\"?[A-Z][A-Za-z_]*\"?\\)") | ||
| 149 | "Used to set a reasonable value for `antlr-language'. | ||
| 150 | Looks like \(LIMIT . REGEXP). Search for REGEXP from the beginning of | ||
| 151 | the buffer to LIMIT and use the first group in the matched string to set | ||
| 152 | the language according to `antlr-language-alist'." | ||
| 153 | :type '(cons (choice :tag "Limit" (const :tag "No" nil) (integer :value 0)) | ||
| 154 | regexp)) | ||
| 155 | 298 | ||
| 156 | 299 | ||
| 157 | ;;;=========================================================================== | 300 | ;;;=========================================================================== |
| @@ -175,7 +318,7 @@ they are only changed by \\[antlr-indent-command]." | |||
| 175 | (const :tag "Always" t) | 318 | (const :tag "Always" t) |
| 176 | (sexp :tag "With TAB" :format "%t" :value tab))) | 319 | (sexp :tag "With TAB" :format "%t" :value tab))) |
| 177 | 320 | ||
| 178 | (defcustom antlr-tab-offset-alist | 321 | (defcustom antlr-tab-offset-alist ; TODO: still advertise? |
| 179 | '((antlr-mode nil 4 nil) | 322 | '((antlr-mode nil 4 nil) |
| 180 | (java-mode "antlr" 4 nil)) | 323 | (java-mode "antlr" 4 nil)) |
| 181 | "Alist to determine whether to use ANTLR's convention for TABs. | 324 | "Alist to determine whether to use ANTLR's convention for TABs. |
| @@ -197,26 +340,59 @@ See `c-set-style' and for details, where the most interesting part in | |||
| 197 | `c-style-alist' is the value of `c-basic-offset'." | 340 | `c-style-alist' is the value of `c-basic-offset'." |
| 198 | :type '(choice (const nil) regexp)) | 341 | :type '(choice (const nil) regexp)) |
| 199 | 342 | ||
| 343 | (defvar antlr-base-offset-alist ; TODO: make a defcustom? | ||
| 344 | '((:header . 0) (:body . 2) (:exception . 1)) | ||
| 345 | "Influence the rule indentation of `antlr-indent-line'. | ||
| 346 | The default indentation of grammar lines are calculated by | ||
| 347 | `c-basic-offset', multiplied by: | ||
| 348 | - the level of the paren/brace/bracket depth, | ||
| 349 | - plus 0/2/1, depending on the position POS-SYMBOL inside the rule: | ||
| 350 | :header, :body, :exception part, customized by this variable. | ||
| 351 | - minus 1 if `antlr-indent-item-regexp' matches the beginning of the | ||
| 352 | line starting from the first non-whitespace. | ||
| 353 | |||
| 354 | Each element in this list is an element (POS-SYMBOL . OFFSET). | ||
| 355 | The following POS-SYMBOL can be: | ||
| 356 | - `:header', the rule header before `antlr-rule-body-start-op', | ||
| 357 | - `:colon' for `antlr-rule-body-start-op', the character starting | ||
| 358 | the rule body, | ||
| 359 | - `:body`, the rule body starting at `antlr-rule-body-start-op' | ||
| 360 | and ending with ';' | ||
| 361 | - `:exception', the part of the rule after the ';', see function | ||
| 362 | `antlr-skip-rule-postlude'. | ||
| 363 | |||
| 364 | `:header', `:body` and `:exception' must appear in the alist, | ||
| 365 | `:colon' is optional and its OFFSET defaults to the one from `:body`.") | ||
| 366 | |||
| 200 | (defcustom antlr-indent-item-regexp | 367 | (defcustom antlr-indent-item-regexp |
| 201 | "[]}):;|&]" ; & is local ANTLR extension (SGML's and-connector) | 368 | "[]}):;|]" |
| 202 | "Regexp matching lines which should be indented by one TAB less. | 369 | "Regexp matching lines which should be indented by one TAB less. |
| 203 | See `antlr-indent-line' and command \\[antlr-indent-command]." | 370 | See `antlr-indent-line' and command \\[antlr-indent-command]." |
| 204 | :type 'regexp) | 371 | :type 'regexp) |
| 205 | 372 | ||
| 206 | (defcustom antlr-indent-at-bol-alist | 373 | (defcustom antlr-indent-at-bol-alist ; TODO: make this pure custom option (define language-dependent vars as defaults) |
| 207 | ;; eval-when-compile not usable with defcustom... | 374 | ;; eval-when-compile not usable with defcustom... |
| 208 | '((java-mode . "\\(package\\|import\\)\\>") | 375 | '((java-mode . "\\(package\\|import\\)\\_>") |
| 209 | (c++-mode . "#\\(assert\\|cpu\\|define\\|endif\\|el\\(if\\|se\\)\\|i\\(dent\\|f\\(def\\|ndef\\)?\\|mport\\|nclude\\(_next\\)?\\)\\|line\\|machine\\|pragma\\|system\\|un\\(assert\\|def\\)\\|warning\\)\\>")) | 376 | (c++-mode . "#\\(assert\\|cpu\\|define\\|endif\\|el\\(if\\|se\\)\\|i\\(dent\\|f\\(def\\|ndef\\)?\\|mport\\|nclude\\(_next\\)?\\)\\|line\\|machine\\|pragma\\|system\\|un\\(assert\\|def\\)\\|warning\\)\\_>") |
| 377 | (c-mode . "#\\(assert\\|cpu\\|define\\|endif\\|el\\(if\\|se\\)\\|i\\(dent\\|f\\(def\\|ndef\\)?\\|mport\\|nclude\\(_next\\)?\\)\\|line\\|machine\\|pragma\\|system\\|un\\(assert\\|def\\)\\|warning\\)\\_>")) | ||
| 210 | "Alist of regexps matching lines are indented at column 0. | 378 | "Alist of regexps matching lines are indented at column 0. |
| 211 | Each element in this list looks like (MODE . REGEXP) where MODE is a | 379 | Each element in this list looks like (MODE . REGEXP) where MODE is a |
| 212 | function and REGEXP is a regular expression. | 380 | function and REGEXP is a regular expression. |
| 213 | 381 | ||
| 214 | If `antlr-language' equals to a MODE, the line starting at the first | 382 | If the value of `antlr-action-mode' equals to a MODE, the line starting |
| 215 | non-whitespace is matched by the corresponding REGEXP, and the line is | 383 | at the first non-whitespace is matched by the corresponding REGEXP, and |
| 216 | part of a header action, indent the line at column 0 instead according | 384 | the line is part of a header action, indent the line at column 0 instead |
| 217 | to the normal rules of `antlr-indent-line'." | 385 | of according to the normal rules of `antlr-indent-line'." |
| 218 | :type '(repeat (cons (function :tag "Major mode") regexp))) | 386 | :type '(repeat (cons (function :tag "Major mode") regexp))) |
| 219 | 387 | ||
| 388 | (defvar antlr-indent-action-line nil | ||
| 389 | ;; TODO: better call it with action start? | ||
| 390 | "Function which indents the current line in actions. | ||
| 391 | The function is called with the character address of the '{' starting | ||
| 392 | the action. | ||
| 393 | If nil, use CC mode to indent the line. | ||
| 394 | The value might be language-dependent, see `antlr-language-variables'.") | ||
| 395 | |||
| 220 | ;; adopt indentation to cc-engine | 396 | ;; adopt indentation to cc-engine |
| 221 | (defvar antlr-disabling-cc-syntactic-symbols | 397 | (defvar antlr-disabling-cc-syntactic-symbols |
| 222 | '(statement-block-intro | 398 | '(statement-block-intro |
| @@ -224,30 +400,30 @@ to the normal rules of `antlr-indent-line'." | |||
| 224 | arglist-intro brace-list-intro knr-argdecl-intro inher-intro | 400 | arglist-intro brace-list-intro knr-argdecl-intro inher-intro |
| 225 | objc-method-intro | 401 | objc-method-intro |
| 226 | block-close defun-close class-close brace-list-close arglist-close | 402 | block-close defun-close class-close brace-list-close arglist-close |
| 227 | inline-close extern-lang-close namespace-close)) | 403 | inline-close extern-lang-close namespace-close) |
| 404 | "CC Mode syntactic context symbols adopting the indentation by CC Mode.") | ||
| 228 | 405 | ||
| 229 | 406 | ||
| 230 | ;;;=========================================================================== | 407 | ;;;=========================================================================== |
| 231 | ;;; Options: customization | 408 | ;;; Options: customization |
| 232 | ;;;=========================================================================== | 409 | ;;;=========================================================================== |
| 233 | 410 | ||
| 411 | (defcustom antlr-end-of-defun-is-next nil | ||
| 412 | "Non-nil, if rule movement commands normally jump to beginning of rule. | ||
| 413 | If non-nil, both `antlr-end-of-rule' and `antlr-end-of-rule' jump | ||
| 414 | to beginning of a rule with no or positive prefix arg, and to the | ||
| 415 | end of a rule with negative prefix arg. | ||
| 416 | |||
| 417 | Default nil means: `antlr-end-of-rule' jumps to beginning of a | ||
| 418 | rule, `antlr-end-of-rule' jumps to end of a rule." | ||
| 419 | :type 'boolean) | ||
| 420 | |||
| 234 | (defcustom antlr-options-use-submenus t | 421 | (defcustom antlr-options-use-submenus t |
| 235 | "Non-nil, if the major mode menu should include option submenus. | 422 | "Non-nil, if the major mode menu should include option submenus. |
| 236 | If nil, the menu just includes a command to insert options. Otherwise, | 423 | If nil, the menu just includes a command to insert options. Otherwise, |
| 237 | it includes four submenus to insert file/grammar/rule/subrule options." | 424 | it includes four submenus to insert file/grammar/rule/subrule options." |
| 238 | :type 'boolean) | 425 | :type 'boolean) |
| 239 | 426 | ||
| 240 | (defcustom antlr-tool-version 20701 | ||
| 241 | "The version number of the Antlr tool. | ||
| 242 | The value is an integer of the form XYYZZ which stands for vX.YY.ZZ. | ||
| 243 | This variable is used to warn about non-supported options and to supply | ||
| 244 | version correct option values when using \\[antlr-insert-option]. | ||
| 245 | |||
| 246 | Don't use a number smaller than 20600 since the stored history of | ||
| 247 | Antlr's options starts with v2.06.00, see `antlr-options-alists'. You | ||
| 248 | can make this variable buffer-local." | ||
| 249 | :type 'integer) | ||
| 250 | |||
| 251 | (defcustom antlr-options-auto-colon t | 427 | (defcustom antlr-options-auto-colon t |
| 252 | "Non-nil, if `:' is inserted with a rule or subrule options section. | 428 | "Non-nil, if `:' is inserted with a rule or subrule options section. |
| 253 | A `:' is only inserted if this value is non-nil, if a rule or subrule | 429 | A `:' is only inserted if this value is non-nil, if a rule or subrule |
| @@ -256,14 +432,8 @@ subrule options section before, and if a `:' is not already present | |||
| 256 | after the section, ignoring whitespace, comments and the init action." | 432 | after the section, ignoring whitespace, comments and the init action." |
| 257 | :type 'boolean) | 433 | :type 'boolean) |
| 258 | 434 | ||
| 259 | (defcustom antlr-options-style nil | 435 | (defcustom antlr-options-style nil ; TODO: obsolete |
| 260 | "List of symbols which determine the style of option values. | 436 | "Obsolete user option." |
| 261 | If a style symbol is present, the corresponding option value is put into | ||
| 262 | quotes, i.e., represented as a string, otherwise it is represented as an | ||
| 263 | identifier. | ||
| 264 | |||
| 265 | The only style symbol used in the default value of `antlr-options-alist' | ||
| 266 | is `language-as-string'. See also `antlr-read-value'." | ||
| 267 | :type '(repeat (symbol :tag "Style symbol"))) | 437 | :type '(repeat (symbol :tag "Style symbol"))) |
| 268 | 438 | ||
| 269 | (defcustom antlr-options-push-mark t | 439 | (defcustom antlr-options-push-mark t |
| @@ -296,178 +466,311 @@ existing `=' won't be changed when changing an option value." | |||
| 296 | The standard value is (\"file\" \"grammar\" \"rule\" \"subrule\"). See | 466 | The standard value is (\"file\" \"grammar\" \"rule\" \"subrule\"). See |
| 297 | `antlr-options-alists'") | 467 | `antlr-options-alists'") |
| 298 | 468 | ||
| 299 | (defvar antlr-options-alists | 469 | (defvar antlr-options-alists nil |
| 470 | ;; TODO: distinguish between "no known option" (options{} is allowed), and | ||
| 471 | ;; does not exist (file options in v3 and v4) | ||
| 472 | "Definitions for Antlr's options of all four different kinds. | ||
| 473 | |||
| 474 | The value looks like \(FILE GRAMMAR RULE SUBRULE) where each FILE, | ||
| 475 | GRAMMAR, RULE, and SUBRULE is a list of option definitions of the | ||
| 476 | corresponding kind, i.e., looks like \(OPTION-DEF...). | ||
| 477 | |||
| 478 | Each OPTION-DEF looks like \(OPTION-NAME EXTRA-FN VALUE-SPEC...) which | ||
| 479 | defines a file/grammar/rule/subrule option with name OPTION-NAME. The | ||
| 480 | OPTION-NAMEs are used for the creation of the \"Insert XXX Option\" | ||
| 481 | submenus, see `antlr-options-use-submenus', and to allow the insertion | ||
| 482 | of the option name with completion when using \\[antlr-insert-option]. | ||
| 483 | |||
| 484 | If EXTRA-FN is a function, it is called at different phases of the | ||
| 485 | insertion with arguments \(PHASE OPTION-NAME). PHASE can have the | ||
| 486 | values `before-input' or `after-insertion', additional phases might be | ||
| 487 | defined in future versions of this mode. The phase `before-input' | ||
| 488 | occurs before the user is asked to insert a value. The phase | ||
| 489 | `after-insertion' occurs after the option value has been inserted. | ||
| 490 | EXTRA-FN might be called with additional arguments in future versions of | ||
| 491 | this mode. | ||
| 492 | |||
| 493 | Each specification VALUE-SPEC looks like \(VERSION READ-FN ARG...). The | ||
| 494 | last VALUE-SPEC in an OPTION-DEF whose VERSION is smaller or equal to | ||
| 495 | `antlr-tool-version' specifies how the user is asked for the value of | ||
| 496 | the option. | ||
| 497 | |||
| 498 | If READ-FN is nil, the only ARG is a string which is printed at the echo | ||
| 499 | area to guide the user what to insert at point. Otherwise, READ-FN is | ||
| 500 | called with arguments \(INIT-VALUE ARG...) to get the new value of the | ||
| 501 | option. INIT-VALUE is the old value of the option or nil. | ||
| 502 | |||
| 503 | The standard value contains the following functions as READ-FN: | ||
| 504 | `antlr-read-value' with ARGs = \(PROMPT AS-STRING TABLE) which reads a | ||
| 505 | general value, or `antlr-read-boolean' with ARGs = \(PROMPT TABLE) which | ||
| 506 | reads a boolean value or a member of TABLE. PROMPT is the prompt when | ||
| 507 | asking for a new value. If non-nil, TABLE is a table for completion or | ||
| 508 | a function evaluating to such a table. The return value is quoted if | ||
| 509 | AS-STRING is non-nil. | ||
| 510 | |||
| 511 | The value is tool-dependent, see `antlr-tool-version-variables'.") | ||
| 512 | |||
| 513 | (defvar antlr-v4-options-alists | ||
| 514 | ;; see https://github.com/antlr/antlr4 - doc/options.md | ||
| 515 | '(() ; no file options | ||
| 516 | (;; grammar options ------------------------------------------------------ | ||
| 517 | ("language" | ||
| 518 | ;; The target language for code generation. Default is Java. See Code | ||
| 519 | ;; Generation Targets for list of currently supported target languages. | ||
| 520 | antlr-language-option-extra antlr-read-language "Generated language: ") | ||
| 521 | ("tokenVocab" | ||
| 522 | ;; Where ANTLR should get predefined tokens and token types. Tree | ||
| 523 | ;; grammars need it to get the token types from the parser that creates | ||
| 524 | ;; its trees. Default value: Do not import token vocab. | ||
| 525 | nil antlr-read-value "Token vocabulary: ") | ||
| 526 | ("TokenLabelType" ; parser and tree only | ||
| 527 | ;; Set the type of all tree labels and tree-valued expressions. Without | ||
| 528 | ;; this option, trees are of type Object. TODO: Cross-reference default | ||
| 529 | ;; impl (org.antlr.runtime.tree.CommonTree in Java)? | ||
| 530 | nil antlr-read-value "Token type: ") | ||
| 531 | ("superClass" ; in combined grammar: for parser | ||
| 532 | ;; Set the superclass of the generated recognizer. Default value | ||
| 533 | ;; Lexer/Parser/TreeParser (org.antlr.runtime.Parser in Java)? | ||
| 534 | nil antlr-read-value "Super class: ") | ||
| 535 | ("contextSuperClass" | ||
| 536 | nil antlr-read-value "Rule context super class: ") | ||
| 537 | ("exportMacro" ; doc/cpp-target.md | ||
| 538 | antlr-c++-mode-extra antlr-read-value "Export macro: ")) | ||
| 539 | nil ; no rule option yet | ||
| 540 | nil ; no subrule options | ||
| 541 | ;; use ??, *?, +? for non-greedy subrules | ||
| 542 | ;; (but there are some greedy options in grammars-v4-master/...) | ||
| 543 | ;; rule element options in v4 are actually different (and have a different | ||
| 544 | ;; syntax): <optionname = value> - not yet supported | ||
| 545 | ;; after op: <assoc=left|right> | ||
| 546 | ;; after sempred: <fail={expr}> | ||
| 547 | ) | ||
| 548 | "Value for `antlr-options-alists' when using ANTLR v4.") | ||
| 549 | |||
| 550 | ;;; v3: | ||
| 551 | ;; https://theantlrguy.atlassian.net/wiki/display/ANTLR3/ANTLR+3+Wiki+Home | ||
| 552 | |||
| 553 | ;; $ANTLR3/tool/src/main/java/org/antlr/tool/Grammar.java | ||
| 554 | ;; https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Grammar+options | ||
| 555 | ;; https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Rule+and+subrule+options | ||
| 556 | (defvar antlr-v3-options-alists | ||
| 557 | '(() ; no file options | ||
| 558 | (;; grammar options ------------------------------------------------------ | ||
| 559 | ("language" | ||
| 560 | ;; The target language for code generation. Default is Java. See Code | ||
| 561 | ;; Generation Targets for list of currently supported target languages. | ||
| 562 | antlr-language-option-extra antlr-read-language "Generated language: ") | ||
| 563 | ("tokenVocab" | ||
| 564 | ;; Where ANTLR should get predefined tokens and token types. Tree | ||
| 565 | ;; grammars need it to get the token types from the parser that creates | ||
| 566 | ;; its trees. Default value: Do not import token vocab. | ||
| 567 | nil antlr-read-value "Token vocabulary: ") | ||
| 568 | ("output" ; parser and tree only | ||
| 569 | ;; The type of output the generated parser should return. Valid values | ||
| 570 | ;; are AST and template. TODO: Briefly, what are the interpretations of | ||
| 571 | ;; these values? Default value: nothing | ||
| 572 | nil antlr-read-value "Output type (AST or template): ") ; TODO: completion | ||
| 573 | ("TokenLabelType" ; parser and tree only | ||
| 574 | ;; Set the type of all tree labels and tree-valued expressions. Without | ||
| 575 | ;; this option, trees are of type Object. TODO: Cross-reference default | ||
| 576 | ;; impl (org.antlr.runtime.tree.CommonTree in Java)? | ||
| 577 | nil antlr-read-value "Token type: ") | ||
| 578 | ("superClass" ; in combined grammar: for parser | ||
| 579 | ;; Set the superclass of the generated recognizer. Default value | ||
| 580 | ;; Lexer/Parser/TreeParser (org.antlr.runtime.Parser in Java)? | ||
| 581 | nil antlr-read-value "Super class: ") | ||
| 582 | ("filter" ; lexer only | ||
| 583 | ;; In the lexer, this allows you to try a list of lexer rules in | ||
| 584 | ;; order. The first one that matches, wins. This is the token that | ||
| 585 | ;; nextToken() returns. If nothing matches, the lexer consumes a single | ||
| 586 | ;; character and tries the list of rules again. See Lexical filters for | ||
| 587 | ;; more., Default: false | ||
| 588 | nil antlr-read-boolean "Lexical filter? ") | ||
| 589 | ("rewrite" ; parser and tree only | ||
| 590 | ;; Valid values are true and false. Default is false. Use this option | ||
| 591 | ;; when your translator output looks very much like the input. Your | ||
| 592 | ;; actions can modify the TokenRewriteStream to insert, delete, or | ||
| 593 | ;; replace ranges of tokens with another object. Used in conjunction with | ||
| 594 | ;; output=template, you can very easily build translators that tweak | ||
| 595 | ;; input files. | ||
| 596 | nil antlr-read-value "Template rewrite: ") | ||
| 597 | ("k" ; parser and tree only | ||
| 598 | ;; Limit the lookahead depth for the recognizer to at most k | ||
| 599 | ;; symbols. This prevents the decision from using acyclic LL* DFA. | ||
| 600 | nil antlr-read-value "Lookahead depth: ") | ||
| 601 | ("backtrack" ; parser and tree only | ||
| 602 | ;; Valid values are true and false. Default is false. Taken from | ||
| 603 | ;; http://www.antlr.org:8080/pipermail/antlr-interest/2006-July/016818.html | ||
| 604 | ;; : The new feature (a big one) is the backtrack=true option for | ||
| 605 | ;; grammar, rule, and block that lets you type in any old crap and ANTLR | ||
| 606 | ;; will backtrack if it can't figure out what you meant. No errors are | ||
| 607 | ;; reported by antlr during analysis. It implicitly adds a syn pred in | ||
| 608 | ;; front of every production, using them only if static grammar LL* | ||
| 609 | ;; analysis fails. Syn pred code is not generated if the pred is not used | ||
| 610 | ;; in a decision. This is essentially a rapid prototyping mode. It is | ||
| 611 | ;; what I have used on the java.g. Oh, it doesn't memoize partial parses | ||
| 612 | ;; (i.e. rule parsing results) during backtracking automatically now. You | ||
| 613 | ;; must also say memoize=true. Can make a HUGE difference to turn on. | ||
| 614 | nil antlr-read-boolean "Use automatic backtracking if necessary? ") | ||
| 615 | ("memoize" ; parser and tree only | ||
| 616 | ;; Valid values are true and false. When backtracking, remember whether | ||
| 617 | ;; or not rule references succeed so that the same input position cannot | ||
| 618 | ;; be parsed more than once by the same rule. This effectively guarantees | ||
| 619 | ;; linear parsing when backtracking at the cost of more memory. TODO: | ||
| 620 | ;; Default value: false | ||
| 621 | nil antlr-read-boolean "Store backtracking calculations? ")) | ||
| 622 | (;; rule options --------------------------------------------------------- | ||
| 623 | ("backtrack" | ||
| 624 | nil antlr-read-boolean "Use automatic backtracking if necessary? ") | ||
| 625 | ("memoize" | ||
| 626 | nil antlr-read-boolean "Store backtracking calculations? ")) | ||
| 627 | (;; subrule options ------------------------------------------------------ | ||
| 628 | ("k" | ||
| 629 | nil antlr-read-value "Lookahead depth: ") | ||
| 630 | ("greedy" ; default true | ||
| 631 | nil antlr-read-boolean "Make this optional/loop subrule greedy? "))) | ||
| 632 | "Value for `antlr-options-alists' when using ANTLR v3.") | ||
| 633 | |||
| 634 | (defvar antlr-v2-options-alists | ||
| 300 | '(;; file options ---------------------------------------------------------- | 635 | '(;; file options ---------------------------------------------------------- |
| 301 | (("language" antlr-language-option-extra | 636 | (("language" |
| 302 | (20600 antlr-read-value | 637 | antlr-language-option-extra antlr-read-language "Generated language: ") |
| 303 | "Generated language: " language-as-string | ||
| 304 | (("Java") ("Cpp") ("HTML") ("Diagnostic"))) | ||
| 305 | (20700 antlr-read-value | ||
| 306 | "Generated language: " language-as-string | ||
| 307 | (("Java") ("Cpp") ("HTML") ("Diagnostic") ("Sather")))) | ||
| 308 | ("mangleLiteralPrefix" nil | 638 | ("mangleLiteralPrefix" nil |
| 309 | (20600 antlr-read-value | 639 | antlr-read-value "Prefix for literals (default LITERAL_): " t) |
| 310 | "Prefix for literals (default LITERAL_): " t)) | ||
| 311 | ("namespace" antlr-c++-mode-extra | 640 | ("namespace" antlr-c++-mode-extra |
| 312 | (20700 antlr-read-value | 641 | antlr-read-value "Wrap generated C++ code in namespace: " t) |
| 313 | "Wrap generated C++ code in namespace: " t)) | ||
| 314 | ("namespaceStd" antlr-c++-mode-extra | 642 | ("namespaceStd" antlr-c++-mode-extra |
| 315 | (20701 antlr-read-value | 643 | antlr-read-value "Replace ANTLR_USE_NAMESPACE(std) by: " t) |
| 316 | "Replace ANTLR_USE_NAMESPACE(std) by: " t)) | ||
| 317 | ("namespaceAntlr" antlr-c++-mode-extra | 644 | ("namespaceAntlr" antlr-c++-mode-extra |
| 318 | (20701 antlr-read-value | 645 | antlr-read-value "Replace ANTLR_USE_NAMESPACE(antlr) by: " t) |
| 319 | "Replace ANTLR_USE_NAMESPACE(antlr) by: " t)) | ||
| 320 | ("genHashLines" antlr-c++-mode-extra | 646 | ("genHashLines" antlr-c++-mode-extra |
| 321 | (20701 antlr-read-boolean | 647 | antlr-read-boolean "Include #line in generated C++ code? ") |
| 322 | "Include #line in generated C++ code? ")) | 648 | ("noConstructors" antlr-c++-mode-extra ; lexer only |
| 649 | antlr-read-boolean "Omit default constructors for generated classes? ") | ||
| 323 | ) | 650 | ) |
| 324 | ;; grammar options -------------------------------------------------------- | 651 | ;; grammar options -------------------------------------------------------- |
| 325 | (("k" nil | 652 | (("k" nil |
| 326 | (20600 antlr-read-value | 653 | antlr-read-value "Lookahead depth: ") |
| 327 | "Lookahead depth: ")) | ||
| 328 | ("importVocab" nil | 654 | ("importVocab" nil |
| 329 | (20600 antlr-read-value | 655 | antlr-read-value "Import vocabulary: ") |
| 330 | "Import vocabulary: ")) | 656 | ("exportVocab" nil antlr-read-value |
| 331 | ("exportVocab" nil | 657 | "Export vocabulary: ") |
| 332 | (20600 antlr-read-value | ||
| 333 | "Export vocabulary: ")) | ||
| 334 | ("testLiterals" nil ; lexer only | 658 | ("testLiterals" nil ; lexer only |
| 335 | (20600 antlr-read-boolean | 659 | antlr-read-boolean "Test each token against literals table? ") |
| 336 | "Test each token against literals table? ")) | ||
| 337 | ("defaultErrorHandler" nil ; not for lexer | 660 | ("defaultErrorHandler" nil ; not for lexer |
| 338 | (20600 antlr-read-boolean | 661 | antlr-read-boolean "Generate default exception handler for each rule? ") |
| 339 | "Generate default exception handler for each rule? ")) | ||
| 340 | ("codeGenMakeSwitchThreshold" nil | 662 | ("codeGenMakeSwitchThreshold" nil |
| 341 | (20600 antlr-read-value | 663 | antlr-read-value "Min number of alternatives for `switch': ") |
| 342 | "Min number of alternatives for `switch': ")) | ||
| 343 | ("codeGenBitsetTestThreshold" nil | 664 | ("codeGenBitsetTestThreshold" nil |
| 344 | (20600 antlr-read-value | 665 | antlr-read-value "Min size of lookahead set for bitset test: ") |
| 345 | "Min size of lookahead set for bitset test: ")) | ||
| 346 | ("analyzerDebug" nil | 666 | ("analyzerDebug" nil |
| 347 | (20600 antlr-read-boolean | 667 | antlr-read-boolean "Display debugging info during grammar analysis? ") |
| 348 | "Display debugging info during grammar analysis? ")) | ||
| 349 | ("codeGenDebug" nil | 668 | ("codeGenDebug" nil |
| 350 | (20600 antlr-read-boolean | 669 | antlr-read-boolean "Display debugging info during code generation? ") |
| 351 | "Display debugging info during code generation? ")) | ||
| 352 | ("buildAST" nil ; not for lexer | 670 | ("buildAST" nil ; not for lexer |
| 353 | (20600 antlr-read-boolean | 671 | antlr-read-boolean "Use automatic AST construction/transformation? ") |
| 354 | "Use automatic AST construction/transformation? ")) | ||
| 355 | ("ASTLabelType" nil ; not for lexer | 672 | ("ASTLabelType" nil ; not for lexer |
| 356 | (20600 antlr-read-value | 673 | antlr-read-value "Class of user-defined AST node: " t) |
| 357 | "Class of user-defined AST node: " t)) | ||
| 358 | ("charVocabulary" nil ; lexer only | 674 | ("charVocabulary" nil ; lexer only |
| 359 | (20600 nil | 675 | nil "Insert character vocabulary") |
| 360 | "Insert character vocabulary")) | ||
| 361 | ("interactive" nil | 676 | ("interactive" nil |
| 362 | (20600 antlr-read-boolean | 677 | antlr-read-boolean "Generate interactive lexer/parser? ") |
| 363 | "Generate interactive lexer/parser? ")) | ||
| 364 | ("caseSensitive" nil ; lexer only | 678 | ("caseSensitive" nil ; lexer only |
| 365 | (20600 antlr-read-boolean | 679 | antlr-read-boolean "Case significant when matching characters? ") |
| 366 | "Case significant when matching characters? ")) | ||
| 367 | ("caseSensitiveLiterals" nil ; lexer only | 680 | ("caseSensitiveLiterals" nil ; lexer only |
| 368 | (20600 antlr-read-boolean | 681 | antlr-read-boolean "Case significant when testing literals table? ") |
| 369 | "Case significant when testing literals table? ")) | 682 | ("classHeaderPrefix" nil |
| 683 | nil "Initial String for grammar class definition") | ||
| 370 | ("classHeaderSuffix" nil | 684 | ("classHeaderSuffix" nil |
| 371 | (20600 nil | 685 | nil "Additional string for grammar class definition") |
| 372 | "Additional string for grammar class definition")) | ||
| 373 | ("filter" nil ; lexer only | 686 | ("filter" nil ; lexer only |
| 374 | (20600 antlr-read-boolean | 687 | antlr-read-boolean "Skip rule (the name, true or false): " |
| 375 | "Skip rule (the name, true or false): " | 688 | antlr-grammar-tokens) |
| 376 | antlr-grammar-tokens)) | ||
| 377 | ("namespace" antlr-c++-mode-extra | 689 | ("namespace" antlr-c++-mode-extra |
| 378 | (20700 antlr-read-value | 690 | antlr-read-value "Wrap generated C++ code for grammar in namespace: " t) |
| 379 | "Wrap generated C++ code for grammar in namespace: " t)) | ||
| 380 | ("namespaceStd" antlr-c++-mode-extra | 691 | ("namespaceStd" antlr-c++-mode-extra |
| 381 | (20701 antlr-read-value | 692 | antlr-read-value "Replace ANTLR_USE_NAMESPACE(std) by: " t) |
| 382 | "Replace ANTLR_USE_NAMESPACE(std) by: " t)) | ||
| 383 | ("namespaceAntlr" antlr-c++-mode-extra | 693 | ("namespaceAntlr" antlr-c++-mode-extra |
| 384 | (20701 antlr-read-value | 694 | antlr-read-value "Replace ANTLR_USE_NAMESPACE(antlr) by: " t) |
| 385 | "Replace ANTLR_USE_NAMESPACE(antlr) by: " t)) | ||
| 386 | ("genHashLines" antlr-c++-mode-extra | 695 | ("genHashLines" antlr-c++-mode-extra |
| 387 | (20701 antlr-read-boolean | 696 | antlr-read-boolean "Include #line in generated C++ code? ") |
| 388 | "Include #line in generated C++ code? ")) | 697 | ("noConstructors" antlr-c++-mode-extra ; lexer only |
| 389 | ;;; ("autoTokenDef" nil ; parser only | 698 | antlr-read-boolean "Omit default constructors for generated classes? ") |
| 390 | ;;; (80000 antlr-read-boolean ; default: true | ||
| 391 | ;;; "Automatically define referenced token? ")) | ||
| 392 | ;;; ("keywordsMeltTo" nil ; parser only | ||
| 393 | ;;; (80000 antlr-read-value | ||
| 394 | ;;; "Change non-matching keywords to token type: ")) | ||
| 395 | ) | 699 | ) |
| 396 | ;; rule options ---------------------------------------------------------- | 700 | ;; rule options ---------------------------------------------------------- |
| 397 | (("testLiterals" nil ; lexer only | 701 | (("testLiterals" nil ; lexer only |
| 398 | (20600 antlr-read-boolean | 702 | antlr-read-boolean "Test this token against literals table? ") |
| 399 | "Test this token against literals table? ")) | ||
| 400 | ("defaultErrorHandler" nil ; not for lexer | 703 | ("defaultErrorHandler" nil ; not for lexer |
| 401 | (20600 antlr-read-boolean | 704 | antlr-read-boolean "Generate default exception handler for this rule? ") |
| 402 | "Generate default exception handler for this rule? ")) | ||
| 403 | ("ignore" nil ; lexer only | 705 | ("ignore" nil ; lexer only |
| 404 | (20600 antlr-read-value | 706 | antlr-read-value "In this rule, ignore tokens of type: " nil |
| 405 | "In this rule, ignore tokens of type: " nil | 707 | antlr-grammar-tokens) |
| 406 | antlr-grammar-tokens)) | ||
| 407 | ("paraphrase" nil ; lexer only | 708 | ("paraphrase" nil ; lexer only |
| 408 | (20600 antlr-read-value | 709 | antlr-read-value "In messages, replace name of this token by: " t) |
| 409 | "In messages, replace name of this token by: " t)) | ||
| 410 | ) | 710 | ) |
| 411 | ;; subrule options ------------------------------------------------------- | 711 | ;; subrule options ------------------------------------------------------- |
| 412 | (("warnWhenFollowAmbig" nil | 712 | (("warnWhenFollowAmbig" nil |
| 413 | (20600 antlr-read-boolean | 713 | antlr-read-boolean "Display warnings for ambiguities with FOLLOW? ") |
| 414 | "Display warnings for ambiguities with FOLLOW? ")) | ||
| 415 | ("generateAmbigWarnings" nil | 714 | ("generateAmbigWarnings" nil |
| 416 | (20600 antlr-read-boolean | 715 | antlr-read-boolean "Display warnings for ambiguities? ") |
| 417 | "Display warnings for ambiguities? ")) | ||
| 418 | ("greedy" nil | 716 | ("greedy" nil |
| 419 | (20700 antlr-read-boolean | 717 | antlr-read-boolean "Make this optional/loop subrule greedy? ") |
| 420 | "Make this optional/loop subrule greedy? ")) | ||
| 421 | )) | 718 | )) |
| 422 | "Definitions for Antlr's options of all four different kinds. | 719 | "Value for `antlr-options-alist' when using ANTLR v2.") |
| 423 | 720 | ||
| 424 | The value looks like \(FILE GRAMMAR RULE SUBRULE) where each FILE, | ||
| 425 | GRAMMAR, RULE, and SUBRULE is a list of option definitions of the | ||
| 426 | corresponding kind, i.e., looks like \(OPTION-DEF...). | ||
| 427 | 721 | ||
| 428 | Each OPTION-DEF looks like \(OPTION-NAME EXTRA-FN VALUE-SPEC...) which | 722 | ;;;=========================================================================== |
| 429 | defines a file/grammar/rule/subrule option with name OPTION-NAME. The | 723 | ;;; Run tool |
| 430 | OPTION-NAMEs are used for the creation of the \"Insert XXX Option\" | 724 | ;;;=========================================================================== |
| 431 | submenus, see `antlr-options-use-submenus', and to allow the insertion | ||
| 432 | of the option name with completion when using \\[antlr-insert-option]. | ||
| 433 | 725 | ||
| 434 | If EXTRA-FN is a function, it is called at different phases of the | 726 | (defvar antlr-tool-path nil ; TODO: make it a defcustom? |
| 435 | insertion with arguments \(PHASE OPTION-NAME). PHASE can have the | 727 | "Extra settings for environment variables $PATH and $LD_LIBRARY_PATH.") |
| 436 | values `before-input' or `after-insertion', additional phases might be | ||
| 437 | defined in future versions of this mode. The phase `before-input' | ||
| 438 | occurs before the user is asked to insert a value. The phase | ||
| 439 | `after-insertion' occurs after the option value has been inserted. | ||
| 440 | EXTRA-FN might be called with additional arguments in future versions of | ||
| 441 | this mode. | ||
| 442 | 728 | ||
| 443 | Each specification VALUE-SPEC looks like \(VERSION READ-FN ARG...). The | 729 | (defvar antlr-compilation-mode nil |
| 444 | last VALUE-SPEC in an OPTION-DEF whose VERSION is smaller or equal to | 730 | "Mode used for compile output of \\[antlr-run-tool].") |
| 445 | `antlr-tool-version' specifies how the user is asked for the value of | ||
| 446 | the option. | ||
| 447 | 731 | ||
| 448 | If READ-FN is nil, the only ARG is a string which is printed at the echo | 732 | (defvar antlr-compilation-error-regexp-alist nil |
| 449 | area to guide the user what to insert at point. Otherwise, READ-FN is | 733 | "If non-nil, used instead `compilation-error-regexp-alist'`. |
| 450 | called with arguments \(INIT-VALUE ARG...) to get the new value of the | 734 | The value might be tool-dependent, see `antlr-tool-version-variables'.") |
| 451 | option. INIT-VALUE is the old value of the option or nil. | ||
| 452 | 735 | ||
| 453 | The standard value contains the following functions as READ-FN: | 736 | (defvar antlr-v4-compilation-error-regexp-alist |
| 454 | `antlr-read-value' with ARGs = \(PROMPT AS-STRING TABLE) which reads a | 737 | '(("\\(?:[eE]rror\\|\\([wW]arning\\)\\)[ \t]*([0-9]+):[ \t]*\ |
| 455 | general value, or `antlr-read-boolean' with ARGs = \(PROMPT TABLE) which | 738 | \\([^\n:]+\\):\\([0-9]+\\):\\([0-9]+\\)" 2 3 4 (1)) |
| 456 | reads a boolean value or a member of TABLE. PROMPT is the prompt when | 739 | gnu) |
| 457 | asking for a new value. If non-nil, TABLE is a table for completion or | 740 | "Value for `antlr-compilation-error-regexp-alist' when using ANTLR v4.") |
| 458 | a function evaluating to such a table. The return value is quoted if | ||
| 459 | AS-STRING is non-nil and is either t or a symbol which is a member of | ||
| 460 | `antlr-options-style'.") | ||
| 461 | 741 | ||
| 742 | (defcustom antlr-run-tool-on-buffer-file t ; was nil before 3.2.0 | ||
| 743 | "Non-nil, if \\[antlr-run-tool] runs on the file for the current buffer. | ||
| 744 | If nil, the provided tool command must include the file name." | ||
| 745 | :type 'boolean) | ||
| 462 | 746 | ||
| 463 | ;;;=========================================================================== | 747 | (defcustom antlr-tool-command nil |
| 464 | ;;; Run tool, create Makefile dependencies | 748 | "Command used in \\[antlr-run-tool] to run the Antlr tool. |
| 465 | ;;;=========================================================================== | 749 | This variable should include all options passed to Antlr except the |
| 750 | option \"-glib\" which is automatically suggested if necessary. | ||
| 751 | |||
| 752 | OBSOLETE as user option - customize version dependent user options." | ||
| 753 | :type 'string) | ||
| 754 | |||
| 755 | (defcustom antlr-v4-tool-command "java org.antlr.v4.Tool" | ||
| 756 | ;; you probably also need to add s/th like | ||
| 757 | ;; "-cp /usr/local/lib/antlr-4.6-complete.jar" to the string | ||
| 758 | "Command used in \\[antlr-run-tool] to run the Antlr tool. | ||
| 759 | This variable should include all options passed to Antlr. | ||
| 760 | Value for `antlr-tool-command' when using ANTLR v4." | ||
| 761 | :type 'string) | ||
| 762 | |||
| 763 | (defcustom antlr-v3-tool-command "java org.antlr.Tool" | ||
| 764 | "Command used in \\[antlr-run-tool] to run the Antlr tool. | ||
| 765 | This variable should include all options passed to Antlr. | ||
| 766 | Value for `antlr-tool-command' when using ANTLR v3." | ||
| 767 | :type 'string) | ||
| 466 | 768 | ||
| 467 | (defcustom antlr-tool-command "java antlr.Tool" | 769 | (defcustom antlr-v2-tool-command "java antlr.Tool" |
| 468 | "Command used in \\[antlr-run-tool] to run the Antlr tool. | 770 | "Command used in \\[antlr-run-tool] to run the Antlr tool. |
| 469 | This variable should include all options passed to Antlr except the | 771 | This variable should include all options passed to Antlr except the |
| 470 | option \"-glib\" which is automatically suggested if necessary." | 772 | option \"-glib\" which is automatically suggested if necessary. |
| 773 | Value for `antlr-tool-command' when using ANTLR v2." | ||
| 471 | :type 'string) | 774 | :type 'string) |
| 472 | 775 | ||
| 473 | (defcustom antlr-ask-about-save t | 776 | (defcustom antlr-ask-about-save t |
| @@ -475,9 +778,18 @@ option \"-glib\" which is automatically suggested if necessary." | |||
| 475 | Otherwise, it saves all modified buffers before running without asking." | 778 | Otherwise, it saves all modified buffers before running without asking." |
| 476 | :type 'boolean) | 779 | :type 'boolean) |
| 477 | 780 | ||
| 781 | |||
| 782 | ;;;=========================================================================== | ||
| 783 | ;;; Makefile creation (ANTLR v2 only) | ||
| 784 | ;;;=========================================================================== | ||
| 785 | |||
| 786 | ;; TODO: make it a variable only (no `defcustom') | ||
| 478 | (defcustom antlr-makefile-specification | 787 | (defcustom antlr-makefile-specification |
| 479 | '("\n" ("GENS" "GENS%d" " \\\n\t") "$(ANTLR)") | 788 | '("\n" ("GENS" "GENS%d" " \\\n\t") "$(ANTLR)") |
| 480 | "Variable to specify the appearance of the generated makefile rules. | 789 | "Variable to specify the appearance of the generated makefile rules. |
| 790 | This variable is only used or ANTLR v2 grammars. For v3 and v4 | ||
| 791 | grammars, run the ANTLR tool with option \"--depend\". | ||
| 792 | |||
| 481 | This variable influences the output of \\[antlr-show-makefile-rules]. | 793 | This variable influences the output of \\[antlr-show-makefile-rules]. |
| 482 | It looks like \(RULE-SEP GEN-VAR-SPEC COMMAND). | 794 | It looks like \(RULE-SEP GEN-VAR-SPEC COMMAND). |
| 483 | 795 | ||
| @@ -507,6 +819,8 @@ COUNT starts with 1. GEN-SEP is used to separate long variable values." | |||
| 507 | '((java-mode ("%sTokenTypes.java") ("%s.java")) | 819 | '((java-mode ("%sTokenTypes.java") ("%s.java")) |
| 508 | (c++-mode ("%sTokenTypes.hpp") ("%s.cpp" "%s.hpp"))) | 820 | (c++-mode ("%sTokenTypes.hpp") ("%s.cpp" "%s.hpp"))) |
| 509 | "Language dependent formats which specify generated files. | 821 | "Language dependent formats which specify generated files. |
| 822 | This variable is only used or ANTLR v2 grammars. | ||
| 823 | |||
| 510 | Each element in this list looks like | 824 | Each element in this list looks like |
| 511 | (MAJOR-MODE (VOCAB-FILE-FORMAT...) (CLASS-FILE-FORMAT...)). | 825 | (MAJOR-MODE (VOCAB-FILE-FORMAT...) (CLASS-FILE-FORMAT...)). |
| 512 | 826 | ||
| @@ -521,6 +835,8 @@ CLASS/%s the generated file for each grammar class CLASS.") | |||
| 521 | 835 | ||
| 522 | (defvar antlr-special-file-formats '("%sTokenTypes.txt" "expanded%s.g") | 836 | (defvar antlr-special-file-formats '("%sTokenTypes.txt" "expanded%s.g") |
| 523 | "Language independent formats which specify generated files. | 837 | "Language independent formats which specify generated files. |
| 838 | This variable is only used or ANTLR v2 grammars. | ||
| 839 | |||
| 524 | The value looks like \(VOCAB-FILE-FORMAT EXPANDED-GRAMMAR-FORMAT). | 840 | The value looks like \(VOCAB-FILE-FORMAT EXPANDED-GRAMMAR-FORMAT). |
| 525 | 841 | ||
| 526 | VOCAB-FILE-FORMAT is a format string, it specifies with substitution | 842 | VOCAB-FILE-FORMAT is a format string, it specifies with substitution |
| @@ -535,6 +851,8 @@ formats.") | |||
| 535 | 851 | ||
| 536 | (defvar antlr-unknown-file-formats '("?%s?.g" "?%s?") | 852 | (defvar antlr-unknown-file-formats '("?%s?.g" "?%s?") |
| 537 | "Formats which specify the names of unknown files. | 853 | "Formats which specify the names of unknown files. |
| 854 | This variable is only used or ANTLR v2 grammars. | ||
| 855 | |||
| 538 | The value looks like \(SUPER-GRAMMAR-FILE-FORMAT SUPER-EVOCAB-FORMAT). | 856 | The value looks like \(SUPER-GRAMMAR-FILE-FORMAT SUPER-EVOCAB-FORMAT). |
| 539 | 857 | ||
| 540 | SUPER-GRAMMAR-FORMAT is a format string, it specifies with substitution | 858 | SUPER-GRAMMAR-FORMAT is a format string, it specifies with substitution |
| @@ -551,6 +869,8 @@ of above mentioned class SUPER.") | |||
| 551 | ## the current directory or is defined more than once. Please replace | 869 | ## the current directory or is defined more than once. Please replace |
| 552 | ## these filenames by the grammar files (and their exportVocab).\n\n" | 870 | ## these filenames by the grammar files (and their exportVocab).\n\n" |
| 553 | "String indicating the existence of unknown files in the Makefile. | 871 | "String indicating the existence of unknown files in the Makefile. |
| 872 | This variable is only used or ANTLR v2 grammars. | ||
| 873 | |||
| 554 | See \\[antlr-show-makefile-rules] and `antlr-unknown-file-formats'.") | 874 | See \\[antlr-show-makefile-rules] and `antlr-unknown-file-formats'.") |
| 555 | 875 | ||
| 556 | (defvar antlr-help-rules-intro | 876 | (defvar antlr-help-rules-intro |
| @@ -560,6 +880,8 @@ They are stored in the kill-ring, i.e., you can insert them with C-y | |||
| 560 | into your Makefile. You can also invoke \\[antlr-show-makefile-rules] | 880 | into your Makefile. You can also invoke \\[antlr-show-makefile-rules] |
| 561 | from within a Makefile to insert them directly.\n\n\n" | 881 | from within a Makefile to insert them directly.\n\n\n" |
| 562 | "Introduction to use with \\[antlr-show-makefile-rules]. | 882 | "Introduction to use with \\[antlr-show-makefile-rules]. |
| 883 | This variable is only used or ANTLR v2 grammars. | ||
| 884 | |||
| 563 | It is a format string and used with substitution DIRECTORY/%s where | 885 | It is a format string and used with substitution DIRECTORY/%s where |
| 564 | DIRECTORY is the name of the current directory.") | 886 | DIRECTORY is the name of the current directory.") |
| 565 | 887 | ||
| @@ -568,10 +890,11 @@ DIRECTORY is the name of the current directory.") | |||
| 568 | ;;; Menu | 890 | ;;; Menu |
| 569 | ;;;=========================================================================== | 891 | ;;;=========================================================================== |
| 570 | 892 | ||
| 571 | (defcustom antlr-imenu-name t ; (featurep 'xemacs) ; TODO: Emacs-21 bug? | 893 | (defcustom antlr-imenu-name t |
| 572 | "Non-nil, if a \"Index\" menu should be added to the menubar. | 894 | "Non-nil, if a \"Index\" menu should be added to the menubar. |
| 573 | If it is a string, it is used instead \"Index\". Requires package | 895 | If it is a string, it is used instead \"Index\". Requires package |
| 574 | imenu." | 896 | imenu. For sorted menu entries, customize variable |
| 897 | `imenu-sort-function'." | ||
| 575 | :type '(choice (const :tag "No menu" nil) | 898 | :type '(choice (const :tag "No menu" nil) |
| 576 | (const :tag "Index menu" t) | 899 | (const :tag "Index menu" t) |
| 577 | (string :tag "Other menu name"))) | 900 | (string :tag "Other menu name"))) |
| @@ -584,8 +907,9 @@ imenu." | |||
| 584 | (define-key map "\C-c\C-a" 'antlr-beginning-of-body) | 907 | (define-key map "\C-c\C-a" 'antlr-beginning-of-body) |
| 585 | (define-key map "\C-c\C-e" 'antlr-end-of-body) | 908 | (define-key map "\C-c\C-e" 'antlr-end-of-body) |
| 586 | (define-key map "\C-c\C-f" 'subword-forward) | 909 | (define-key map "\C-c\C-f" 'subword-forward) |
| 587 | (define-key map "\C-c\C-b" 'c-backward-into-nomenclature) | 910 | (define-key map "\C-c\C-b" 'subword-backward) |
| 588 | (define-key map "\C-c\C-c" 'comment-region) | 911 | (define-key map "\C-c\C-c" 'comment-region) |
| 912 | (define-key map "\C-c\C-k" 'antlr-insert-keyword-rule) | ||
| 589 | (define-key map "\C-c\C-v" 'antlr-hide-actions) | 913 | (define-key map "\C-c\C-v" 'antlr-hide-actions) |
| 590 | (define-key map "\C-c\C-r" 'antlr-run-tool) | 914 | (define-key map "\C-c\C-r" 'antlr-run-tool) |
| 591 | (define-key map "\C-c\C-o" 'antlr-insert-option) | 915 | (define-key map "\C-c\C-o" 'antlr-insert-option) |
| @@ -609,12 +933,16 @@ imenu." | |||
| 609 | `("Antlr" | 933 | `("Antlr" |
| 610 | ,@(if antlr-options-use-submenus | 934 | ,@(if antlr-options-use-submenus |
| 611 | `(("Insert File Option" | 935 | `(("Insert File Option" |
| 936 | :visible (elt antlr-options-alists 0) | ||
| 612 | :filter ,(lambda (x) (antlr-options-menu-filter 1 x))) | 937 | :filter ,(lambda (x) (antlr-options-menu-filter 1 x))) |
| 613 | ("Insert Grammar Option" | 938 | ("Insert Grammar Option" |
| 939 | :visible (elt antlr-options-alists 1) | ||
| 614 | :filter ,(lambda (x) (antlr-options-menu-filter 2 x))) | 940 | :filter ,(lambda (x) (antlr-options-menu-filter 2 x))) |
| 615 | ("Insert Rule Option" | 941 | ("Insert Rule Option" |
| 942 | :visible (elt antlr-options-alists 2) | ||
| 616 | :filter ,(lambda (x) (antlr-options-menu-filter 3 x))) | 943 | :filter ,(lambda (x) (antlr-options-menu-filter 3 x))) |
| 617 | ("Insert Subrule Option" | 944 | ("Insert Subrule Option" |
| 945 | :visible (elt antlr-options-alists 3) | ||
| 618 | :filter ,(lambda (x) (antlr-options-menu-filter 4 x))) | 946 | :filter ,(lambda (x) (antlr-options-menu-filter 4 x))) |
| 619 | "---") | 947 | "---") |
| 620 | '(["Insert Option" antlr-insert-option | 948 | '(["Insert Option" antlr-insert-option |
| @@ -629,8 +957,8 @@ imenu." | |||
| 629 | "---" | 957 | "---" |
| 630 | ["Backward Statement" c-beginning-of-statement t] | 958 | ["Backward Statement" c-beginning-of-statement t] |
| 631 | ["Forward Statement" c-end-of-statement t] | 959 | ["Forward Statement" c-end-of-statement t] |
| 632 | ["Backward Into Nomencl." c-backward-into-nomenclature t] | 960 | ["Backward Subword" subword-forward t] |
| 633 | ["Forward Into Nomencl." subword-forward t]) | 961 | ["Forward Subword" subword-backward t]) |
| 634 | ["Indent Region" indent-region | 962 | ["Indent Region" indent-region |
| 635 | :active (and (not buffer-read-only) (c-region-is-active-p))] | 963 | :active (and (not buffer-read-only) (c-region-is-active-p))] |
| 636 | ["Comment Out Region" comment-region | 964 | ["Comment Out Region" comment-region |
| @@ -644,26 +972,177 @@ imenu." | |||
| 644 | ["Unhide All Actions" (antlr-hide-actions 0) t] | 972 | ["Unhide All Actions" (antlr-hide-actions 0) t] |
| 645 | "---" | 973 | "---" |
| 646 | ["Run Tool on Grammar" antlr-run-tool t] | 974 | ["Run Tool on Grammar" antlr-run-tool t] |
| 647 | ["Show Makefile Rules" antlr-show-makefile-rules t] | 975 | ["Show Makefile Rules" antlr-show-makefile-rules (eq antlr-tool-version 'antlr-v2)] |
| 648 | "---" | 976 | "---" |
| 649 | ["Customize Antlr" (customize-group 'antlr) t])) | 977 | ["Customize Antlr" (customize-group 'antlr) t])) |
| 650 | 978 | ||
| 651 | 979 | ||
| 652 | ;;;=========================================================================== | 980 | ;;;=========================================================================== |
| 653 | ;;; font-lock | 981 | ;;; basic syntax |
| 982 | ;;;=========================================================================== | ||
| 983 | |||
| 984 | (defvar antlr-syntax-propertize nil | ||
| 985 | "Specification used to apply ‘syntax-table’ text properties. | ||
| 986 | When non-nil, the value looks like \(MAIN EXTEND-REGION MULTILINE-CHAR). | ||
| 987 | |||
| 988 | MAIN is used as value for `syntax-propertize-function'. | ||
| 989 | |||
| 990 | EXTEND-REGION is for `syntax-propertize-extend-region-functions'; | ||
| 991 | it is appended to the existing value if it is a function, or | ||
| 992 | replaces the value otherwise, t leaves the value untouched. | ||
| 993 | |||
| 994 | MULTILINE-CHAR is for `c-multiline-string-start-char' if non-nil; | ||
| 995 | if that variable already has a non-nil value, it is set to t. | ||
| 996 | |||
| 997 | The value is tool-dependent, see `antlr-tool-version-variables'.") | ||
| 998 | |||
| 999 | (defvar antlr-v4-syntax-propertize | ||
| 1000 | '(antlr-syntax-propertize-charsets (antlr-syntax-propertize-wholerule)) | ||
| 1001 | "Value for `antlr-syntax-propertize' when using ANTLR v4.") | ||
| 1002 | |||
| 1003 | (defvar antlr-v3-syntax-propertize | ||
| 1004 | '(antlr-syntax-propertize-template-literals syntax-propertize-multiline ?<) | ||
| 1005 | "Value for `antlr-syntax-propertize' when using ANTLR v3.") | ||
| 1006 | |||
| 1007 | (defvar antlr-v2-syntax-propertize nil | ||
| 1008 | "Value for `antlr-syntax-propertize' when using ANTLR v2.") | ||
| 1009 | |||
| 1010 | (defvar antlr-skip-line-regexp nil | ||
| 1011 | "Regexp matching special declarations after the grammar header. | ||
| 1012 | The value is tool-dependent, see `antlr-tool-version-variables'.") | ||
| 1013 | |||
| 1014 | (defvar antlr-v4-skip-line-regexp "[ \t]*import[ \t]+[^][}{)(^\n;]+;" | ||
| 1015 | "Value for `antlr-skip-line-regexp' when using ANTLR v4.") | ||
| 1016 | |||
| 1017 | (defvar antlr-v3-skip-line-regexp "[ \t]*scope[ \t]+[^][}{)(^\n;]+;" | ||
| 1018 | "Value for `antlr-skip-line-regexp' when using ANTLR v3.") | ||
| 1019 | |||
| 1020 | (defvar antlr-rule-body-start-op ":" | ||
| 1021 | "Single-character string which starts the rule body.") | ||
| 1022 | |||
| 1023 | |||
| 1024 | ;;;=========================================================================== | ||
| 1025 | ;;; tool- and language-dependent font-lock | ||
| 1026 | ;;;=========================================================================== | ||
| 1027 | |||
| 1028 | (defvar antlr-font-lock-symbol-regexp nil | ||
| 1029 | "Regexp matching symbol declarations in the grammar, or nil. | ||
| 1030 | If a regexp, the buffer content matched by the first regexp group | ||
| 1031 | is highlighted with face `antlr-keyword' and the content matched | ||
| 1032 | by the second regexp group is highlighted with face | ||
| 1033 | `antlr-symbol'. | ||
| 1034 | |||
| 1035 | The value is tool-dependent, see `antlr-tool-version-variables'.") | ||
| 1036 | |||
| 1037 | (defvar antlr-v4-font-lock-symbol-regexp | ||
| 1038 | "^[ \t]*\\(mode\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\sw*\\)?" | ||
| 1039 | "Value for `antlr-font-lock-symbol-regexp' when using ANTLR v4.") | ||
| 1040 | |||
| 1041 | (defvar antlr-v3-font-lock-symbol-regexp | ||
| 1042 | "^[ \t]*\\(scope\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\sw*\\)?" | ||
| 1043 | "Value for `antlr-font-lock-symbol-regexp' when using ANTLR v3.") | ||
| 1044 | |||
| 1045 | (defcustom antlr-font-lock-literal-regexp | ||
| 1046 | ;; actually, in v3/v4 it is 'L' only | ||
| 1047 | "\\([\"']\\)\\(\\sw\\(\\sw\\|-\\)*\\|\\(\\s_\\|\\s.\\)+\\|\\s(\\|\\s)\\)\\1" | ||
| 1048 | "Regexp matching literals with special syntax highlighting, or nil. | ||
| 1049 | If nil, there is no special syntax highlighting for some literals. | ||
| 1050 | Otherwise, it should be a regular expression which must contain at least | ||
| 1051 | two regexp groups. The string matched by the second group is highlighted | ||
| 1052 | with face `antlr-literal'." | ||
| 1053 | :type '(choice (const :tag "None" nil) regexp)) | ||
| 1054 | |||
| 1055 | (defvar antlr-font-lock-attribute-regexp "\\(\\$\\sw+\\)" | ||
| 1056 | "Regexp matching attributes within actions with special syntax highlighting. | ||
| 1057 | If nil, there is no special syntax highlighting for attributes. | ||
| 1058 | Otherwise, it should be a regular expression which must contain at least | ||
| 1059 | one regexp group. The string matched by the first group is highlighted | ||
| 1060 | with face `antlr-attribute'.") | ||
| 1061 | |||
| 1062 | (defvar antlr-font-lock-negation-regexp "\\.\\.\\|\\([.~]\\)" | ||
| 1063 | "Regexp whose first regexp group matches negation. | ||
| 1064 | The negation is highlighted with face `font-lock-negation-char-face'.") | ||
| 1065 | |||
| 1066 | (defvar antlr-font-lock-syntax-spec '("\\(->\\|[!^]\\)") | ||
| 1067 | "Specification for highlighting syntax symbols for AST creation: !, ^, ->. | ||
| 1068 | If non-nil, the value looks like (REGEXP). Syntax symbols are matched | ||
| 1069 | by the first regexp group in REGEXP, and are highlighted with face | ||
| 1070 | `antlr-syntax'.") | ||
| 1071 | ;; TODO: in v4, highlight lexer commands after "->" | ||
| 1072 | |||
| 1073 | (defvar antlr-grammar-header-regexp | ||
| 1074 | "\\<\\(lexer[ \t]+grammar\\|parser[ \t]+grammar\\|tree[ \t]+grammar\\|grammar\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\(?:\\sw\\|\\s_\\)*\\)[ \t]*;" | ||
| 1075 | "Regexp matching class headers. | ||
| 1076 | The value might be tool-dependent, see `antlr-tool-version-variables'.") | ||
| 1077 | |||
| 1078 | (defvar antlr-v2-grammar-header-regexp | ||
| 1079 | "\\<\\(class\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\(?:\\sw\\|\\s_\\)*\\)[ \t]+\\(extends\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\(?:\\sw\\|\\s_\\)*\\)[ \t]*;" | ||
| 1080 | "Value for `antlr-grammar-header-regexp' when using ANTLR v2.") | ||
| 1081 | |||
| 1082 | (defvar antlr-ruleref-assign-regexp "\\(\\sw+\\)[ \t]*\\(\\+?=\\)?" | ||
| 1083 | "Regexp matching rule references or their optional labels. | ||
| 1084 | If the second regexp group does not match, the first regexp group | ||
| 1085 | matches a rule reference, which is highlighted with face `antlr-tokenref' | ||
| 1086 | for token rules, and face `antlr-ruleref' for other rules. | ||
| 1087 | |||
| 1088 | If there is no third regexp group or it does not match, the first | ||
| 1089 | regexp group matches a rule label, which is highlighted with face | ||
| 1090 | `font-lock-variable-name-face'. | ||
| 1091 | |||
| 1092 | The value might be tool-dependent, see `antlr-tool-version-variables'.") | ||
| 1093 | |||
| 1094 | (defvar antlr-v2-ruleref-assign-regexp "\\(\\sw+\\)[ \t]*\\([:]\\|\\(=\\)\\)?" | ||
| 1095 | "Value for `antlr-ruleref-assign-regexp' when using ANTLR v2.") | ||
| 1096 | |||
| 1097 | (defvar antlr-action-font-lock-keywords nil | ||
| 1098 | "Font Lock keywords used for the actions in the grammar. | ||
| 1099 | The value should be like the first element of `font-lock-defaults. | ||
| 1100 | See also `antlr-font-lock-maximum-decoration'. | ||
| 1101 | The value might be language-dependent, see `antlr-language-variables'.") | ||
| 1102 | |||
| 1103 | (defvar antlr-java-action-font-lock-keywords | ||
| 1104 | '(antlr-no-action-keywords | ||
| 1105 | java-font-lock-keywords-1 java-font-lock-keywords-2 | ||
| 1106 | java-font-lock-keywords-3) | ||
| 1107 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-java'.") | ||
| 1108 | |||
| 1109 | (defvar antlr-action-scope-names '("lexer" "parser" "treeparser") | ||
| 1110 | "Valid ANTLR action scope names.") | ||
| 1111 | |||
| 1112 | (defvar antlr-action-names t | ||
| 1113 | "Valid ANTLR action names. | ||
| 1114 | This is a string list or t, which means that any name is valid. | ||
| 1115 | The value might be language-dependent, see `antlr-language-variables'.") | ||
| 1116 | |||
| 1117 | ;; see $(ANTLR3)/tool/src/main/java/org/antlr/codegen/$(LANGUAGE)Target.java-isValidActionScope() | ||
| 1118 | ;; or $(ANTLR3.JAR)/antlr3-jar/org/antlr/codegen/templates/, fine-grep for "actions\." | ||
| 1119 | (defvar antlr-java-action-names | ||
| 1120 | '("init" "after" "header" "members" "rulecatch" "synpredgate") | ||
| 1121 | "Valid ANTLR action names in Java. | ||
| 1122 | Value for `antlr-action-names' when using language `antlr-java'.") | ||
| 1123 | |||
| 1124 | (defvar antlr-token-identifier-p 'antlr-upcase-p | ||
| 1125 | "Function for syntax highlighting to distinguish token refs from rule refs. | ||
| 1126 | Function is called with the first character of the identifier; it should | ||
| 1127 | return non-nil if the identifier is a token reference.") | ||
| 1128 | |||
| 1129 | |||
| 1130 | ;;;=========================================================================== | ||
| 1131 | ;;; general font-lock | ||
| 654 | ;;;=========================================================================== | 1132 | ;;;=========================================================================== |
| 655 | 1133 | ||
| 656 | (defcustom antlr-font-lock-maximum-decoration 'inherit | 1134 | (defcustom antlr-font-lock-maximum-decoration 'inherit |
| 657 | "The maximum decoration level for fontifying actions. | 1135 | "The maximum decoration level for fontifying actions. |
| 658 | Value `none' means, do not fontify actions, just normal grammar code | 1136 | Value `none' means, do not fontify actions, just normal grammar |
| 659 | according to `antlr-font-lock-additional-keywords'. Value `inherit' | 1137 | code according to `antlr-font-lock-additional-keywords' and |
| 660 | means, use value of `font-lock-maximum-decoration'. Any other value is | 1138 | `antlr-font-lock-late-keywords'. Value `inherit' means, use |
| 1139 | value of `font-lock-maximum-decoration'. Any other value is | ||
| 661 | interpreted as in `font-lock-maximum-decoration' with no level-0 | 1140 | interpreted as in `font-lock-maximum-decoration' with no level-0 |
| 662 | fontification, see `antlr-font-lock-keywords-alist'. | 1141 | fontification, see `antlr-font-lock-keywords-alist'. |
| 663 | 1142 | ||
| 664 | While calculating the decoration level for actions, `major-mode' is | 1143 | While calculating the decoration level for actions, `major-mode' is |
| 665 | bound to `antlr-language'. For example, with value | 1144 | bound to the value of `antlr-action-mode'. For example, with value |
| 666 | ((java-mode . 2) (c++-mode . 0)) | 1145 | ((java-mode \. 2) (c++-mode \. 0)) |
| 667 | Java actions are fontified with level 2 and C++ actions are not | 1146 | Java actions are fontified with level 2 and C++ actions are not |
| 668 | fontified at all." | 1147 | fontified at all." |
| 669 | :type '(choice (const :tag "None" none) | 1148 | :type '(choice (const :tag "None" none) |
| @@ -689,145 +1168,137 @@ fontified at all." | |||
| 689 | "Empty font-lock keywords for actions. | 1168 | "Empty font-lock keywords for actions. |
| 690 | Do not change the value of this constant.") | 1169 | Do not change the value of this constant.") |
| 691 | 1170 | ||
| 692 | (defvar antlr-font-lock-keywords-alist | ||
| 693 | '((java-mode | ||
| 694 | antlr-no-action-keywords | ||
| 695 | java-font-lock-keywords-1 java-font-lock-keywords-2 | ||
| 696 | java-font-lock-keywords-3) | ||
| 697 | (c++-mode | ||
| 698 | antlr-no-action-keywords | ||
| 699 | c++-font-lock-keywords-1 c++-font-lock-keywords-2 | ||
| 700 | c++-font-lock-keywords-3)) | ||
| 701 | "List of font-lock keywords for actions in the grammar. | ||
| 702 | Each element in this list looks like | ||
| 703 | (MAJOR-MODE KEYWORD...) | ||
| 704 | |||
| 705 | If `antlr-language' is equal to MAJOR-MODE, the KEYWORDs are the | ||
| 706 | font-lock keywords according to `font-lock-defaults' used for the code | ||
| 707 | in the grammar's actions and semantic predicates, see | ||
| 708 | `antlr-font-lock-maximum-decoration'.") | ||
| 709 | |||
| 710 | (defface antlr-default '((t nil)) | 1171 | (defface antlr-default '((t nil)) |
| 711 | "Face to prevent strings from language dependent highlighting. | 1172 | "Face to prevent strings from language dependent highlighting. |
| 712 | Do not change.") | 1173 | Do not change.") |
| 713 | 1174 | ||
| 714 | (defface antlr-keyword | 1175 | (defface antlr-keyword |
| 715 | '((((class color) (background light)) | 1176 | '((t :inherit font-lock-keyword-face)) |
| 716 | (:foreground "black" :weight bold)) | ||
| 717 | (t :inherit font-lock-keyword-face)) | ||
| 718 | "ANTLR keywords.") | 1177 | "ANTLR keywords.") |
| 719 | 1178 | ||
| 720 | (defface antlr-syntax | 1179 | (defface antlr-syntax |
| 721 | '((((class color) (background light)) | 1180 | '((t :inherit font-lock-keyword-face)) |
| 722 | (:foreground "black" :weight bold)) | 1181 | "ANTLR syntax symbols for AST creation: !, ^, ->.") |
| 723 | (t :inherit font-lock-constant-face)) | 1182 | |
| 724 | "ANTLR syntax symbols like :, |, (, ), ....") | 1183 | (defface antlr-action |
| 1184 | '((t :inherit font-lock-builtin-face)) | ||
| 1185 | "ANTLR action names: @ActionName, @ActionScope::ActionName.") | ||
| 725 | 1186 | ||
| 726 | (defface antlr-ruledef | 1187 | (defface antlr-ruledef |
| 727 | '((((class color) (background light)) | 1188 | '((t :inherit font-lock-function-name-face)) |
| 728 | (:foreground "blue" :weight bold)) | 1189 | "ANTLR parser and treeparser rule symbols (definition).") |
| 729 | (t :inherit font-lock-function-name-face)) | ||
| 730 | "ANTLR rule references (definition).") | ||
| 731 | 1190 | ||
| 732 | (defface antlr-tokendef | 1191 | (defface antlr-tokendef |
| 733 | '((((class color) (background light)) | 1192 | '((t :inherit font-lock-function-name-face)) |
| 734 | (:foreground "blue" :weight bold)) | 1193 | "ANTLR scanner rule symbols (definition).") |
| 735 | (t :inherit font-lock-function-name-face)) | ||
| 736 | "ANTLR token references (definition).") | ||
| 737 | 1194 | ||
| 738 | (defface antlr-ruleref | 1195 | (defface antlr-ruleref |
| 739 | '((((class color) (background light)) (:foreground "blue4")) | 1196 | '((t :inherit font-lock-type-face)) |
| 740 | (t :inherit font-lock-type-face)) | 1197 | "ANTLR parser and treeparser rule symbols (usage).") |
| 741 | "ANTLR rule references (usage).") | ||
| 742 | 1198 | ||
| 743 | (defface antlr-tokenref | 1199 | (defface antlr-tokenref |
| 744 | '((((class color) (background light)) (:foreground "orange4")) | 1200 | '((t :inherit font-lock-constant-face)) |
| 745 | (t :inherit font-lock-type-face)) | 1201 | "ANTLR scanner rule symbols (usage).") |
| 746 | "ANTLR token references (usage).") | 1202 | |
| 1203 | (defface antlr-symbol | ||
| 1204 | '((t :inherit font-lock-variable-name-face)) | ||
| 1205 | "ANTLR symbols (definition and usage) for things other than rules. | ||
| 1206 | Used for grammars, v3 scopes and v4 modes.") | ||
| 747 | 1207 | ||
| 748 | (defface antlr-literal | 1208 | (defface antlr-literal |
| 749 | '((((class color) (background light)) | 1209 | '((t :inherit font-lock-string-face :weight bold)) |
| 750 | (:foreground "brown4" :weight bold)) | ||
| 751 | (t :inherit font-lock-string-face)) | ||
| 752 | "ANTLR special literal tokens. | 1210 | "ANTLR special literal tokens. |
| 753 | It is used to highlight strings matched by the first regexp group of | 1211 | It is used to highlight strings matched by the first regexp group of |
| 754 | `antlr-font-lock-literal-regexp'.") | 1212 | `antlr-font-lock-literal-regexp'.") |
| 755 | 1213 | ||
| 756 | (defcustom antlr-font-lock-literal-regexp "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" | 1214 | (defface antlr-attribute '((t :inherit font-lock-preprocessor-face)) |
| 757 | "Regexp matching literals with special syntax highlighting, or nil. | 1215 | "ANTLR references to attributes within actions.") |
| 758 | If nil, there is no special syntax highlighting for some literals. | 1216 | |
| 759 | Otherwise, it should be a regular expression which must contain a regexp | 1217 | (defvar antlr-font-lock-late-keywords |
| 760 | group. The string matched by the first group is highlighted with | 1218 | ;; The tokens are already fontified as string/docstrings. The extra |
| 761 | `antlr-font-lock-literal-face'." | 1219 | ;; fontification of literals must come after the fontification from cc-mode; |
| 762 | :type '(choice (const :tag "None" nil) regexp)) | 1220 | ;; otherwise `c-font-lock-invalid-string' fontifies the final doublequote of |
| 763 | 1221 | ;; the last literal in a line with red (warning) - for whatever reason. | |
| 764 | (defvar antlr-class-header-regexp | 1222 | `((,(lambda (limit) ; v3, v4: literals are only '...' |
| 765 | "\\(class\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\sw*\\)[ \t]+\\(extends\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\sw*\\)[ \t]*;" | 1223 | (if antlr-font-lock-literal-regexp |
| 766 | "Regexp matching class headers.") | 1224 | (antlr-re-search-forward antlr-font-lock-literal-regexp limit))) |
| 767 | 1225 | (2 'antlr-literal t)) | |
| 768 | (defvar antlr-font-lock-additional-keywords | ||
| 769 | `((antlr-invalidate-context-cache) | ||
| 770 | ("\\$setType[ \t]*(\\([A-Za-z\300-\326\330-\337]\\sw*\\))" | ||
| 771 | (1 'antlr-tokendef)) | ||
| 772 | ("\\$\\sw+" (0 'antlr-keyword)) | ||
| 773 | ;; the tokens are already fontified as string/docstrings: | ||
| 774 | (,(lambda (limit) | 1226 | (,(lambda (limit) |
| 775 | (if antlr-font-lock-literal-regexp | 1227 | (antlr-re-search-forward "^\\(\\sw+\\)" limit)) |
| 776 | (antlr-re-search-forward antlr-font-lock-literal-regexp limit))) | 1228 | (1 (if (funcall antlr-token-identifier-p (char-after (match-beginning 0))) |
| 777 | (1 'antlr-literal t)) | 1229 | 'antlr-tokendef |
| 1230 | 'antlr-ruledef) | ||
| 1231 | t)) | ||
| 778 | (,(lambda (limit) | 1232 | (,(lambda (limit) |
| 779 | (antlr-re-search-forward antlr-class-header-regexp limit)) | 1233 | (antlr-re-search-forward antlr-grammar-header-regexp limit)) |
| 780 | (1 'antlr-keyword) | 1234 | (1 'antlr-keyword t) |
| 781 | (2 'antlr-ruledef) | 1235 | (2 'antlr-symbol t) |
| 782 | (3 'antlr-keyword) | 1236 | (3 'antlr-keyword t t) |
| 783 | (4 (if (member (match-string 4) '("Lexer" "Parser" "TreeParser")) | 1237 | (4 (if (member (match-string-no-properties 4) '("Lexer" "Parser" "TreeParser")) |
| 784 | 'antlr-keyword | 1238 | 'antlr-keyword |
| 785 | 'font-lock-type-face))) | 1239 | 'font-lock-type-face) |
| 1240 | t t)) | ||
| 786 | (,(lambda (limit) | 1241 | (,(lambda (limit) |
| 787 | (antlr-re-search-forward | 1242 | (antlr-re-search-forward |
| 788 | "\\<\\(header\\|options\\|tokens\\|exception\\|catch\\|returns\\)\\>" | 1243 | "\\<\\(header\\|options\\|tokens\\|channels\\|exception\\|catch\\|finally\\|returns\\|throws\\|import\\|locals\\)\\>" |
| 789 | limit)) | 1244 | limit)) |
| 790 | (1 'antlr-keyword)) | 1245 | (1 'antlr-keyword t)) |
| 791 | (,(lambda (limit) | 1246 | (,(lambda (limit) |
| 792 | (antlr-re-search-forward | 1247 | (when antlr-font-lock-symbol-regexp |
| 793 | "^\\(private\\|public\\|protected\\)\\>[ \t]*\\(\\(\\sw+[ \t]*\\(:\\)?\\)\\)?" | 1248 | (antlr-re-search-forward antlr-font-lock-symbol-regexp limit))) |
| 794 | limit)) | 1249 | (1 'antlr-keyword t) |
| 795 | (1 'font-lock-type-face) ; not XEmacs's java level-3 fruit salad | 1250 | (2 'antlr-symbol t t)) |
| 796 | (3 (if (antlr-upcase-p (char-after (match-beginning 3))) | ||
| 797 | 'antlr-tokendef | ||
| 798 | 'antlr-ruledef) | ||
| 799 | nil t) | ||
| 800 | (4 'antlr-syntax nil t)) | ||
| 801 | (,(lambda (limit) | 1251 | (,(lambda (limit) |
| 802 | (antlr-re-search-forward "^\\(\\sw+\\)[ \t]*\\(:\\)?" limit)) | 1252 | (antlr-re-search-forward |
| 803 | (1 (if (antlr-upcase-p (char-after (match-beginning 0))) | 1253 | "^\\(private\\|public\\|protected\\|fragment\\)\\>[ \t]*\\(\\sw+\\)?" |
| 1254 | limit)) | ||
| 1255 | (1 'antlr-keyword t) | ||
| 1256 | (2 (if (funcall antlr-token-identifier-p (char-after (match-beginning 2))) | ||
| 804 | 'antlr-tokendef | 1257 | 'antlr-tokendef |
| 805 | 'antlr-ruledef) | 1258 | 'antlr-ruledef) |
| 806 | nil t) | 1259 | t t)) |
| 807 | (2 'antlr-syntax nil t)) | 1260 | (,(lambda (limit) ; v3, v4 |
| 1261 | (antlr-re-search-forward "@\\([A-Za-z\300-\326\330-\337_]\\sw*\\)\\(?:::\\([A-Za-z\300-\326\330-\337_]\\sw*\\)\\)?" limit)) | ||
| 1262 | (1 (antlr-font-lock-checked-face (if (match-beginning 2) | ||
| 1263 | antlr-action-scope-names | ||
| 1264 | antlr-action-names) | ||
| 1265 | 1 'antlr-action) | ||
| 1266 | t) | ||
| 1267 | (2 (antlr-font-lock-checked-face antlr-action-names 2 'antlr-action) | ||
| 1268 | t t)) | ||
| 808 | (,(lambda (limit) | 1269 | (,(lambda (limit) |
| 809 | ;; v:ruleref and v:"literal" is allowed... | 1270 | (and antlr-font-lock-syntax-spec |
| 810 | (antlr-re-search-forward "\\(\\sw+\\)[ \t]*\\([=:]\\)?" limit)) | 1271 | (antlr-re-search-forward (car antlr-font-lock-syntax-spec) limit))) |
| 1272 | (1 'antlr-syntax t))) | ||
| 1273 | "Late font-lock keywords for ANTLR's normal grammar code. | ||
| 1274 | See `antlr-font-lock-keywords-alist' for the keywords of actions.") | ||
| 1275 | |||
| 1276 | (defvar antlr-font-lock-additional-keywords | ||
| 1277 | `((,(lambda (limit) | ||
| 1278 | (and antlr-font-lock-attribute-regexp | ||
| 1279 | (re-search-forward antlr-font-lock-attribute-regexp limit 'limit))) | ||
| 1280 | (1 'antlr-attribute)) | ||
| 1281 | (,(lambda (limit) | ||
| 1282 | ;; v2: v:ruleref v:"literal", v=ruleref (no highlighting), v3: v=ruleref | ||
| 1283 | (antlr-re-search-forward antlr-ruleref-assign-regexp limit)) | ||
| 811 | (1 (if (match-beginning 2) | 1284 | (1 (if (match-beginning 2) |
| 812 | (if (eq (char-after (match-beginning 2)) ?=) | 1285 | (if (match-beginning 3) |
| 813 | 'antlr-default | 1286 | 'antlr-default |
| 814 | 'font-lock-variable-name-face) | 1287 | 'font-lock-variable-name-face) ; yes, same as vars in [...] |
| 815 | (if (antlr-upcase-p (char-after (match-beginning 1))) | 1288 | (if (funcall antlr-token-identifier-p (char-after (match-beginning 1))) |
| 816 | 'antlr-tokenref | 1289 | 'antlr-tokenref |
| 817 | 'antlr-ruleref))) | 1290 | 'antlr-ruleref))) |
| 818 | (2 'antlr-default nil t)) | 1291 | (2 'antlr-default nil t)) |
| 819 | (,(lambda (limit) | 1292 | (,(lambda (limit) |
| 820 | (antlr-re-search-forward "[|&:;(~]\\|)\\([*+?]\\|=>\\)?" limit)) | 1293 | (antlr-re-search-forward antlr-font-lock-negation-regexp limit)) |
| 821 | (0 'antlr-syntax))) | 1294 | (1 'font-lock-negation-char-face t t))) |
| 822 | "Font-lock keywords for ANTLR's normal grammar code. | 1295 | "Early font-lock keywords for ANTLR's normal grammar code. |
| 823 | See `antlr-font-lock-keywords-alist' for the keywords of actions.") | 1296 | See `antlr-font-lock-keywords-alist' for the keywords of actions.") |
| 824 | 1297 | ||
| 825 | (defvar antlr-font-lock-defaults | 1298 | (defvar antlr-font-lock-defaults |
| 826 | '(antlr-font-lock-keywords | 1299 | '(antlr-font-lock-keywords |
| 827 | nil nil ((?_ . "w") (?\( . ".") (?\) . ".")) beginning-of-defun) | 1300 | nil nil ((?_ . "w"))) |
| 828 | "Font-lock defaults used for ANTLR syntax highlighting. | 1301 | "Font-lock defaults used for ANTLR syntax highlighting.") |
| 829 | The SYNTAX-ALIST element is also used to initialize | ||
| 830 | `antlr-action-syntax-table'.") | ||
| 831 | 1302 | ||
| 832 | 1303 | ||
| 833 | ;;;=========================================================================== | 1304 | ;;;=========================================================================== |
| @@ -841,38 +1312,12 @@ The SYNTAX-ALIST element is also used to initialize | |||
| 841 | (let ((st (make-syntax-table))) | 1312 | (let ((st (make-syntax-table))) |
| 842 | (c-populate-syntax-table st) | 1313 | (c-populate-syntax-table st) |
| 843 | st) | 1314 | st) |
| 844 | "Syntax table used in `antlr-mode' buffers. | 1315 | "Syntax table used in `antlr-mode' buffers.") |
| 845 | If non-nil, it will be initialized in `antlr-mode'.") | ||
| 846 | |||
| 847 | ;; used for "in Java/C++ code" = syntactic-depth>0 | ||
| 848 | (defvar antlr-action-syntax-table | ||
| 849 | (let ((st (copy-syntax-table antlr-mode-syntax-table)) | ||
| 850 | (slist (nth 3 antlr-font-lock-defaults))) | ||
| 851 | (while slist | ||
| 852 | (modify-syntax-entry (caar slist) (cdar slist) st) | ||
| 853 | (setq slist (cdr slist))) | ||
| 854 | st) | ||
| 855 | "Syntax table used for ANTLR action parsing. | ||
| 856 | Initialized by `antlr-mode-syntax-table', changed by SYNTAX-ALIST in | ||
| 857 | `antlr-font-lock-defaults'. This table should be selected if you use | ||
| 858 | `buffer-syntactic-context' and `buffer-syntactic-context-depth' in order | ||
| 859 | not to confuse their context_cache.") | ||
| 860 | 1316 | ||
| 861 | (defvar antlr-mode-abbrev-table nil | 1317 | (defvar antlr-mode-abbrev-table nil |
| 862 | "Abbreviation table used in `antlr-mode' buffers.") | 1318 | "Abbreviation table used in `antlr-mode' buffers.") |
| 863 | (define-abbrev-table 'antlr-mode-abbrev-table ()) | 1319 | (define-abbrev-table 'antlr-mode-abbrev-table ()) |
| 864 | 1320 | ||
| 865 | (defvar antlr-slow-cache-enabling-symbol 'loudly | ||
| 866 | ;; Emacs's font-lock changes buffer's tick counter, therefore this value should | ||
| 867 | ;; be a parameter of a font-lock function, but not any other variable of | ||
| 868 | ;; functions which call `antlr-slow-syntactic-context'. | ||
| 869 | "If value is a bound symbol, cache will be used even with text changes. | ||
| 870 | This is no user option. Used for `antlr-slow-syntactic-context'.") | ||
| 871 | |||
| 872 | (defvar antlr-slow-cache-diff-threshold 5000 | ||
| 873 | "Maximum distance between `point' and cache position for cache use. | ||
| 874 | Used for `antlr-slow-syntactic-context'.") | ||
| 875 | |||
| 876 | 1321 | ||
| 877 | ;;;;########################################################################## | 1322 | ;;;;########################################################################## |
| 878 | ;;;; The Code | 1323 | ;;;; The Code |
| @@ -881,111 +1326,25 @@ Used for `antlr-slow-syntactic-context'.") | |||
| 881 | 1326 | ||
| 882 | 1327 | ||
| 883 | ;;;=========================================================================== | 1328 | ;;;=========================================================================== |
| 884 | ;;; Syntax functions | ||
| 885 | ;;;=========================================================================== | ||
| 886 | |||
| 887 | ;;;=========================================================================== | ||
| 888 | ;;; Context cache | 1329 | ;;; Context cache |
| 889 | ;;;=========================================================================== | 1330 | ;;;=========================================================================== |
| 890 | 1331 | ||
| 891 | (defvar antlr-slow-context-cache nil "Internal.") | 1332 | (defun antlr-syntactic-context (&optional ppss) |
| 892 | |||
| 893 | ;;;(defvar antlr-statistics-full-neg 0) | ||
| 894 | ;;;(defvar antlr-statistics-full-diff 0) | ||
| 895 | ;;;(defvar antlr-statistics-full-other 0) | ||
| 896 | ;;;(defvar antlr-statistics-cache 0) | ||
| 897 | ;;;(defvar antlr-statistics-inval 0) | ||
| 898 | |||
| 899 | (defun antlr-invalidate-context-cache (&rest _dummies) | ||
| 900 | ;; checkdoc-params: (dummies) | ||
| 901 | "Invalidate context cache for syntactical context information." | ||
| 902 | ;;; (cl-incf antlr-statistics-inval) | ||
| 903 | (setq antlr-slow-context-cache nil)) | ||
| 904 | |||
| 905 | (defun antlr-syntactic-context () | ||
| 906 | "Return some syntactic context information. | 1333 | "Return some syntactic context information. |
| 907 | Return `string' if point is within a string, `block-comment' or | 1334 | Return `string' if point is within a string, `block-comment' or |
| 908 | `comment' is point is within a comment or the depth within all | 1335 | `comment' if point is within a comment or the depth within all |
| 909 | parenthesis-syntax delimiters at point otherwise. | 1336 | parenthesis-syntax delimiters at point otherwise. |
| 910 | WARNING: this may alter `match-data'." | 1337 | WARNING: this may alter `match-data'. |
| 911 | (let ((orig (point)) diff state | 1338 | Optional argument PPSS" ; TODO: warning this valid? |
| 912 | ;; Arg, Emacs's (buffer-modified-tick) changes with font-lock. Use | 1339 | ;; does not work for negative depth |
| 913 | ;; hack that `loudly' is bound during font-locking => cache use will | 1340 | (or ppss (setq ppss (syntax-ppss))) |
| 914 | ;; increase from 7% to 99.99% during font-locking. | 1341 | (cond ((nth 3 ppss) 'string) |
| 915 | (tick (or (boundp antlr-slow-cache-enabling-symbol) | 1342 | ((nth 4 ppss) 'comment) |
| 916 | (buffer-modified-tick)))) | 1343 | (t |
| 917 | (if (and (cdr antlr-slow-context-cache) | 1344 | (let ((poss (nth 9 ppss))) ; TODO Emacs: syntax-ppss-open-positions |
| 918 | (>= (setq diff (- orig (cadr antlr-slow-context-cache))) 0) | 1345 | (while (and poss (memq (char-after (car poss)) '(nil ?\())) |
| 919 | (< diff antlr-slow-cache-diff-threshold) | 1346 | (setq poss (cdr poss))) |
| 920 | (eq (current-buffer) (caar antlr-slow-context-cache)) | 1347 | (and poss (length poss)))))) ; depth if inside {} or [] |
| 921 | (eq tick (cdar antlr-slow-context-cache))) | ||
| 922 | ;; (setq antlr-statistics-cache (1+ antlr-statistics-cache) ...) | ||
| 923 | (setq state (parse-partial-sexp (cadr antlr-slow-context-cache) orig | ||
| 924 | nil nil | ||
| 925 | (cddr antlr-slow-context-cache))) | ||
| 926 | (if (>= orig antlr-slow-cache-diff-threshold) | ||
| 927 | (beginning-of-defun) | ||
| 928 | (goto-char (point-min))) | ||
| 929 | ;; (cond ((and diff (< diff 0)) (cl-incf antlr-statistics-full-neg)) | ||
| 930 | ;; ((and diff (>= diff 3000)) (cl-incf antlr-statistics-full-diff)) | ||
| 931 | ;; (t (cl-incf antlr-statistics-full-other))) | ||
| 932 | (setq state (parse-partial-sexp (point) orig))) | ||
| 933 | (goto-char orig) | ||
| 934 | (if antlr-slow-context-cache | ||
| 935 | (setcdr antlr-slow-context-cache (cons orig state)) | ||
| 936 | (setq antlr-slow-context-cache | ||
| 937 | (cons (cons (current-buffer) tick) | ||
| 938 | (cons orig state)))) | ||
| 939 | (cond ((nth 3 state) 'string) | ||
| 940 | ((nth 4 state) 'comment) ; block-comment? -- we don't care | ||
| 941 | (t (car state))))) | ||
| 942 | |||
| 943 | ;; (cl-incf (aref antlr-statistics 2)) | ||
| 944 | ;; (unless (and (eq (current-buffer) | ||
| 945 | ;; (caar antlr-slow-context-cache)) | ||
| 946 | ;; (eq (buffer-modified-tick) | ||
| 947 | ;; (cdar antlr-slow-context-cache))) | ||
| 948 | ;; (cl-incf (aref antlr-statistics 1)) | ||
| 949 | ;; (setq antlr-slow-context-cache nil)) | ||
| 950 | ;; (let* ((orig (point)) | ||
| 951 | ;; (base (cadr antlr-slow-context-cache)) | ||
| 952 | ;; (curr (cddr antlr-slow-context-cache)) | ||
| 953 | ;; (state (cond ((eq orig (car curr)) (cdr curr)) | ||
| 954 | ;; ((eq orig (car base)) (cdr base)))) | ||
| 955 | ;; diff diff2) | ||
| 956 | ;; (unless state | ||
| 957 | ;; (cl-incf (aref antlr-statistics 3)) | ||
| 958 | ;; (when curr | ||
| 959 | ;; (if (< (setq diff (abs (- orig (car curr)))) | ||
| 960 | ;; (setq diff2 (abs (- orig (car base))))) | ||
| 961 | ;; (setq state curr) | ||
| 962 | ;; (setq state base | ||
| 963 | ;; diff diff2)) | ||
| 964 | ;; (if (or (>= (1+ diff) (point)) (>= diff 3000)) | ||
| 965 | ;; (setq state nil))) ; start from bod/bob | ||
| 966 | ;; (if state | ||
| 967 | ;; (setq state | ||
| 968 | ;; (parse-partial-sexp (car state) orig nil nil (cdr state))) | ||
| 969 | ;; (if (>= orig 3000) (beginning-of-defun) (goto-char (point-min))) | ||
| 970 | ;; (cl-incf (aref antlr-statistics 4)) | ||
| 971 | ;; (setq cw (list orig (point) base curr)) | ||
| 972 | ;; (setq state (parse-partial-sexp (point) orig))) | ||
| 973 | ;; (goto-char orig) | ||
| 974 | ;; (if antlr-slow-context-cache | ||
| 975 | ;; (setcdr (cdr antlr-slow-context-cache) (cons orig state)) | ||
| 976 | ;; (setq antlr-slow-context-cache | ||
| 977 | ;; (cons (cons (current-buffer) (buffer-modified-tick)) | ||
| 978 | ;; (cons (cons orig state) (cons orig state)))))) | ||
| 979 | ;; (cond ((nth 3 state) 'string) | ||
| 980 | ;; ((nth 4 state) 'comment) ; block-comment? -- we don't care | ||
| 981 | ;; (t (car state))))) | ||
| 982 | |||
| 983 | ;; (beginning-of-defun) | ||
| 984 | ;; (let ((state (parse-partial-sexp (point) orig))) | ||
| 985 | ;; (goto-char orig) | ||
| 986 | ;; (cond ((nth 3 state) 'string) | ||
| 987 | ;; ((nth 4 state) 'comment) ; block-comment? -- we don't care | ||
| 988 | ;; (t (car state)))))) | ||
| 989 | 1348 | ||
| 990 | 1349 | ||
| 991 | ;;;=========================================================================== | 1350 | ;;;=========================================================================== |
| @@ -994,9 +1353,8 @@ WARNING: this may alter `match-data'." | |||
| 994 | 1353 | ||
| 995 | (defun antlr-upcase-p (char) | 1354 | (defun antlr-upcase-p (char) |
| 996 | "Non-nil, if CHAR is an uppercase character (if CHAR was a char)." | 1355 | "Non-nil, if CHAR is an uppercase character (if CHAR was a char)." |
| 997 | ;; in XEmacs, upcase only works for ASCII | 1356 | ;; (get-char-code-property char 'lowercase) |
| 998 | (or (and (<= ?A char) (<= char ?Z)) | 1357 | (not (eq (downcase char) char))) |
| 999 | (and (<= ?\300 char) (<= char ?\337)))) ; ?\327 is no letter | ||
| 1000 | 1358 | ||
| 1001 | (defun antlr-re-search-forward (regexp bound) | 1359 | (defun antlr-re-search-forward (regexp bound) |
| 1002 | "Search forward from point for regular expression REGEXP. | 1360 | "Search forward from point for regular expression REGEXP. |
| @@ -1005,36 +1363,47 @@ nil if no occurrence was found. Do not search within comments, strings | |||
| 1005 | and actions/semantic predicates. BOUND bounds the search; it is a | 1363 | and actions/semantic predicates. BOUND bounds the search; it is a |
| 1006 | buffer position. See also the functions `match-beginning', `match-end' | 1364 | buffer position. See also the functions `match-beginning', `match-end' |
| 1007 | and `replace-match'." | 1365 | and `replace-match'." |
| 1008 | ;; WARNING: Should only be used with `antlr-action-syntax-table'! | ||
| 1009 | (let ((continue t)) | 1366 | (let ((continue t)) |
| 1010 | (while (and (re-search-forward regexp bound 'limit) | 1367 | (while (and (re-search-forward regexp bound 'limit) |
| 1011 | (save-match-data | 1368 | (save-match-data |
| 1012 | (if (eq (antlr-syntactic-context) 0) | 1369 | (or (antlr-syntactic-context) (setq continue nil))))) |
| 1013 | (setq continue nil) | ||
| 1014 | t)))) | ||
| 1015 | (if continue nil (point)))) | 1370 | (if continue nil (point)))) |
| 1016 | 1371 | ||
| 1017 | (defun antlr-search-forward (string) | 1372 | (defsubst antlr-search-result (line-regexp) |
| 1373 | "Return `point' if last search is valid, or nil otherwise. | ||
| 1374 | The search is not considered valid if point is inside actions, comments | ||
| 1375 | or strings, or if the beginning of the current line matches LINE-REGEXP | ||
| 1376 | if that is non-nil." | ||
| 1377 | (unless (antlr-syntactic-context) | ||
| 1378 | (if (and line-regexp | ||
| 1379 | (save-excursion | ||
| 1380 | (beginning-of-line) | ||
| 1381 | (looking-at line-regexp)) | ||
| 1382 | (<= (point) (match-end 0) (1+ (point)))) | ||
| 1383 | nil | ||
| 1384 | (point)))) | ||
| 1385 | |||
| 1386 | (defun antlr-search-forward (string &optional line-regexp) | ||
| 1018 | "Search forward from point for STRING. | 1387 | "Search forward from point for STRING. |
| 1019 | Set point to the end of the occurrence found, and return point. Return | 1388 | Set point to the end of the occurrence found, and return point. Return |
| 1020 | nil if no occurrence was found. Do not search within comments, strings | 1389 | nil if no occurrence was found. Do not search within comments, strings |
| 1021 | and actions/semantic predicates." | 1390 | and actions/semantic predicates. |
| 1022 | ;; WARNING: Should only be used with `antlr-action-syntax-table'! | 1391 | See function `antlr-search-result' for the optional arg LINE-REGEXP." |
| 1023 | (let ((continue t)) | 1392 | (let ((result nil)) |
| 1024 | (while (and (search-forward string nil 'limit) | 1393 | (while (and (null result) (search-forward string nil 'limit)) |
| 1025 | (if (eq (antlr-syntactic-context) 0) (setq continue nil) t))) | 1394 | (setq result (antlr-search-result line-regexp))) |
| 1026 | (if continue nil (point)))) | 1395 | result)) |
| 1027 | 1396 | ||
| 1028 | (defun antlr-search-backward (string) | 1397 | (defun antlr-search-backward (string &optional line-regexp) |
| 1029 | "Search backward from point for STRING. | 1398 | "Search backward from point for STRING. |
| 1030 | Set point to the beginning of the occurrence found, and return point. | 1399 | Set point to the beginning of the occurrence found, and return point. |
| 1031 | Return nil if no occurrence was found. Do not search within comments, | 1400 | Return nil if no occurrence was found. Do not search within comments, |
| 1032 | strings and actions/semantic predicates." | 1401 | strings and actions/semantic predicates. |
| 1033 | ;; WARNING: Should only be used with `antlr-action-syntax-table'! | 1402 | See function `antlr-search-result' for the optional arg LINE-REGEXP." |
| 1034 | (let ((continue t)) | 1403 | (let ((result nil)) |
| 1035 | (while (and (search-backward string nil 'limit) | 1404 | (while (and (null result) (search-backward string nil 'limit)) |
| 1036 | (if (eq (antlr-syntactic-context) 0) (setq continue nil) t))) | 1405 | (setq result (antlr-search-result line-regexp))) |
| 1037 | (if continue nil (point)))) | 1406 | result)) |
| 1038 | 1407 | ||
| 1039 | (defsubst antlr-skip-sexps (count) | 1408 | (defsubst antlr-skip-sexps (count) |
| 1040 | "Skip the next COUNT balanced expressions and the comments after it. | 1409 | "Skip the next COUNT balanced expressions and the comments after it. |
| @@ -1043,6 +1412,117 @@ Return position before the comments after the last expression." | |||
| 1043 | (prog1 (point) | 1412 | (prog1 (point) |
| 1044 | (antlr-c-forward-sws))) | 1413 | (antlr-c-forward-sws))) |
| 1045 | 1414 | ||
| 1415 | (defun antlr-syntax-propertize-wholerule (start end) | ||
| 1416 | ;; checkdoc-params: (start end) | ||
| 1417 | "Function used to properly highlight ANTLR v4 charsets. | ||
| 1418 | This function is used in `syntax-propertize-extend-region-functions' to | ||
| 1419 | make sure that the propertized region starts at the beginning of a rule." | ||
| 1420 | (goto-char start) | ||
| 1421 | (beginning-of-line) | ||
| 1422 | (while (if (bobp) nil (looking-at "[ \t\n}]\\|@init\\_>\\|options\\_>")) | ||
| 1423 | (beginning-of-line 0)) | ||
| 1424 | ;; no need to find the real end of a rule... end-of-line is good | ||
| 1425 | (cons (point) | ||
| 1426 | (progn (goto-char end) | ||
| 1427 | (if (bolp) (point) (line-beginning-position 2))))) | ||
| 1428 | |||
| 1429 | ;; font-lock.el and/or syntax.el should say something about the use of | ||
| 1430 | ;; `syntax-ppss' when `font-lock-syntax-table' is set - we should not use the | ||
| 1431 | ;; same cache for calls inside and outside font-lock, don't we? | ||
| 1432 | |||
| 1433 | (defun antlr-syntax-propertize-charsets (start end) | ||
| 1434 | ;; checkdoc-params: (start end) | ||
| 1435 | "Function used to properly highlight ANTLR v4 charsets. | ||
| 1436 | This function is as value for `syntax-propertize-function' and makes | ||
| 1437 | sure that charsets like [a-z] in token rule bodies are considered | ||
| 1438 | literals." | ||
| 1439 | (goto-char start) | ||
| 1440 | (let ((mode (if (bolp) :start :next))) | ||
| 1441 | (while (< (point) end) | ||
| 1442 | (let ((context (antlr-syntactic-context))) | ||
| 1443 | (cond ((numberp context) | ||
| 1444 | (goto-char (or (ignore-errors (scan-lists (point) 1 context)) | ||
| 1445 | end))) | ||
| 1446 | ((eq mode :start) ; TODO: only if context = 0 | ||
| 1447 | (when (looking-at "fragment\\_>") | ||
| 1448 | (forward-char 8) | ||
| 1449 | (skip-chars-forward " \t\n")) | ||
| 1450 | (setq mode (if (antlr-upcase-p (char-after)) | ||
| 1451 | :scanner | ||
| 1452 | (if (eq (char-syntax (char-after)) ?w) | ||
| 1453 | :end | ||
| 1454 | :next)))) | ||
| 1455 | ((eq mode :end) | ||
| 1456 | (skip-chars-forward "^;" end) | ||
| 1457 | (while (and (< (point) end) (antlr-syntactic-context)) | ||
| 1458 | (forward-char) | ||
| 1459 | (skip-chars-forward "^;" end)) | ||
| 1460 | (setq mode :next)) | ||
| 1461 | ((eq mode :next) | ||
| 1462 | (beginning-of-line 2) | ||
| 1463 | (while (and (< (point) end) (looking-at "[ \t\n@}]")) | ||
| 1464 | (beginning-of-line 2)) | ||
| 1465 | (setq mode :start)) | ||
| 1466 | ((eq mode :scanner) | ||
| 1467 | (skip-chars-forward "^:;" end) | ||
| 1468 | (while (and (< (point) end) (antlr-syntactic-context)) | ||
| 1469 | (forward-char) | ||
| 1470 | (skip-chars-forward "^:;" end)) | ||
| 1471 | (if (eq (char-after) ?:) | ||
| 1472 | (if (eq (char-after (1+ (point))) ?:) | ||
| 1473 | (forward-char 2) ; "::" for namespace | ||
| 1474 | (setq mode :charset)) | ||
| 1475 | (setq mode :next))) | ||
| 1476 | ((eq mode :charset) | ||
| 1477 | ;; LEXER_CHAR_SET : | ||
| 1478 | ;; '[' ( '\\' ~('\r'|'\n') | ~('\r'|'\n'|'\\'|']') )* ']' | ||
| 1479 | (skip-chars-forward "^;[" end) | ||
| 1480 | (while (and (< (point) end) (antlr-syntactic-context)) | ||
| 1481 | (forward-char) | ||
| 1482 | (skip-chars-forward "^;[" end)) | ||
| 1483 | (if (not (eq (char-after) ?\[)) | ||
| 1484 | (setq mode :next) | ||
| 1485 | (put-text-property (point) (progn (forward-char) (point)) | ||
| 1486 | 'syntax-table | ||
| 1487 | (eval-when-compile | ||
| 1488 | (string-to-syntax "|"))) | ||
| 1489 | (let (char (esc nil)) | ||
| 1490 | (while (and (setq char (char-after)) | ||
| 1491 | (not (eq char ?\n)) | ||
| 1492 | (or esc (not (eq char ?\])))) | ||
| 1493 | (setq esc (if esc nil (eq char ?\\))) | ||
| 1494 | (forward-char))) | ||
| 1495 | (put-text-property (point) (1+ (point)) | ||
| 1496 | 'syntax-table | ||
| 1497 | (eval-when-compile | ||
| 1498 | (string-to-syntax "|")))))))))) | ||
| 1499 | |||
| 1500 | (defun antlr-syntax-propertize-template-literals (start end) | ||
| 1501 | ;; checkdoc-params: (start end) | ||
| 1502 | "Function used to properly highlight ANTLR v3 template literals. | ||
| 1503 | This function is as value for `syntax-propertize-function' and makes | ||
| 1504 | sure that templates like <<...>> outside actions, strings or comments | ||
| 1505 | are considered literals." | ||
| 1506 | (goto-char start) | ||
| 1507 | (while (search-forward "<<" end t) | ||
| 1508 | (let ((context (antlr-syntactic-context))) | ||
| 1509 | (if context | ||
| 1510 | (when (numberp context) | ||
| 1511 | (goto-char (min (or (ignore-errors (scan-lists (point) 1 context)) | ||
| 1512 | end) | ||
| 1513 | end))) | ||
| 1514 | (let ((pos (- (point) 2))) | ||
| 1515 | ;; put the text property on the inner "<>", since multi-line is set | ||
| 1516 | ;; to be ok with `c-multiline-string-start-char' | ||
| 1517 | (put-text-property (1+ pos) (point) 'syntax-table | ||
| 1518 | (eval-when-compile | ||
| 1519 | (string-to-syntax "|"))) | ||
| 1520 | (when (search-forward ">>" end 'move) | ||
| 1521 | (put-text-property (- (point) 2) (1- (point)) 'syntax-table | ||
| 1522 | (eval-when-compile | ||
| 1523 | (string-to-syntax "|")))) | ||
| 1524 | (put-text-property pos (point) 'syntax-multiline t)))))) | ||
| 1525 | |||
| 1046 | 1526 | ||
| 1047 | ;;;=========================================================================== | 1527 | ;;;=========================================================================== |
| 1048 | ;;; font-lock | 1528 | ;;; font-lock |
| @@ -1052,63 +1532,82 @@ Return position before the comments after the last expression." | |||
| 1052 | "Return font-lock keywords for current buffer. | 1532 | "Return font-lock keywords for current buffer. |
| 1053 | See `antlr-font-lock-additional-keywords', `antlr-language' and | 1533 | See `antlr-font-lock-additional-keywords', `antlr-language' and |
| 1054 | `antlr-font-lock-maximum-decoration'." | 1534 | `antlr-font-lock-maximum-decoration'." |
| 1055 | (if (eq antlr-font-lock-maximum-decoration 'none) | 1535 | (append antlr-font-lock-additional-keywords |
| 1056 | antlr-font-lock-additional-keywords | 1536 | (unless (eq antlr-font-lock-maximum-decoration 'none) |
| 1057 | (append antlr-font-lock-additional-keywords | 1537 | (let* ((major-mode antlr-action-mode) ;#dynamic |
| 1058 | (eval (let ((major-mode antlr-language)) ; dynamic | 1538 | (level (font-lock-value-in-major-mode |
| 1059 | (font-lock-choose-keywords | 1539 | (if (eq antlr-font-lock-maximum-decoration 'inherit) |
| 1060 | (cdr (assq antlr-language | 1540 | font-lock-maximum-decoration |
| 1061 | antlr-font-lock-keywords-alist)) | 1541 | antlr-font-lock-maximum-decoration)))) |
| 1062 | (if (eq antlr-font-lock-maximum-decoration 'inherit) | 1542 | (font-lock-eval-keywords |
| 1063 | font-lock-maximum-decoration | 1543 | (font-lock-choose-keywords antlr-action-font-lock-keywords |
| 1064 | antlr-font-lock-maximum-decoration))) | 1544 | level)))) |
| 1065 | t)))) | 1545 | antlr-font-lock-late-keywords)) |
| 1546 | |||
| 1547 | (defun antlr-font-lock-checked-face (strings group face) ; checkdoc-order: nil | ||
| 1548 | "Return font-lock face for regexp group GROUP. | ||
| 1549 | If the matched string is an element of STRINGS (or STRINGS is not a list), | ||
| 1550 | return FACE, otherwise return `font-lock-warning-face'." | ||
| 1551 | (if (if (consp strings) (member (match-string-no-properties group) strings) strings) | ||
| 1552 | face | ||
| 1553 | font-lock-warning-face)) | ||
| 1066 | 1554 | ||
| 1067 | 1555 | ||
| 1068 | ;;;=========================================================================== | 1556 | ;;;=========================================================================== |
| 1069 | ;;; imenu support | 1557 | ;;; imenu support |
| 1070 | ;;;=========================================================================== | 1558 | ;;;=========================================================================== |
| 1071 | 1559 | ||
| 1560 | ;; Actually, issues in the "Index" (at least with sorted entries) menu are | ||
| 1561 | ;; imenu-induced. If entries are missing in the menu (as are sometimes for me | ||
| 1562 | ;; on Emacs-25.1.1), try M-x imenu RET -> you see all. This might not be the | ||
| 1563 | ;; case anymore with the reordering of `imenu-add-to-menubar'... | ||
| 1564 | (defvar antlr-do-syntax-propertize (version< emacs-version "25") | ||
| 1565 | "Whether \\[antlr-mode] runs `syntax-propertize' on the complete buffer. | ||
| 1566 | Running it explicitly at the beginning of the mode might be | ||
| 1567 | necessary for a correct Index menu and motion commands.") | ||
| 1568 | |||
| 1072 | (defun antlr-grammar-tokens () | 1569 | (defun antlr-grammar-tokens () |
| 1073 | "Return alist for tokens defined in current buffer." | 1570 | "Return alist for tokens defined in current buffer." |
| 1074 | (save-excursion (antlr-imenu-create-index-function t))) | 1571 | (save-excursion (antlr-imenu-create-index-function 'upcase))) |
| 1075 | 1572 | ||
| 1076 | (defun antlr-imenu-create-index-function (&optional tokenrefs-only) | 1573 | ;; TODO: version dependent? |
| 1574 | (defun antlr-imenu-create-index-function (&optional refs-only) | ||
| 1077 | "Return imenu index-alist for ANTLR grammar files. | 1575 | "Return imenu index-alist for ANTLR grammar files. |
| 1078 | IF TOKENREFS-ONLY is non-nil, just return alist with tokenref names." | 1576 | IF REFS-ONLY is non-nil, just return alist with ref names, |
| 1577 | with value 'upcase, only return alist with tokenref names." | ||
| 1079 | (let ((items nil) | 1578 | (let ((items nil) |
| 1080 | (classes nil) | 1579 | (classes nil) |
| 1081 | (continue t)) | 1580 | (continue t)) |
| 1082 | ;; The generic imenu function searches backward, which is slower | 1581 | ;; Using `imenu-progress-message' would require imenu for compilation, but |
| 1083 | ;; and more likely not to work during editing. | 1582 | ;; nobody is missing these messages. The generic imenu function searches |
| 1084 | (with-syntax-table antlr-action-syntax-table | 1583 | ;; backward, which is slower and more likely not to work during editing. |
| 1085 | (antlr-invalidate-context-cache) | 1584 | (goto-char (point-min)) |
| 1086 | (goto-char (point-min)) | 1585 | (antlr-skip-file-prelude t) |
| 1087 | (antlr-skip-file-prelude t) | 1586 | (while continue |
| 1088 | (while continue | 1587 | (if (looking-at "\\(class\\|lexer[ \t]+grammar\\|parser[ \t]+grammar\\|tree[ \t]+grammar\\|grammar\\|mode\\|import\\)[ \t]+\\([A-Za-z\300-\326\330-\337]\\(?:\\sw\\|\\s_\\)*\\)") ; TODO: import is (hopefully) temp |
| 1089 | (if (looking-at "{") (antlr-skip-sexps 1)) | 1588 | (and (not refs-only) |
| 1090 | (if (looking-at antlr-class-header-regexp) | 1589 | (memq (char-after (match-beginning 1)) '(?c ?m)) ;class, mode |
| 1091 | (or tokenrefs-only | 1590 | (push (cons (match-string-no-properties 2) |
| 1092 | (push (cons (match-string 2) | 1591 | (if imenu-use-markers |
| 1093 | (if imenu-use-markers | 1592 | (copy-marker (match-beginning 2)) |
| 1094 | (copy-marker (match-beginning 2)) | 1593 | (match-beginning 2))) |
| 1095 | (match-beginning 2))) | 1594 | classes)) |
| 1096 | classes)) | 1595 | (if (looking-at "p\\(ublic\\|rotected\\|rivate\\)\\_>\\|fragment\\_>") |
| 1097 | (if (looking-at "p\\(ublic\\|rotected\\|rivate\\)") | 1596 | (antlr-skip-sexps 1)) |
| 1098 | (antlr-skip-sexps 1)) | 1597 | (when (looking-at "\\(?:\\sw\\|\\s_\\)+") |
| 1099 | (when (looking-at "\\sw+") | 1598 | (when (or (not (eq refs-only 'upcase)) |
| 1100 | (if tokenrefs-only | 1599 | (antlr-upcase-p (char-after (point)))) |
| 1101 | (if (antlr-upcase-p (char-after (point))) | 1600 | (push (cons (match-string-no-properties 0) |
| 1102 | (push (list (match-string 0)) items)) | 1601 | (if (and imenu-use-markers (not refs-only)) |
| 1103 | (push (cons (match-string 0) | 1602 | (copy-marker (match-beginning 0)) |
| 1104 | (if imenu-use-markers | 1603 | (match-beginning 0))) |
| 1105 | (copy-marker (match-beginning 0)) | 1604 | items)))) |
| 1106 | (match-beginning 0))) | 1605 | (if (setq continue (antlr-search-forward ";" antlr-skip-line-regexp)) |
| 1107 | items)))) | 1606 | (antlr-skip-rule-postlude t))) |
| 1108 | (if (setq continue (antlr-search-forward ";")) | ||
| 1109 | (antlr-skip-exception-part t)))) | ||
| 1110 | (if classes | 1607 | (if classes |
| 1111 | (cons (cons "Classes" (nreverse classes)) (nreverse items)) | 1608 | (cons (cons (if (eq antlr-tool-version 'antlr-v2) "Classes" "Modes") |
| 1609 | (nreverse classes)) | ||
| 1610 | (nreverse items)) | ||
| 1112 | (nreverse items)))) | 1611 | (nreverse items)))) |
| 1113 | 1612 | ||
| 1114 | 1613 | ||
| @@ -1116,28 +1615,95 @@ IF TOKENREFS-ONLY is non-nil, just return alist with tokenref names." | |||
| 1116 | ;;; Parse grammar files (internal functions) | 1615 | ;;; Parse grammar files (internal functions) |
| 1117 | ;;;=========================================================================== | 1616 | ;;;=========================================================================== |
| 1118 | 1617 | ||
| 1119 | (defun antlr-skip-exception-part (skip-comment) | 1618 | ;; --- simplified v2 grammar ------------------------------------------------- |
| 1120 | "Skip exception part of current rule, i.e., everything after `;'. | 1619 | ;; file: ("header" STRING? ACTION)? OPTIONS? ACTION? class* |
| 1121 | This also includes the options and tokens part of a grammar class | 1620 | ;; class: "class" ID // moved preable action to file rule |
| 1122 | header. If SKIP-COMMENT is non-nil, also skip the comment after that | 1621 | ;; ("extends" ("Lexer"|"Parser"|"TreeParser") ID?)? ";" |
| 1123 | part." | 1622 | ;; OPTIONS? TOKENS? ACTION? rule* |
| 1124 | (let ((pos (point)) | 1623 | ;; rule: ("protected"|"public"|"private")? ID "!"? |
| 1125 | (class nil)) | 1624 | ;; (ARGS)? ('returns' ARGS)? ('throws' IDs )? OPTIONS? ACTION? |
| 1625 | ;; ":" alts ";" ("exception" ARGS? ("catch" ARGS ACTION)* )* | ||
| 1626 | |||
| 1627 | ;; --- simplified v3/v4 grammar ---------------------------------------------- | ||
| 1628 | ;; grammar: ('lexer'|'parser'|'tree')? 'grammar' id ';' | ||
| 1629 | ;; < OPTIONS? TOKENS? (grammar3only|grammar4only) action* > | ||
| 1630 | ;; rule* ('mode' ID ';' rule* )* // lexer MODE is v4 only | ||
| 1631 | ;; grammar3only: ('scope' id ACTION)* // strict sequence in <...> | ||
| 1632 | ;; grammar4only: ('import' IDs ';')? ('channels' ACTION)? // any sequence in <...> | ||
| 1633 | ;; action: '@' (ID '::')? ID ACTION | ||
| 1634 | ;; rule: ('protected'|'public'|'private'|'fragment')? ID '!'? | ||
| 1635 | ;; (ARGS)? ('returns' ARGS)? ('throws' IDs )? ('locals' ARGS)? | ||
| 1636 | ;; < OPTIONS? scope3only action* > | ||
| 1637 | ;; ':' alts ';' ('catch' ARGS ACTION)* ('finally' ACTION)? | ||
| 1638 | ;; scope3only: ('scope' ACTION)? ('scope' IDs ';' )? | ||
| 1639 | |||
| 1640 | (eval-and-compile | ||
| 1641 | (defconst antlr-rule-postlude-skip-alist--const ; const for eval-when-compile safety | ||
| 1642 | '(("exception" 1 . t) ("import" antlr-skip-import-statement) | ||
| 1643 | ("options" 2) ("tokens" 2) ("finally" 2) ("channels" 2) | ||
| 1644 | ("catch" 3) ("scope" 3)) | ||
| 1645 | "Constant for `antlr-rule-postlude-skip-alist'.")) | ||
| 1646 | |||
| 1647 | (defvar antlr-rule-postlude-skip-alist antlr-rule-postlude-skip-alist--const | ||
| 1648 | "Alist of keywords after the ';' which still belong to the grammar rule. | ||
| 1649 | Each element looks like | ||
| 1650 | (KEYWORD FUNCTION ARGS...) | ||
| 1651 | or | ||
| 1652 | (KEYWORD SEXPS-COUNT OPTIONALP) | ||
| 1653 | |||
| 1654 | After the ';' ending a rule body, function `antlr-skip-rule-postlude' | ||
| 1655 | skips whitespace and comments, and check the text after point against | ||
| 1656 | `antlr-rule-postlude-skip-regexp'. While there is a match, | ||
| 1657 | |||
| 1658 | - if regexp group 1 has not been matched: we set point the end of the, | ||
| 1659 | match, and skip the next sexpr, whitespace and comments | ||
| 1660 | |||
| 1661 | - if the string matched by regexp group 1 is not the car of an element | ||
| 1662 | of `antlr-rule-postlude-skip-alist': we skip one sexpr - which should | ||
| 1663 | move point to the end of the whole match, | ||
| 1664 | |||
| 1665 | - when the corresponding element of `antlr-rule-postlude-skip-alist' | ||
| 1666 | is of the first form, we call FUNCTION with arguments ARGS - this | ||
| 1667 | the function should return the position after a match and move | ||
| 1668 | point to the non whitespace/comment position after that | ||
| 1669 | |||
| 1670 | - when the corresponding element of `antlr-rule-postlude-skip-alist' | ||
| 1671 | is of the second form, we skip SEXPS-COUNT balanced expression | ||
| 1672 | (including the keyword itself) | ||
| 1673 | |||
| 1674 | The value might be tool-dependent, see `antlr-tool-version-variables'.") | ||
| 1675 | |||
| 1676 | (defvar antlr-rule-postlude-skip-regexp | ||
| 1677 | (eval-when-compile | ||
| 1678 | (concat (regexp-opt (mapcar #'car antlr-rule-postlude-skip-alist--const) t) | ||
| 1679 | "\\_>\\|@[A-Za-z\300-\326\330-\337_]\\(?:\\sw\\|\\s_\\)*\\(?:::[A-Za-z\300-\326\330-\337_]\\(?:\\sw\\|\\s_\\)*\\)?")) | ||
| 1680 | "Regexp matching things after ';' which still belong to the grammar rule. | ||
| 1681 | See `antlr-rule-postlude-skip-alist' for details. | ||
| 1682 | The value might be tool-dependent, see `antlr-tool-version-variables'.") | ||
| 1683 | |||
| 1684 | (defun antlr-skip-rule-postlude (skip-comment) | ||
| 1685 | "Skip the postlude of a definition, i.e. everything after `;'. | ||
| 1686 | Definitions are rules, grammar/class and v4 mode definition. If | ||
| 1687 | SKIP-COMMENT is non-nil, also skip the whitespace and comment | ||
| 1688 | after that part. See `antlr-rule-postlude-skip-alist'. | ||
| 1689 | |||
| 1690 | Point is assumed to be after the `;'. Always return end position | ||
| 1691 | before trailing whitespaces and comments" | ||
| 1692 | (let ((pos (point))) | ||
| 1126 | (antlr-c-forward-sws) | 1693 | (antlr-c-forward-sws) |
| 1127 | (while (looking-at "options\\>\\|tokens\\>") | 1694 | (while (looking-at antlr-rule-postlude-skip-regexp) |
| 1128 | (setq class t) | 1695 | (if (match-end 1) |
| 1129 | (setq pos (antlr-skip-sexps 2))) | 1696 | (let ((skip (cdr (assoc (match-string-no-properties 1) |
| 1130 | (if class | 1697 | antlr-rule-postlude-skip-alist)))) |
| 1131 | ;; Problem: an action only belongs to a class def, not a normal rule. | 1698 | (if (functionp (car skip)) |
| 1132 | ;; But checking the current rule type is too expensive => only expect | 1699 | (setq pos (apply (car skip) (cdr skip))) |
| 1133 | ;; an action if we have found an option or tokens part. | 1700 | (setq pos (antlr-skip-sexps (or (car skip) 1))) |
| 1134 | (if (looking-at "{") (setq pos (antlr-skip-sexps 1))) | 1701 | (when (and (cdr skip) (eq (char-after) ?\[)) |
| 1135 | (while (looking-at "exception\\>") | 1702 | (setq pos (antlr-skip-sexps 1))))) |
| 1136 | (setq pos (antlr-skip-sexps 1)) | 1703 | (goto-char (match-end 0)) ; to end of @action / @scope::action |
| 1137 | (when (looking-at "\\[") | 1704 | (antlr-c-forward-sws) |
| 1138 | (setq pos (antlr-skip-sexps 1))) | 1705 | (setq pos (antlr-skip-sexps 1)))) |
| 1139 | (while (looking-at "catch\\>") | 1706 | (if (eq (char-after) ?\{) (setq pos (antlr-skip-sexps 1))) ; v2 |
| 1140 | (setq pos (antlr-skip-sexps 3))))) | ||
| 1141 | (or skip-comment (goto-char pos)))) | 1707 | (or skip-comment (goto-char pos)))) |
| 1142 | 1708 | ||
| 1143 | (defun antlr-skip-file-prelude (skip-comment) | 1709 | (defun antlr-skip-file-prelude (skip-comment) |
| @@ -1147,46 +1713,47 @@ Return the start position of the file prelude. | |||
| 1147 | 1713 | ||
| 1148 | Hack: if SKIP-COMMENT is `header-only' only skip header and return | 1714 | Hack: if SKIP-COMMENT is `header-only' only skip header and return |
| 1149 | position before the comment after the header." | 1715 | position before the comment after the header." |
| 1150 | (let* ((pos (point)) | 1716 | (let* ((pos (point)) ; should be (point-min) |
| 1151 | (pos0 pos)) | 1717 | (pos0 pos)) |
| 1152 | (antlr-c-forward-sws) | 1718 | (antlr-c-forward-sws) |
| 1153 | (if skip-comment (setq pos0 (point))) | 1719 | (if skip-comment (setq pos0 (point))) |
| 1154 | (while (looking-at "header\\>[ \t]*\\(\"\\)?") | 1720 | (while (looking-at "header\\_>[ \t]*\\(\"\\)?") |
| 1155 | (setq pos (antlr-skip-sexps (if (match-beginning 1) 3 2)))) | 1721 | (setq pos (antlr-skip-sexps (if (match-beginning 1) 3 2)))) |
| 1156 | (if (eq skip-comment 'header-only) ; a hack... | 1722 | (if (eq skip-comment 'header-only) ; a hack... |
| 1157 | pos | 1723 | pos |
| 1158 | (when (looking-at "options\\>") | 1724 | (when (looking-at "options\\_>") |
| 1159 | (setq pos (antlr-skip-sexps 2))) | 1725 | (setq pos (antlr-skip-sexps 2))) |
| 1726 | (if (eq (char-after) ?\{) (setq pos (antlr-skip-sexps 1))) | ||
| 1160 | (or skip-comment (goto-char pos)) | 1727 | (or skip-comment (goto-char pos)) |
| 1161 | pos0))) | 1728 | pos0))) |
| 1162 | 1729 | ||
| 1163 | (defun antlr-next-rule (arg skip-comment) | 1730 | (defun antlr-next-rule (arg skip-comment) |
| 1164 | "Move forward to next end of rule. Do it ARG many times. | 1731 | "Move forward to next end of rule. Do it ARG many times. |
| 1165 | A grammar class header and the file prelude are also considered as a | 1732 | A grammar/class definition and the file prelude of Antlr v2 |
| 1166 | rule. Negative argument ARG means move back to ARGth preceding end of | 1733 | grammars are also considered as a rule. Negative argument ARG |
| 1167 | rule. The behavior is not defined when ARG is zero. If SKIP-COMMENT | 1734 | means move back to ARGth preceding end of rule. The behavior is |
| 1168 | is non-nil, move to beginning of the rule." | 1735 | not defined when ARG is zero. If SKIP-COMMENT is non-nil, move |
| 1169 | ;; WARNING: Should only be used with `antlr-action-syntax-table'! | 1736 | to beginning of the rule." |
| 1170 | ;; PRE: ARG<>0 | 1737 | ;; PRE: ARG<>0 |
| 1171 | (let ((pos (point)) | 1738 | (let ((pos (point)) |
| 1172 | (beg (point))) | 1739 | (beg (point))) |
| 1173 | ;; first look whether point is in exception part | 1740 | ;; first look whether point is in rule postlude |
| 1174 | (if (antlr-search-backward ";") | 1741 | (if (antlr-search-backward ";" antlr-skip-line-regexp) |
| 1175 | (progn | 1742 | (progn |
| 1176 | (setq beg (point)) | 1743 | (setq beg (point)) |
| 1177 | (forward-char) | 1744 | (forward-char) |
| 1178 | (antlr-skip-exception-part skip-comment)) | 1745 | (antlr-skip-rule-postlude skip-comment)) |
| 1179 | (antlr-skip-file-prelude skip-comment)) | 1746 | (antlr-skip-file-prelude skip-comment)) |
| 1180 | (if (< arg 0) | 1747 | (if (< arg 0) |
| 1181 | (unless (and (< (point) pos) (zerop (cl-incf arg))) | 1748 | (unless (and (< (point) pos) (zerop (cl-incf arg))) |
| 1182 | ;; if we have moved backward, we already moved one defun backward | 1749 | ;; if we have moved backward, we already moved one defun backward |
| 1183 | (goto-char beg) ; rewind (to ";" / point) | 1750 | (goto-char beg) ; rewind (to ";" / point) |
| 1184 | (while (and arg (<= (cl-incf arg) 0)) | 1751 | (while (and arg (<= (cl-incf arg) 0)) |
| 1185 | (if (antlr-search-backward ";") | 1752 | (if (antlr-search-backward ";" antlr-skip-line-regexp) |
| 1186 | (setq beg (point)) | 1753 | (setq beg (point)) |
| 1187 | (when (>= arg -1) | 1754 | (when (>= arg -1) |
| 1188 | ;; try file prelude: | 1755 | ;; try file prelude: |
| 1189 | (setq pos (antlr-skip-file-prelude skip-comment)) | 1756 | (setq pos (antlr-skip-file-prelude skip-comment)) ; header pos |
| 1190 | (if (zerop arg) | 1757 | (if (zerop arg) |
| 1191 | (if (>= (point) beg) | 1758 | (if (>= (point) beg) |
| 1192 | (goto-char (if (>= pos beg) (point-min) pos))) | 1759 | (goto-char (if (>= pos beg) (point-min) pos))) |
| @@ -1195,21 +1762,20 @@ is non-nil, move to beginning of the rule." | |||
| 1195 | (setq arg nil))) | 1762 | (setq arg nil))) |
| 1196 | (when arg ; always found a ";" | 1763 | (when arg ; always found a ";" |
| 1197 | (forward-char) | 1764 | (forward-char) |
| 1198 | (antlr-skip-exception-part skip-comment))) | 1765 | (antlr-skip-rule-postlude skip-comment))) |
| 1199 | (if (<= (point) pos) ; moved backward? | 1766 | (if (<= (point) pos) ; moved backward? |
| 1200 | (goto-char pos) ; rewind | 1767 | (goto-char pos) ; rewind |
| 1201 | (decf arg)) ; already moved one defun forward | 1768 | (decf arg)) ; already moved one defun forward |
| 1202 | (unless (zerop arg) | 1769 | (unless (zerop arg) |
| 1203 | (while (>= (decf arg) 0) | 1770 | (while (>= (decf arg) 0) |
| 1204 | (antlr-search-forward ";")) | 1771 | (antlr-search-forward ";" antlr-skip-line-regexp)) |
| 1205 | (antlr-skip-exception-part skip-comment))))) | 1772 | (antlr-skip-rule-postlude skip-comment))))) |
| 1206 | 1773 | ||
| 1207 | (defun antlr-outside-rule-p () | 1774 | (defun antlr-outside-rule-p () |
| 1208 | "Non-nil if point is outside a grammar rule. | 1775 | "Non-nil if point is outside a grammar rule. |
| 1209 | Move to the beginning of the current rule if point is inside a rule." | 1776 | Move to the beginning of the current rule if point is inside a rule." |
| 1210 | ;; WARNING: Should only be used with `antlr-action-syntax-table'! | ||
| 1211 | (let ((pos (point))) | 1777 | (let ((pos (point))) |
| 1212 | (antlr-next-rule -1 nil) | 1778 | (antlr-next-rule -1 nil) ; to end of previous rule |
| 1213 | (let ((between (or (bobp) (< (point) pos)))) | 1779 | (let ((between (or (bobp) (< (point) pos)))) |
| 1214 | (antlr-c-forward-sws) | 1780 | (antlr-c-forward-sws) |
| 1215 | (and between (> (point) pos) (goto-char pos))))) | 1781 | (and between (> (point) pos) (goto-char pos))))) |
| @@ -1225,58 +1791,70 @@ Move to the beginning of the current rule if point is inside a rule." | |||
| 1225 | A grammar class header and the file prelude are also considered as a | 1791 | A grammar class header and the file prelude are also considered as a |
| 1226 | rule." | 1792 | rule." |
| 1227 | (save-excursion | 1793 | (save-excursion |
| 1228 | (with-syntax-table antlr-action-syntax-table | 1794 | (not (antlr-outside-rule-p)))) |
| 1229 | (not (antlr-outside-rule-p))))) | ||
| 1230 | 1795 | ||
| 1231 | (defun antlr-end-of-rule (&optional arg) | 1796 | (defun antlr-end-of-rule (&optional arg) |
| 1232 | "Move forward to next end of rule. Do it ARG [default: 1] many times. | 1797 | "Move forward to next/end of rule. Do it ARG [default: 1] many times. |
| 1233 | A grammar class header and the file prelude are also considered as a | 1798 | A grammar/class header and the file prelude are also considered a |
| 1234 | rule. Negative argument ARG means move back to ARGth preceding end of | 1799 | rule. |
| 1800 | |||
| 1801 | If `antlr-end-of-defun-is-next' is nil, move to next end of rule, | ||
| 1802 | i.e. the end of the current rule with ARG = 1. Otherwise move | ||
| 1803 | forward to the ARGth next rule. | ||
| 1804 | |||
| 1805 | Negative argument ARG means move back to ARGth preceding end of | ||
| 1235 | rule. If ARG is zero, run `antlr-end-of-body'." | 1806 | rule. If ARG is zero, run `antlr-end-of-body'." |
| 1236 | (interactive "^p") | 1807 | (interactive "^p") |
| 1808 | ;; yes, there is a variable `end-of-defun-function', but `end-of-defun' does | ||
| 1809 | ;; far too much around the funcall of that variable (Emacs-24.4) | ||
| 1237 | (if (zerop arg) | 1810 | (if (zerop arg) |
| 1238 | (antlr-end-of-body) | 1811 | (antlr-end-of-body) |
| 1239 | (with-syntax-table antlr-action-syntax-table | 1812 | (antlr-next-rule arg (and antlr-end-of-defun-is-next (> arg 0))))) |
| 1240 | (antlr-next-rule arg nil)))) | ||
| 1241 | 1813 | ||
| 1242 | (defun antlr-beginning-of-rule (&optional arg) | 1814 | (defun antlr-beginning-of-rule (&optional arg) |
| 1243 | "Move backward to preceding beginning of rule. Do it ARG many times. | 1815 | "Move backward to preceding beginning of rule. Do it ARG many times. |
| 1244 | A grammar class header and the file prelude are also considered as a | 1816 | A grammar/class header and the file prelude are also considered a |
| 1245 | rule. Negative argument ARG means move forward to ARGth next beginning | 1817 | rule. |
| 1246 | of rule. If ARG is zero, run `antlr-beginning-of-body'." | 1818 | |
| 1819 | Negative argument ARG means move forward to abs(ARG)th next rule: | ||
| 1820 | beginning of rule if `antlr-end-of-defun-is-next' is nil, and end | ||
| 1821 | of rule otherwise. | ||
| 1822 | |||
| 1823 | If ARG is zero, run `antlr-beginning-of-body'." | ||
| 1247 | (interactive "^p") | 1824 | (interactive "^p") |
| 1248 | (if (zerop arg) | 1825 | (if (zerop arg) |
| 1249 | (antlr-beginning-of-body) | 1826 | (antlr-beginning-of-body) |
| 1250 | (with-syntax-table antlr-action-syntax-table | 1827 | (antlr-next-rule (- arg) (if antlr-end-of-defun-is-next (> arg 0) t)))) |
| 1251 | (antlr-next-rule (- arg) t)))) | ||
| 1252 | 1828 | ||
| 1253 | (defun antlr-end-of-body (&optional msg) | 1829 | (defun antlr-end-of-body (&optional msg) |
| 1254 | "Move to position after the `;' of the current rule. | 1830 | "Move to position after the `;' of the current rule. |
| 1255 | A grammar class header is also considered as a rule. With optional | 1831 | A grammar class header is also considered as a rule. With optional |
| 1256 | prefix arg MSG, move to `:'." | 1832 | prefix arg MSG, move to `:'." |
| 1257 | (interactive "^") | 1833 | (interactive "^") |
| 1258 | (with-syntax-table antlr-action-syntax-table | 1834 | (let ((orig (point))) |
| 1259 | (let ((orig (point))) | 1835 | (if (antlr-outside-rule-p) |
| 1260 | (if (antlr-outside-rule-p) | 1836 | (error "Outside an ANTLR rule")) |
| 1261 | (error "Outside an ANTLR rule")) | 1837 | (let ((bor (point))) ; beginning of current rule |
| 1262 | (let ((bor (point))) | 1838 | (when (< (antlr-skip-file-prelude t) (point)) |
| 1263 | (when (< (antlr-skip-file-prelude t) (point)) | 1839 | ;; Yes, we are in the file prelude |
| 1264 | ;; Yes, we are in the file prelude | 1840 | (goto-char orig) |
| 1265 | (goto-char orig) | 1841 | (error (or msg "The file prelude is without `;'"))) |
| 1266 | (error (or msg "The file prelude is without `;'"))) | 1842 | (antlr-search-forward ";" antlr-skip-line-regexp) |
| 1267 | (antlr-search-forward ";") | 1843 | (when msg |
| 1268 | (when msg | 1844 | (when (< (point) |
| 1269 | (when (< (point) | 1845 | (progn (goto-char bor) |
| 1270 | (progn (goto-char bor) | 1846 | (or (antlr-search-forward antlr-rule-body-start-op) |
| 1271 | (or (antlr-search-forward ":") (point-max)))) | 1847 | (point-max)))) |
| 1272 | (goto-char orig) | 1848 | (goto-char orig) |
| 1273 | (error msg)) | 1849 | (error msg)) |
| 1274 | (antlr-c-forward-sws)))))) | 1850 | (antlr-c-forward-sws))))) |
| 1275 | 1851 | ||
| 1276 | (defun antlr-beginning-of-body () | 1852 | (defun antlr-beginning-of-body () |
| 1277 | "Move to the first element after the `:' of the current rule." | 1853 | "Move to the first element after the `:' of the current rule." |
| 1278 | (interactive "^") | 1854 | (interactive "^") |
| 1279 | (antlr-end-of-body "Class headers and the file prelude are without `:'")) | 1855 | (antlr-end-of-body (if (eq antlr-tool-version 'antlr-v2) |
| 1856 | "Class definitions and the file prelude are without `:'" | ||
| 1857 | "Grammar and mode definitions are without `:'"))) | ||
| 1280 | 1858 | ||
| 1281 | 1859 | ||
| 1282 | ;;;=========================================================================== | 1860 | ;;;=========================================================================== |
| @@ -1291,11 +1869,9 @@ If non-nil, TRANSFORM is used on literals instead of `downcase-region'." | |||
| 1291 | (let ((literals 0)) | 1869 | (let ((literals 0)) |
| 1292 | (save-excursion | 1870 | (save-excursion |
| 1293 | (goto-char (point-min)) | 1871 | (goto-char (point-min)) |
| 1294 | (with-syntax-table antlr-action-syntax-table | 1872 | (while (antlr-re-search-forward "\"\\(\\sw\\(\\sw\\|\\s_\\|-\\)*\\)\"" nil) ; TODO: '...' |
| 1295 | (antlr-invalidate-context-cache) | 1873 | (funcall transform (match-beginning 0) (match-end 0)) |
| 1296 | (while (antlr-re-search-forward "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" nil) | 1874 | (cl-incf literals))) |
| 1297 | (funcall transform (match-beginning 0) (match-end 0)) | ||
| 1298 | (cl-incf literals)))) | ||
| 1299 | (message "Transformed %d literals" literals))) | 1875 | (message "Transformed %d literals" literals))) |
| 1300 | 1876 | ||
| 1301 | (defun antlr-upcase-literals () | 1877 | (defun antlr-upcase-literals () |
| @@ -1303,6 +1879,9 @@ If non-nil, TRANSFORM is used on literals instead of `downcase-region'." | |||
| 1303 | (interactive) | 1879 | (interactive) |
| 1304 | (antlr-downcase-literals 'upcase-region)) | 1880 | (antlr-downcase-literals 'upcase-region)) |
| 1305 | 1881 | ||
| 1882 | ;; TODO: `antlr-hide-actions' should probably be a minor mode like | ||
| 1883 | ;; `hide-ifdef-mode'. Whether to exclude arguments (of limited use) should be | ||
| 1884 | ;; controlled by `antlr-action-visibility' (negative value) | ||
| 1306 | (defun antlr-hide-actions (arg &optional silent) | 1885 | (defun antlr-hide-actions (arg &optional silent) |
| 1307 | "Hide or unhide all actions in buffer. | 1886 | "Hide or unhide all actions in buffer. |
| 1308 | Hide all actions including arguments in brackets if ARG is 1 or if | 1887 | Hide all actions including arguments in brackets if ARG is 1 or if |
| @@ -1320,24 +1899,22 @@ Display a message unless optional argument SILENT is non-nil." | |||
| 1320 | (antlr-hide-actions 0 t) | 1899 | (antlr-hide-actions 0 t) |
| 1321 | (save-excursion | 1900 | (save-excursion |
| 1322 | (goto-char (point-min)) | 1901 | (goto-char (point-min)) |
| 1323 | (with-syntax-table antlr-action-syntax-table | 1902 | (while (antlr-re-search-forward regexp nil) |
| 1324 | (antlr-invalidate-context-cache) | 1903 | (let ((beg (ignore-errors (scan-sexps (point) -1)))) |
| 1325 | (while (antlr-re-search-forward regexp nil) | 1904 | (when beg |
| 1326 | (let ((beg (ignore-errors (scan-sexps (point) -1)))) | 1905 | (if diff ; braces are visible |
| 1327 | (when beg | 1906 | (if (> (point) (+ beg diff)) |
| 1328 | (if diff ; braces are visible | 1907 | (add-text-properties (1+ beg) (1- (point)) |
| 1329 | (if (> (point) (+ beg diff)) | 1908 | '(invisible t intangible t))) |
| 1330 | (add-text-properties (1+ beg) (1- (point)) | 1909 | ;; if actions is on line(s) of its own, hide WS |
| 1331 | '(invisible t intangible t))) | 1910 | (and (looking-at "[ \t]*$") |
| 1332 | ;; if actions is on line(s) of its own, hide WS | 1911 | (save-excursion |
| 1333 | (and (looking-at "[ \t]*$") | 1912 | (goto-char beg) |
| 1334 | (save-excursion | 1913 | (skip-chars-backward " \t") |
| 1335 | (goto-char beg) | 1914 | (and (bolp) (setq beg (point)))) |
| 1336 | (skip-chars-backward " \t") | 1915 | (beginning-of-line 2)) ; beginning of next line |
| 1337 | (and (bolp) (setq beg (point)))) | 1916 | (add-text-properties beg (point) |
| 1338 | (beginning-of-line 2)) ; beginning of next line | 1917 | '(invisible t intangible t))))))) |
| 1339 | (add-text-properties beg (point) | ||
| 1340 | '(invisible t intangible t)))))))) | ||
| 1341 | (or silent | 1918 | (or silent |
| 1342 | (message "Hide all actions (%s arguments)...done" | 1919 | (message "Hide all actions (%s arguments)...done" |
| 1343 | (if (= arg 1) "including" "excluding")))) | 1920 | (if (= arg 1) "including" "excluding")))) |
| @@ -1379,10 +1956,7 @@ Inserting an option with this command works as follows: | |||
| 1379 | according to a newly inserted language option. | 1956 | according to a newly inserted language option. |
| 1380 | 1957 | ||
| 1381 | The name of all options with a specification for their values are stored | 1958 | The name of all options with a specification for their values are stored |
| 1382 | in `antlr-options-alists'. The used specification also depends on the | 1959 | in `antlr-options-alists' which depends on `antlr-tool-version'. |
| 1383 | value of `antlr-tool-version', i.e., step 4 will warn you if you use an | ||
| 1384 | option that has been introduced in newer version of ANTLR, and step 5 | ||
| 1385 | will offer completion using version-correct values. | ||
| 1386 | 1960 | ||
| 1387 | If the option already exists inside the visible part of the buffer, this | 1961 | If the option already exists inside the visible part of the buffer, this |
| 1388 | command can be used to change the value of that option. Otherwise, find | 1962 | command can be used to change the value of that option. Otherwise, find |
| @@ -1410,6 +1984,7 @@ This command might also set the mark like \\[set-mark-command] does, see | |||
| 1410 | (barf-if-buffer-read-only) | 1984 | (barf-if-buffer-read-only) |
| 1411 | (or location (setq location (cdr (antlr-option-kind level)))) | 1985 | (or location (setq location (cdr (antlr-option-kind level)))) |
| 1412 | (cond ((null level) | 1986 | (cond ((null level) |
| 1987 | ;; TODO: better msg if there is (currently) no such option | ||
| 1413 | (error "Cannot deduce what kind of option to insert")) | 1988 | (error "Cannot deduce what kind of option to insert")) |
| 1414 | ((atom location) | 1989 | ((atom location) |
| 1415 | (error "Cannot insert any %s options around here" | 1990 | (error "Cannot insert any %s options around here" |
| @@ -1430,7 +2005,7 @@ This command might also set the mark like \\[set-mark-command] does, see | |||
| 1430 | (goto-char (max (point-min) (car area))) | 2005 | (goto-char (max (point-min) (car area))) |
| 1431 | (re-search-forward (concat "\\(^\\|;\\)[ \t]*\\(\\<" | 2006 | (re-search-forward (concat "\\(^\\|;\\)[ \t]*\\(\\<" |
| 1432 | (regexp-quote option) | 2007 | (regexp-quote option) |
| 1433 | "\\>\\)[ \t\n]*\\(\\(=[ \t]?\\)[ \t]*\\(\\(\\sw\\|\\s_\\)+\\|\"\\([^\n\"\\]\\|[\\][^\n]\\)*\"\\)?\\)?") | 2008 | "\\_>\\)[ \t\n]*\\(\\(=[ \t]?\\)[ \t]*\\(\\(\\sw\\|\\s_\\)+\\|\"\\([^\n\"\\]\\|[\\][^\n]\\)*\"\\)?\\)?") |
| 1434 | ;; 2=name, 3=4+5, 4="=", 5=value | 2009 | ;; 2=name, 3=4+5, 4="=", 5=value |
| 1435 | (min (point-max) (cdr area)) | 2010 | (min (point-max) (cdr area)) |
| 1436 | t)) | 2011 | t)) |
| @@ -1449,7 +2024,7 @@ This command might also set the mark like \\[set-mark-command] does, see | |||
| 1449 | 2024 | ||
| 1450 | (defun antlr-insert-option-interactive (arg) | 2025 | (defun antlr-insert-option-interactive (arg) |
| 1451 | "Interactive specification for `antlr-insert-option'. | 2026 | "Interactive specification for `antlr-insert-option'. |
| 1452 | Return \(LEVEL OPTION LOCATION)." | 2027 | Use `current-prefix-arg' for ARG. Return \(LEVEL OPTION LOCATION)." |
| 1453 | (barf-if-buffer-read-only) | 2028 | (barf-if-buffer-read-only) |
| 1454 | (if arg (setq arg (prefix-numeric-value arg))) | 2029 | (if arg (setq arg (prefix-numeric-value arg))) |
| 1455 | (unless (memq arg '(nil 1 2 3 4)) | 2030 | (unless (memq arg '(nil 1 2 3 4)) |
| @@ -1468,7 +2043,6 @@ Return \(LEVEL OPTION LOCATION)." | |||
| 1468 | 2043 | ||
| 1469 | (defun antlr-options-menu-filter (level _menu-items) | 2044 | (defun antlr-options-menu-filter (level _menu-items) |
| 1470 | "Return items for options submenu of level LEVEL." | 2045 | "Return items for options submenu of level LEVEL." |
| 1471 | ;; checkdoc-params: (menu-items) | ||
| 1472 | (let ((active (if buffer-read-only | 2046 | (let ((active (if buffer-read-only |
| 1473 | nil | 2047 | nil |
| 1474 | (consp (cdr-safe (cdr (antlr-option-kind level))))))) | 2048 | (consp (cdr-safe (cdr (antlr-option-kind level))))))) |
| @@ -1505,7 +2079,7 @@ like \(AREA . PLACE), see `antlr-option-location'." | |||
| 1505 | ((not (eq level 3)) ; grammar or subrule options | 2079 | ((not (eq level 3)) ; grammar or subrule options |
| 1506 | (setq pos (point)) | 2080 | (setq pos (point)) |
| 1507 | (antlr-c-forward-sws)) | 2081 | (antlr-c-forward-sws)) |
| 1508 | ((looking-at "^\\(private[ \t\n]\\|public[ \t\n]\\|protected[ \t\n]\\)?[ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)[ \t\n]*\\(!\\)?[ \t\n]*\\(\\[\\)?") | 2082 | ((looking-at "^\\(private[ \t\n]\\|public[ \t\n]\\|protected[ \t\n]\\|fragment[ \t\n]\\)?[ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)[ \t\n]*\\(!\\)?[ \t\n]*\\(\\[\\)?") |
| 1509 | ;; rule options, with complete rule header | 2083 | ;; rule options, with complete rule header |
| 1510 | (goto-char (or (match-end 4) (match-end 3))) | 2084 | (goto-char (or (match-end 4) (match-end 3))) |
| 1511 | (setq pos (antlr-skip-sexps (if (match-end 5) 1 0))) | 2085 | (setq pos (antlr-skip-sexps (if (match-end 5) 1 0))) |
| @@ -1540,51 +2114,51 @@ the rule/subrule after the init action. Otherwise, the point position | |||
| 1540 | is undefined." | 2114 | is undefined." |
| 1541 | (widen) | 2115 | (widen) |
| 1542 | (if (eq requested 1) | 2116 | (if (eq requested 1) |
| 1543 | 1 | 2117 | (and (car antlr-options-alists) 1) |
| 1544 | (with-syntax-table antlr-action-syntax-table | 2118 | (let* ((orig (point)) |
| 1545 | (antlr-invalidate-context-cache) | 2119 | (outsidep (antlr-outside-rule-p)) |
| 1546 | (let* ((orig (point)) | 2120 | bor) |
| 1547 | (outsidep (antlr-outside-rule-p)) | 2121 | (setq bor (point)) ; beginning of rule |
| 1548 | bor depth) | 2122 | (cond ((eq requested 2) ; grammar options required? |
| 1549 | (if (eq (char-after) ?\{) (antlr-skip-sexps 1)) | 2123 | (antlr-try-rule-or-grammar-option requested bor)) |
| 1550 | (setq bor (point)) ; beginning of rule (after init action) | 2124 | ((and (car antlr-options-alists) ; file options available (v2) |
| 1551 | (cond ((eq requested 2) ; grammar options required? | 2125 | (save-excursion ; in region of file options? |
| 1552 | (let (boc) ; beginning of class | 2126 | (goto-char (point-min)) |
| 1553 | (goto-char (point-min)) | 2127 | (antlr-skip-file-prelude t) ; ws/comment after: OK |
| 1554 | (while (and (<= (point) bor) | 2128 | (< orig (point)))) |
| 1555 | (antlr-re-search-forward antlr-class-header-regexp | 2129 | (and (null requested) 1)) |
| 1556 | nil)) | 2130 | (outsidep ; outside -> grammar option |
| 1557 | (if (<= (match-beginning 0) bor) | 2131 | (when (memq requested '(nil 2)) |
| 1558 | (setq boc (match-end 0)))) | 2132 | (antlr-try-rule-or-grammar-option 2 bor))) |
| 1559 | (when boc | 2133 | ((looking-at antlr-grammar-header-regexp) ; rule = class def? |
| 1560 | (goto-char boc) | 2134 | (goto-char (match-end 0)) |
| 1561 | 2))) | 2135 | (and (null requested) 2)) |
| 1562 | ((save-excursion ; in region of file options? | 2136 | ((or (eq requested 3) (null (elt antlr-options-alists 3))) |
| 1563 | (goto-char (point-min)) | 2137 | (antlr-try-rule-or-grammar-option requested bor)) |
| 1564 | (antlr-skip-file-prelude t) ; ws/comment after: OK | 2138 | ((antlr-syntactic-grammar-depth orig bor t) |
| 1565 | (< orig (point))) | 2139 | 4) |
| 1566 | (and (null requested) 1)) | 2140 | (t |
| 1567 | (outsidep ; outside rule not OK | 2141 | (antlr-try-rule-or-grammar-option requested bor)))))) |
| 1568 | nil) | 2142 | |
| 1569 | ((looking-at antlr-class-header-regexp) ; rule = class def? | 2143 | (defun antlr-try-rule-or-grammar-option (requested bor) |
| 1570 | (goto-char (match-end 0)) | 2144 | "Try whether rule or grammar option can be applied. |
| 1571 | (and (null requested) 2)) | 2145 | Called by function `antlr-option-level' with arguments REQUESTED, |
| 1572 | ((eq requested 3) ; rule options required? | 2146 | and BOR poiting to the beginning of the current rule." |
| 1573 | (goto-char bor) | 2147 | (or (and (memq requested '(nil 3)) (elt antlr-options-alists 2) |
| 1574 | 3) | 2148 | (progn (goto-char bor) 3)) |
| 1575 | ((setq depth (antlr-syntactic-grammar-depth orig bor)) | 2149 | (and (memq requested '(nil 2)) (cadr antlr-options-alists) |
| 1576 | (if (> depth 0) ; move out of actions | 2150 | (let (boc) ; beginning of class |
| 1577 | (goto-char (scan-lists (point) -1 depth))) | 2151 | (goto-char (point-min)) |
| 1578 | (set-syntax-table antlr-mode-syntax-table) | 2152 | (while (and (<= (point) bor) |
| 1579 | (antlr-invalidate-context-cache) | 2153 | (antlr-re-search-forward antlr-grammar-header-regexp nil)) |
| 1580 | (if (eq (antlr-syntactic-context) 0) ; not in subrule? | 2154 | (if (<= (match-beginning 0) bor) |
| 1581 | (unless (eq requested 4) | 2155 | (setq boc (match-end 0)))) |
| 1582 | (goto-char bor) | 2156 | (when boc |
| 1583 | 3) | 2157 | (goto-char boc) |
| 1584 | (goto-char (1+ (scan-lists (point) -1 1))) | 2158 | 2))))) |
| 1585 | 4))))))) | ||
| 1586 | 2159 | ||
| 1587 | (defun antlr-option-location (orig min-vis max-vis min-area max-area withp) | 2160 | (defun antlr-option-location (orig min-vis max-vis min-area max-area withp) |
| 2161 | ;; checkdoc-order: nil | ||
| 1588 | "Return location for the options area. | 2162 | "Return location for the options area. |
| 1589 | ORIG is the original position of `point', MIN-VIS is `point-min' and | 2163 | ORIG is the original position of `point', MIN-VIS is `point-min' and |
| 1590 | MAX-VIS is `point-max'. If WITHP is non-nil, there exists an option | 2164 | MAX-VIS is `point-max'. If WITHP is non-nil, there exists an option |
| @@ -1616,26 +2190,25 @@ non-nil." | |||
| 1616 | ;; use start of options area (only if `withp') | 2190 | ;; use start of options area (only if `withp') |
| 1617 | (cons min-area 'beginning))))) | 2191 | (cons min-area 'beginning))))) |
| 1618 | 2192 | ||
| 1619 | (defun antlr-syntactic-grammar-depth (pos beg) | 2193 | (defun antlr-syntactic-grammar-depth (pos beg &optional outside-action) |
| 1620 | "Return syntactic context depth at POS. | 2194 | "Return syntactic context depth at POS. |
| 1621 | Move to POS and from there on to the beginning of the string or comment | 2195 | Move to POS and from there on to the beginning of the string or comment |
| 1622 | if POS is inside such a construct. Then, return the syntactic context | 2196 | if POS is inside such a construct. Then, return the syntactic context |
| 1623 | depth at point if the point position is smaller than BEG. | 2197 | depth at point if the point position is smaller than BEG. |
| 1624 | WARNING: this may alter `match-data'." | 2198 | WARNING: this may alter `match-data'. |
| 2199 | With optional argument OUTSIDE-ACTION, move to beginning of action." | ||
| 1625 | (goto-char pos) | 2200 | (goto-char pos) |
| 1626 | (let ((context (or (antlr-syntactic-context) 0))) | 2201 | (let ((ppss (syntax-ppss))) |
| 1627 | (while (and context (not (integerp context))) | 2202 | (when (or (nth 3 ppss) (nth 4 ppss)) ; string or comment -> to beginning |
| 1628 | (cond ((eq context 'string) | 2203 | (goto-char (nth 8 ppss))) |
| 1629 | (setq context | 2204 | (when outside-action |
| 1630 | (and (search-backward "\"" nil t) | 2205 | (let ((poss (nth 9 ppss)) ; TODO: syntax-ppss-open-positions |
| 1631 | (>= (point) beg) | 2206 | open) |
| 1632 | (or (antlr-syntactic-context) 0)))) | 2207 | (while (and poss (eq (char-after (car poss)) ?\()) |
| 1633 | ((memq context '(comment block-comment)) | 2208 | (setq open (pop poss))) |
| 1634 | (setq context | 2209 | (when open |
| 1635 | (and (re-search-backward "/[/*]" nil t) | 2210 | (goto-char (1+ open)) |
| 1636 | (>= (point) beg) | 2211 | (>= open beg)))))) |
| 1637 | (or (antlr-syntactic-context) 0)))))) | ||
| 1638 | context)) | ||
| 1639 | 2212 | ||
| 1640 | 2213 | ||
| 1641 | ;;;=========================================================================== | 2214 | ;;;=========================================================================== |
| @@ -1643,6 +2216,7 @@ WARNING: this may alter `match-data'." | |||
| 1643 | ;;;=========================================================================== | 2216 | ;;;=========================================================================== |
| 1644 | 2217 | ||
| 1645 | (defun antlr-insert-option-do (level option old area pos) | 2218 | (defun antlr-insert-option-do (level option old area pos) |
| 2219 | ;; checkdoc-order: nil | ||
| 1646 | "Insert option into buffer at position POS. | 2220 | "Insert option into buffer at position POS. |
| 1647 | Insert option of level LEVEL and name OPTION. If OLD is non-nil, an | 2221 | Insert option of level LEVEL and name OPTION. If OLD is non-nil, an |
| 1648 | options area is already exists. If OLD looks like \(BEG . END), the | 2222 | options area is already exists. If OLD looks like \(BEG . END), the |
| @@ -1654,7 +2228,7 @@ If the original point position was outside an options area, AREA is nil. | |||
| 1654 | Otherwise, and if an option specification already exists, AREA is a cons | 2228 | Otherwise, and if an option specification already exists, AREA is a cons |
| 1655 | cell where the two values determine the area inside the braces." | 2229 | cell where the two values determine the area inside the braces." |
| 1656 | (let* ((spec (cdr (assoc option (elt antlr-options-alists (1- level))))) | 2230 | (let* ((spec (cdr (assoc option (elt antlr-options-alists (1- level))))) |
| 1657 | (value (antlr-option-spec level option (cdr spec) (consp old)))) | 2231 | (value (cdr spec))) |
| 1658 | (if (fboundp (car spec)) (funcall (car spec) 'before-input option)) | 2232 | (if (fboundp (car spec)) (funcall (car spec) 'before-input option)) |
| 1659 | ;; set mark (unless point was inside options area before) | 2233 | ;; set mark (unless point was inside options area before) |
| 1660 | (if (cond (area (eq antlr-options-push-mark t)) | 2234 | (if (cond (area (eq antlr-options-push-mark t)) |
| @@ -1677,7 +2251,6 @@ cell where the two values determine the area inside the braces." | |||
| 1677 | (elt antlr-options-headings (1- level)) | 2251 | (elt antlr-options-headings (1- level)) |
| 1678 | option)) | 2252 | option)) |
| 1679 | ;; option specification found | 2253 | ;; option specification found |
| 1680 | (setq value (cdr value)) | ||
| 1681 | (if (car value) | 2254 | (if (car value) |
| 1682 | (let ((initial (and (consp old) (cdr old) | 2255 | (let ((initial (and (consp old) (cdr old) |
| 1683 | (buffer-substring (car old) (cdr old))))) | 2256 | (buffer-substring (car old) (cdr old))))) |
| @@ -1703,42 +2276,13 @@ cell where the two values determine the area inside the braces." | |||
| 1703 | ;; final ----------------------------------------------------------------- | 2276 | ;; final ----------------------------------------------------------------- |
| 1704 | (if (fboundp (car spec)) (funcall (car spec) 'after-insertion option)))) | 2277 | (if (fboundp (car spec)) (funcall (car spec) 'after-insertion option)))) |
| 1705 | 2278 | ||
| 1706 | (defun antlr-option-spec (level option specs existsp) | ||
| 1707 | "Return version correct option value specification. | ||
| 1708 | Return specification for option OPTION of kind level LEVEL. SPECS | ||
| 1709 | should correspond to the VALUE-SPEC... in `antlr-options-alists'. | ||
| 1710 | EXISTSP determines whether the option already exists." | ||
| 1711 | (let (value) | ||
| 1712 | (while (and specs (>= antlr-tool-version (caar specs))) | ||
| 1713 | (setq value (pop specs))) | ||
| 1714 | (cond (value) ; found correct spec | ||
| 1715 | ((null specs) nil) ; didn't find any specs | ||
| 1716 | (existsp (car specs)) ; wrong version, but already present | ||
| 1717 | ((y-or-n-p (format "Insert v%s %s option %s in v%s? " | ||
| 1718 | (antlr-version-string (caar specs)) | ||
| 1719 | (elt antlr-options-headings (1- level)) | ||
| 1720 | option | ||
| 1721 | (antlr-version-string antlr-tool-version))) | ||
| 1722 | (car specs)) | ||
| 1723 | (t | ||
| 1724 | (error "Didn't insert v%s %s option %s in v%s" | ||
| 1725 | (antlr-version-string (caar specs)) | ||
| 1726 | (elt antlr-options-headings (1- level)) | ||
| 1727 | option | ||
| 1728 | (antlr-version-string antlr-tool-version)))))) | ||
| 1729 | |||
| 1730 | (defun antlr-version-string (version) | ||
| 1731 | "Format the Antlr version number VERSION, see `antlr-tool-version'." | ||
| 1732 | (let ((version100 (/ version 100))) | ||
| 1733 | (format "%d.%d.%d" | ||
| 1734 | (/ version100 100) (mod version100 100) (mod version 100)))) | ||
| 1735 | |||
| 1736 | 2279 | ||
| 1737 | ;;;=========================================================================== | 2280 | ;;;=========================================================================== |
| 1738 | ;;; Insert options: the details (used by `antlr-insert-option-do') | 2281 | ;;; Insert options: the details (used by `antlr-insert-option-do') |
| 1739 | ;;;=========================================================================== | 2282 | ;;;=========================================================================== |
| 1740 | 2283 | ||
| 1741 | (defun antlr-insert-option-existing (old value) | 2284 | (defun antlr-insert-option-existing (old value) |
| 2285 | ;; checkdoc-order: nil | ||
| 1742 | "Insert option value VALUE at point for existing option. | 2286 | "Insert option value VALUE at point for existing option. |
| 1743 | For OLD, see `antlr-insert-option-do'." | 2287 | For OLD, see `antlr-insert-option-do'." |
| 1744 | ;; no = => insert = | 2288 | ;; no = => insert = |
| @@ -1777,7 +2321,7 @@ For AREA and OLD, see `antlr-insert-option-do'." | |||
| 1777 | (skip-chars-forward " \t") | 2321 | (skip-chars-forward " \t") |
| 1778 | 2322 | ||
| 1779 | (if (looking-at "$\\|//") | 2323 | (if (looking-at "$\\|//") |
| 1780 | ;; just comment after point => skip (+ lines with same col comment) | 2324 | ;; just comment after point => skip (+ lines with same col comment) |
| 1781 | (let ((same (if (> (match-end 0) (match-beginning 0)) | 2325 | (let ((same (if (> (match-end 0) (match-beginning 0)) |
| 1782 | (current-column)))) | 2326 | (current-column)))) |
| 1783 | (beginning-of-line 2) | 2327 | (beginning-of-line 2) |
| @@ -1831,9 +2375,8 @@ Used by `antlr-insert-option-do'." | |||
| 1831 | "Read a string from the minibuffer, possibly with completion. | 2375 | "Read a string from the minibuffer, possibly with completion. |
| 1832 | If INITIAL-CONTENTS is non-nil, insert it in the minibuffer initially. | 2376 | If INITIAL-CONTENTS is non-nil, insert it in the minibuffer initially. |
| 1833 | PROMPT is a string to prompt with, normally it ends in a colon and a | 2377 | PROMPT is a string to prompt with, normally it ends in a colon and a |
| 1834 | space. If AS-STRING is t or is a member \(comparison done with `eq') of | 2378 | space. If AS-STRING is non-nil, return printed representation of the user |
| 1835 | `antlr-options-style', return printed representation of the user input, | 2379 | input, otherwise return the user input directly. |
| 1836 | otherwise return the user input directly. | ||
| 1837 | 2380 | ||
| 1838 | If TABLE or TABLE-X is non-nil, read with completion. The completion | 2381 | If TABLE or TABLE-X is non-nil, read with completion. The completion |
| 1839 | table is the resulting alist of TABLE-X concatenated with TABLE where | 2382 | table is the resulting alist of TABLE-X concatenated with TABLE where |
| @@ -1847,10 +2390,10 @@ Used inside `antlr-options-alists'." | |||
| 1847 | (input (if table0 | 2390 | (input (if table0 |
| 1848 | (completing-read prompt table0 nil nil initial-contents) | 2391 | (completing-read prompt table0 nil nil initial-contents) |
| 1849 | (read-from-minibuffer prompt initial-contents)))) | 2392 | (read-from-minibuffer prompt initial-contents)))) |
| 1850 | (if (and as-string | 2393 | (if as-string |
| 1851 | (or (eq as-string t) | 2394 | ;; if necessary, `use print-escape-newlines', `print-escape-nonascii' |
| 1852 | (cdr (assq as-string antlr-options-style)))) | 2395 | ;; if strings should be used in v3/v4, write our own (single quote) |
| 1853 | (format "%S" input) | 2396 | (format "%S" input) |
| 1854 | input))) | 2397 | input))) |
| 1855 | 2398 | ||
| 1856 | (defun antlr-read-boolean (initial-contents prompt &optional table) | 2399 | (defun antlr-read-boolean (initial-contents prompt &optional table) |
| @@ -1859,52 +2402,67 @@ If INITIAL-CONTENTS is non-nil, insert it in the minibuffer initially. | |||
| 1859 | PROMPT is a string to prompt with, normally it ends in a question mark | 2402 | PROMPT is a string to prompt with, normally it ends in a question mark |
| 1860 | and a space. \"(true or false) \" is appended if TABLE is nil. | 2403 | and a space. \"(true or false) \" is appended if TABLE is nil. |
| 1861 | 2404 | ||
| 1862 | Read with completion over \"true\", \"false\" and the keys in TABLE, see | 2405 | Without TABLE, use `y-or-n-p', otherwise read with completion |
| 1863 | also `antlr-read-value'. | 2406 | over \"true\", \"false\" and the keys in TABLE, see also |
| 2407 | `antlr-read-value'. | ||
| 1864 | 2408 | ||
| 1865 | Used inside `antlr-options-alists'." | 2409 | Used inside `antlr-options-alists'." |
| 1866 | (antlr-read-value initial-contents | 2410 | (if table |
| 1867 | (if table prompt (concat prompt "(true or false) ")) | 2411 | (antlr-read-value initial-contents prompt |
| 1868 | nil | 2412 | nil table '(("false") ("true"))) |
| 1869 | table '(("false") ("true")))) | 2413 | (if (y-or-n-p prompt) "true" "false"))) |
| 2414 | |||
| 2415 | (defun antlr-read-language (initial-contents prompt) | ||
| 2416 | "Read an action language from the minibuffer, with completion. | ||
| 2417 | If INITIAL-CONTENTS is non-nil, insert it in the minibuffer initially. | ||
| 2418 | PROMPT is a string to prompt with, normally it ends in a colon and a | ||
| 2419 | space. | ||
| 2420 | |||
| 2421 | Used inside `antlr-options-alists'." | ||
| 2422 | (let ((table (apply 'nconc | ||
| 2423 | (mapcar (lambda (l) (mapcar #'list (cdr l))) | ||
| 2424 | antlr-language-list)))) | ||
| 2425 | (antlr-read-value initial-contents prompt nil table))) | ||
| 1870 | 2426 | ||
| 1871 | (defun antlr-language-option-extra (phase &rest _dummies) | 2427 | (defun antlr-language-option-extra (phase &rest _dummies) |
| 1872 | ;; checkdoc-params: (dummies) | ||
| 1873 | "Change language according to the new value of the \"language\" option. | 2428 | "Change language according to the new value of the \"language\" option. |
| 1874 | Call `antlr-mode' if the new language would be different from the value | 2429 | Call `antlr-mode' if the new language would be different from the value |
| 1875 | of `antlr-language', keeping the value of variable `font-lock-mode'. | 2430 | of `antlr-language', keeping the value of variable `font-lock-mode'. |
| 1876 | 2431 | ||
| 1877 | Called in PHASE `after-insertion', see `antlr-options-alists'." | 2432 | Called in PHASE `after-insertion', see `antlr-options-alists'." |
| 1878 | (when (eq phase 'after-insertion) | 2433 | (when (eq phase 'after-insertion) |
| 1879 | (let ((new-language (antlr-language-option t))) | 2434 | (let ((new-language (antlr-guess-language))) |
| 1880 | (or (null new-language) | 2435 | (or (null new-language) |
| 1881 | (eq new-language antlr-language) | 2436 | (eq new-language antlr-language) |
| 1882 | (let ((font-lock font-lock-mode)) | 2437 | (let ((font-lock (and (boundp 'font-lock-mode) font-lock-mode))) |
| 1883 | (if font-lock (font-lock-mode 0)) | 2438 | (if font-lock (font-lock-mode 0)) |
| 1884 | (antlr-mode) | 2439 | (funcall major-mode) ; TODO: do differently? |
| 1885 | (and font-lock (null font-lock-mode) (font-lock-mode 1))))))) | 2440 | (and font-lock (null font-lock-mode) (font-lock-mode 1))))))) |
| 1886 | 2441 | ||
| 1887 | (defun antlr-c++-mode-extra (phase option &rest _dummies) | 2442 | (defun antlr-c++-mode-extra (phase option &rest _dummies) |
| 1888 | ;; checkdoc-params: (option dummies) | 2443 | ;; checkdoc-order: nil |
| 1889 | "Warn if C++ option is used with the wrong language. | 2444 | "Warn if C++ option OPTION is used with the wrong language. |
| 1890 | Ask user \(\"y or n\"), if a C++ only option is going to be inserted but | 2445 | Ask user \(\"y or n\"), if a C++ only option is going to be inserted but |
| 1891 | `antlr-language' has not the value `c++-mode'. | 2446 | `antlr-language' has not the value `antlr-cpp'. |
| 1892 | 2447 | ||
| 1893 | Called in PHASE `before-input', see `antlr-options-alists'." | 2448 | Called in PHASE `before-input', see `antlr-options-alists'." |
| 1894 | (and (eq phase 'before-input) | 2449 | (and (eq phase 'before-input) |
| 1895 | (not (eq antlr-language 'c++-mode)) | 2450 | (not (eq antlr-language 'antlr-cpp)) |
| 1896 | (not (y-or-n-p (format "Insert C++ %s option? " option))) | 2451 | (not (y-or-n-p (format "Insert C++ %s option? " option))) |
| 1897 | (error "Didn't insert C++ %s option with language %s" | 2452 | (error "Didn't insert Cpp %s option with language %s" |
| 1898 | option (cadr (assq antlr-language antlr-language-alist))))) | 2453 | option antlr-language-mode-name))) |
| 1899 | 2454 | ||
| 1900 | 2455 | ||
| 1901 | ;;;=========================================================================== | 2456 | ;;;=========================================================================== |
| 1902 | ;;; Compute dependencies | 2457 | ;;; Compute dependencies |
| 1903 | ;;;=========================================================================== | 2458 | ;;;=========================================================================== |
| 2459 | ;; This whole section is ANTLR-v2 specific. It is not used in v3 and v4. | ||
| 1904 | 2460 | ||
| 1905 | (defun antlr-file-dependencies () | 2461 | (defun antlr-file-dependencies () |
| 1906 | "Return dependencies for grammar in current buffer. | 2462 | "Return dependencies for grammar in current buffer. |
| 1907 | The result looks like \(FILE \(CLASSES . SUPERS) VOCABS . LANGUAGE) | 2463 | This function is for ANTLR v2 grammars only. |
| 2464 | |||
| 2465 | The result looks like \(FILE \(CLASSES . SUPERS) VOCABS . LANGUAGE) | ||
| 1908 | where CLASSES = ((CLASS . CLASS-EVOCAB) ...), | 2466 | where CLASSES = ((CLASS . CLASS-EVOCAB) ...), |
| 1909 | SUPERS = ((SUPER . USE-EVOCAB-P) ...), and | 2467 | SUPERS = ((SUPER . USE-EVOCAB-P) ...), and |
| 1910 | VOCABS = ((EVOCAB ...) . (IVOCAB ...)) | 2468 | VOCABS = ((EVOCAB ...) . (IVOCAB ...)) |
| @@ -1919,55 +2477,56 @@ its export vocabulary is used as an import vocabulary." | |||
| 1919 | (unless buffer-file-name | 2477 | (unless buffer-file-name |
| 1920 | (error "Grammar buffer does not visit a file")) | 2478 | (error "Grammar buffer does not visit a file")) |
| 1921 | (let (classes export-vocabs import-vocabs superclasses default-vocab) | 2479 | (let (classes export-vocabs import-vocabs superclasses default-vocab) |
| 1922 | (with-syntax-table antlr-action-syntax-table | 2480 | (goto-char (point-min)) |
| 1923 | (goto-char (point-min)) | 2481 | (while (antlr-re-search-forward antlr-grammar-header-regexp nil) |
| 1924 | (while (antlr-re-search-forward antlr-class-header-regexp nil) | 2482 | ;; parse class definition -------------------------------------------- |
| 1925 | ;; parse class definition -------------------------------------------- | 2483 | (let* ((class (match-string-no-properties 2)) |
| 1926 | (let* ((class (match-string 2)) | 2484 | (sclass (match-string-no-properties 4)) |
| 1927 | (sclass (match-string 4)) | 2485 | ;; export vocab defaults to class name (first grammar in file) |
| 1928 | ;; export vocab defaults to class name (first grammar in file) | 2486 | ;; or to the export vocab of the first grammar in file: |
| 1929 | ;; or to the export vocab of the first grammar in file: | 2487 | (evocab (or default-vocab class)) |
| 1930 | (evocab (or default-vocab class)) | 2488 | (ivocab nil)) |
| 1931 | (ivocab nil)) | 2489 | (goto-char (match-end 0)) |
| 1932 | (goto-char (match-end 0)) | 2490 | (antlr-c-forward-sws) |
| 1933 | (antlr-c-forward-sws) | 2491 | (while (looking-at "options\\_>\\|\\(tokens\\)\\_>") |
| 1934 | (while (looking-at "options\\>\\|\\(tokens\\)\\>") | 2492 | (if (match-beginning 1) |
| 1935 | (if (match-beginning 1) | 2493 | (antlr-skip-sexps 2) |
| 1936 | (antlr-skip-sexps 2) | 2494 | (goto-char (match-end 0)) |
| 1937 | (goto-char (match-end 0)) | 2495 | (antlr-c-forward-sws) |
| 1938 | (antlr-c-forward-sws) | 2496 | ;; parse grammar option sections ------------------------------- |
| 1939 | ;; parse grammar option sections ------------------------------- | 2497 | (when (eq (char-after (point)) ?\{) |
| 1940 | (when (eq (char-after (point)) ?\{) | 2498 | (let* ((beg (1+ (point))) |
| 1941 | (let* ((beg (1+ (point))) | 2499 | (end (1- (antlr-skip-sexps 1))) |
| 1942 | (end (1- (antlr-skip-sexps 1))) | 2500 | (cont (point))) |
| 1943 | (cont (point))) | ||
| 1944 | (goto-char beg) | 2501 | (goto-char beg) |
| 1945 | (if (re-search-forward "\\<exportVocab[ \t]*=[ \t]*\\([A-Za-z\300-\326\330-\337]\\sw*\\)" end t) | 2502 | (if (re-search-forward "\\<exportVocab[ \t]*=[ \t]*\\([A-Za-z\300-\326\330-\337]\\(?:\\sw\\|\\s_\\)*\\)" end t) |
| 1946 | (setq evocab (match-string 1))) | 2503 | (setq evocab (match-string-no-properties 1))) |
| 1947 | (goto-char beg) | 2504 | (goto-char beg) |
| 1948 | (if (re-search-forward "\\<importVocab[ \t]*=[ \t]*\\([A-Za-z\300-\326\330-\337]\\sw*\\)" end t) | 2505 | (if (re-search-forward "\\<importVocab[ \t]*=[ \t]*\\([A-Za-z\300-\326\330-\337]\\(?:\\sw\\|\\s_\\)*\\)" end t) |
| 1949 | (setq ivocab (match-string 1))) | 2506 | (setq ivocab (match-string-no-properties 1))) |
| 1950 | (goto-char cont))))) | 2507 | (goto-char cont))))) |
| 1951 | (unless (member sclass '("Parser" "Lexer" "TreeParser")) | 2508 | (unless (member sclass '("Parser" "Lexer" "TreeParser")) |
| 1952 | (let ((super (assoc sclass superclasses))) | 2509 | (let ((super (assoc sclass superclasses))) |
| 1953 | (if super | 2510 | (if super |
| 1954 | (or ivocab (setcdr super t)) | 2511 | (or ivocab (setcdr super t)) |
| 1955 | (push (cons sclass (null ivocab)) superclasses)))) | 2512 | (push (cons sclass (null ivocab)) superclasses)))) |
| 1956 | ;; remember class with export vocabulary: | 2513 | ;; remember class with export vocabulary: |
| 1957 | (push (cons class evocab) classes) | 2514 | (push (cons class evocab) classes) |
| 1958 | ;; default export vocab is export vocab of first grammar in file: | 2515 | ;; default export vocab is export vocab of first grammar in file: |
| 1959 | (or default-vocab (setq default-vocab evocab)) | 2516 | (or default-vocab (setq default-vocab evocab)) |
| 1960 | (or (member evocab export-vocabs) (push evocab export-vocabs)) | 2517 | (or (member evocab export-vocabs) (push evocab export-vocabs)) |
| 1961 | (or (null ivocab) | 2518 | (or (null ivocab) |
| 1962 | (member ivocab import-vocabs) (push ivocab import-vocabs))))) | 2519 | (member ivocab import-vocabs) (push ivocab import-vocabs)))) |
| 1963 | (if classes | 2520 | (if classes |
| 1964 | (cl-list* (file-name-nondirectory buffer-file-name) | 2521 | (cl-list* (file-name-nondirectory buffer-file-name) |
| 1965 | (cons (nreverse classes) (nreverse superclasses)) | 2522 | (cons (nreverse classes) (nreverse superclasses)) |
| 1966 | (cons (nreverse export-vocabs) (nreverse import-vocabs)) | 2523 | (cons (nreverse export-vocabs) (nreverse import-vocabs)) |
| 1967 | antlr-language)))) | 2524 | antlr-action-mode)))) |
| 1968 | 2525 | ||
| 1969 | (defun antlr-directory-dependencies (dirname) | 2526 | (defun antlr-directory-dependencies (dirname) |
| 1970 | "Return dependencies for all grammar files in directory DIRNAME. | 2527 | "Return dependencies for all grammar files in directory DIRNAME. |
| 2528 | This function is for ANTLR v2 grammars only. | ||
| 2529 | |||
| 1971 | The result looks like \((CLASS-SPEC ...) . \(FILE-DEP ...)) | 2530 | The result looks like \((CLASS-SPEC ...) . \(FILE-DEP ...)) |
| 1972 | where CLASS-SPEC = (CLASS (FILE . EVOCAB) ...). | 2531 | where CLASS-SPEC = (CLASS (FILE . EVOCAB) ...). |
| 1973 | 2532 | ||
| @@ -1991,11 +2550,12 @@ export vocabulary specified in that file." | |||
| 1991 | (insert-file-contents file t nil nil t) | 2550 | (insert-file-contents file t nil nil t) |
| 1992 | (normal-mode t) ; necessary for major-mode, syntax | 2551 | (normal-mode t) ; necessary for major-mode, syntax |
| 1993 | ; table and `antlr-language' | 2552 | ; table and `antlr-language' |
| 1994 | (when (derived-mode-p 'antlr-mode) | 2553 | (when (and (derived-mode-p 'antlr-mode) |
| 2554 | (eq antlr-tool-version 'antlr-v2)) | ||
| 1995 | (let* ((file-deps (antlr-file-dependencies)) | 2555 | (let* ((file-deps (antlr-file-dependencies)) |
| 1996 | (file (car file-deps))) | 2556 | (file (car file-deps))) |
| 1997 | (when file-deps | 2557 | (when file-deps |
| 1998 | (dolist (class-def (caadr file-deps)) | 2558 | (dolist (class-def (cl-caadr file-deps)) |
| 1999 | (let ((file-evocab (cons file (cdr class-def))) | 2559 | (let ((file-evocab (cons file (cdr class-def))) |
| 2000 | (class-spec (assoc (car class-def) classes))) | 2560 | (class-spec (assoc (car class-def) classes))) |
| 2001 | (if class-spec | 2561 | (if class-spec |
| @@ -2005,13 +2565,10 @@ export vocabulary specified in that file." | |||
| 2005 | (push file-deps dependencies))))))) | 2565 | (push file-deps dependencies))))))) |
| 2006 | (cons (nreverse classes) (nreverse dependencies)))))) | 2566 | (cons (nreverse classes) (nreverse dependencies)))))) |
| 2007 | 2567 | ||
| 2008 | |||
| 2009 | ;;;=========================================================================== | ||
| 2010 | ;;; Compilation: run ANTLR tool | ||
| 2011 | ;;;=========================================================================== | ||
| 2012 | |||
| 2013 | (defun antlr-superclasses-glibs (supers classes) | 2568 | (defun antlr-superclasses-glibs (supers classes) |
| 2014 | "Compute the grammar lib option for the super grammars SUPERS. | 2569 | "Compute the grammar lib option for the super grammars SUPERS. |
| 2570 | This function is for ANTLR v2 grammars only. | ||
| 2571 | |||
| 2015 | Look in CLASSES for the right grammar lib files for SUPERS. SUPERS is | 2572 | Look in CLASSES for the right grammar lib files for SUPERS. SUPERS is |
| 2016 | part SUPER in the result of `antlr-file-dependencies'. CLASSES is the | 2573 | part SUPER in the result of `antlr-file-dependencies'. CLASSES is the |
| 2017 | part \(CLASS-SPEC ...) in the result of `antlr-directory-dependencies'. | 2574 | part \(CLASS-SPEC ...) in the result of `antlr-directory-dependencies'. |
| @@ -2043,45 +2600,86 @@ vocabulary of the super-grammar or nil if it is not needed." | |||
| 2043 | (cons (if glibs (concat " -glib " (mapconcat 'car glibs ";")) "") | 2600 | (cons (if glibs (concat " -glib " (mapconcat 'car glibs ";")) "") |
| 2044 | (cons unknown glibs)))) | 2601 | (cons unknown glibs)))) |
| 2045 | 2602 | ||
| 2603 | |||
| 2604 | ;;;=========================================================================== | ||
| 2605 | ;;; Compilation: run ANTLR tool | ||
| 2606 | ;;;=========================================================================== | ||
| 2607 | |||
| 2608 | (defvar antlr-grammar-file nil | ||
| 2609 | "Grammar file processed in *compilation* buffer. | ||
| 2610 | Set by command `antlr-run-tool’.") | ||
| 2611 | |||
| 2612 | (defun antlr-grammar-file () | ||
| 2613 | "Return the current grammar file. | ||
| 2614 | This function could be useful in `antlr-compilation-error-regexp-alist' | ||
| 2615 | for certain tools." | ||
| 2616 | antlr-grammar-file) | ||
| 2617 | |||
| 2046 | (defun antlr-run-tool (command file &optional saved) | 2618 | (defun antlr-run-tool (command file &optional saved) |
| 2047 | "Run Antlr took COMMAND on grammar FILE. | 2619 | "Run Antlr took COMMAND on grammar FILE. |
| 2048 | When called interactively, COMMAND is read from the minibuffer and | 2620 | When called interactively, COMMAND is read from the minibuffer and |
| 2049 | defaults to `antlr-tool-command' with a computed \"-glib\" option if | 2621 | defaults to `antlr-tool-command', with a computed \"-glib\" option for |
| 2050 | necessary. | 2622 | ANTLR v2 grammars if necessary. |
| 2623 | See also variable `antlr-run-tool-on-buffer-file'. | ||
| 2051 | 2624 | ||
| 2052 | Save all buffers first unless optional value SAVED is non-nil. When | 2625 | Save all buffers first unless optional value SAVED is non-nil. When |
| 2053 | called interactively, the buffers are always saved, see also variable | 2626 | called interactively, the buffers are always saved, see also variable |
| 2054 | `antlr-ask-about-save'." | 2627 | `antlr-ask-about-save'." |
| 2055 | (interactive (antlr-run-tool-interactive)) | 2628 | (interactive (antlr-run-tool-interactive)) |
| 2056 | (or saved (save-some-buffers (not antlr-ask-about-save))) | 2629 | (or saved (save-some-buffers (not antlr-ask-about-save))) |
| 2057 | (let ((default-directory (file-name-directory file))) | 2630 | (let ((default-directory (file-name-directory file)) |
| 2058 | (compilation-start (concat command " " (file-name-nondirectory file)) | 2631 | (error-regexp-alist antlr-compilation-error-regexp-alist) |
| 2059 | nil (lambda (_mode-name) "*Antlr-Run*")))) | 2632 | (process-environment |
| 2633 | (if antlr-tool-path | ||
| 2634 | (let ((path (mapconcat 'substitute-env-vars | ||
| 2635 | antlr-tool-path path-separator))) | ||
| 2636 | (cons (concat "PATH=" path path-separator | ||
| 2637 | (getenv "PATH")) | ||
| 2638 | (cons (concat "LD_LIBRARY_PATH=" path path-separator | ||
| 2639 | (getenv "LD_LIBRARY_PATH")) | ||
| 2640 | process-environment))) | ||
| 2641 | process-environment))) ;#dynamic | ||
| 2642 | ;; the MODE argument of `compilation-start' is quite a hack... | ||
| 2643 | (with-current-buffer | ||
| 2644 | (compilation-start command antlr-compilation-mode | ||
| 2645 | (lambda (_mode-name) "*Antlr-Run*")) | ||
| 2646 | (when error-regexp-alist | ||
| 2647 | (setq-local compilation-error-regexp-alist error-regexp-alist)) | ||
| 2648 | (setq-local antlr-grammar-file file)))) | ||
| 2060 | 2649 | ||
| 2061 | (defun antlr-run-tool-interactive () | 2650 | (defun antlr-run-tool-interactive () |
| 2062 | ;; code in `interactive' is not compiled | 2651 | ;; code in `interactive' is not compiled |
| 2063 | "Interactive specification for `antlr-run-tool'. | 2652 | "Interactive specification for `antlr-run-tool'. |
| 2064 | Use prefix argument ARG to return \(COMMAND FILE SAVED)." | 2653 | Use prefix argument ARG to return \(COMMAND FILE SAVED)." |
| 2065 | (let* ((supers (cdadr (save-excursion | 2654 | (let* ((supers (and (eq antlr-tool-version 'antlr-v2) |
| 2066 | (save-restriction | 2655 | (cl-cdadr (save-excursion |
| 2067 | (widen) | 2656 | (save-restriction |
| 2068 | (antlr-file-dependencies))))) | 2657 | (widen) |
| 2069 | (glibs "")) | 2658 | (antlr-file-dependencies)))))) |
| 2070 | (when supers | 2659 | (prompt (if (functionp antlr-tool-command) |
| 2071 | (save-some-buffers (not antlr-ask-about-save) nil) | 2660 | (funcall antlr-tool-command buffer-file-name supers) |
| 2072 | (setq glibs (car (antlr-superclasses-glibs | 2661 | (if (null supers) |
| 2073 | supers | 2662 | antlr-tool-command |
| 2074 | (car (antlr-directory-dependencies | 2663 | (save-some-buffers (not antlr-ask-about-save) nil) |
| 2075 | default-directory)))))) | 2664 | (concat antlr-tool-command |
| 2076 | (list (read-shell-command "Run Antlr on current file with: " | 2665 | (car (antlr-superclasses-glibs |
| 2077 | (concat antlr-tool-command glibs " ")) | 2666 | supers |
| 2078 | buffer-file-name | 2667 | (car (antlr-directory-dependencies |
| 2079 | supers))) | 2668 | default-directory))))))))) |
| 2669 | (list (if antlr-run-tool-on-buffer-file | ||
| 2670 | (concat (read-shell-command "Run Antlr with: " prompt) | ||
| 2671 | " " (file-name-nondirectory buffer-file-name)) | ||
| 2672 | (read-shell-command "Run Antlr with: " | ||
| 2673 | (concat prompt " " | ||
| 2674 | (file-name-nondirectory buffer-file-name)))) | ||
| 2675 | buffer-file-name | ||
| 2676 | supers))) | ||
| 2080 | 2677 | ||
| 2081 | 2678 | ||
| 2082 | ;;;=========================================================================== | 2679 | ;;;=========================================================================== |
| 2083 | ;;; Makefile creation | 2680 | ;;; Makefile creation |
| 2084 | ;;;=========================================================================== | 2681 | ;;;=========================================================================== |
| 2682 | ;; This whole section is ANTLR-v2 specific. | ||
| 2085 | 2683 | ||
| 2086 | (defun antlr-makefile-insert-variable (number pre post) | 2684 | (defun antlr-makefile-insert-variable (number pre post) |
| 2087 | "Insert Makefile variable numbered NUMBER according to specification. | 2685 | "Insert Makefile variable numbered NUMBER according to specification. |
| @@ -2094,6 +2692,8 @@ Also insert strings PRE and POST before and after the variable." | |||
| 2094 | 2692 | ||
| 2095 | (defun antlr-insert-makefile-rules (&optional in-makefile) | 2693 | (defun antlr-insert-makefile-rules (&optional in-makefile) |
| 2096 | "Insert Makefile rules in the current buffer at point. | 2694 | "Insert Makefile rules in the current buffer at point. |
| 2695 | This function is for ANTLR v2 grammars only. | ||
| 2696 | |||
| 2097 | IN-MAKEFILE is non-nil, if the current buffer is the Makefile. See | 2697 | IN-MAKEFILE is non-nil, if the current buffer is the Makefile. See |
| 2098 | command `antlr-show-makefile-rules' for detail." | 2698 | command `antlr-show-makefile-rules' for detail." |
| 2099 | (let* ((dirname default-directory) | 2699 | (let* ((dirname default-directory) |
| @@ -2101,24 +2701,24 @@ command `antlr-show-makefile-rules' for detail." | |||
| 2101 | (classes (car deps0)) ; CLASS -> (FILE . EVOCAB) ... | 2701 | (classes (car deps0)) ; CLASS -> (FILE . EVOCAB) ... |
| 2102 | (deps (cdr deps0)) ; FILE -> (c . s) (ev . iv) . LANGUAGE | 2702 | (deps (cdr deps0)) ; FILE -> (c . s) (ev . iv) . LANGUAGE |
| 2103 | (with-error nil) | 2703 | (with-error nil) |
| 2104 | (gen-sep (or (caddr (cadr antlr-makefile-specification)) " ")) | 2704 | (gen-sep (or (cl-caddr (cadr antlr-makefile-specification)) " ")) |
| 2105 | (n (and (cdr deps) (cadr antlr-makefile-specification) 0))) | 2705 | (n (and (cdr deps) (cadr antlr-makefile-specification) 0))) |
| 2106 | (or in-makefile (set-buffer standard-output)) | 2706 | (or in-makefile (set-buffer standard-output)) |
| 2107 | (dolist (dep deps) | 2707 | (dolist (dep deps) |
| 2108 | (let ((supers (cdadr dep)) | 2708 | (let ((supers (cl-cdadr dep)) |
| 2109 | (lang (cdr (assoc (cdddr dep) antlr-file-formats-alist)))) | 2709 | (lang (cdr (assoc (cl-cdddr dep) antlr-file-formats-alist)))) |
| 2110 | (if n (cl-incf n)) | 2710 | (if n (cl-incf n)) |
| 2111 | (antlr-makefile-insert-variable n "" " =") | 2711 | (antlr-makefile-insert-variable n "" " =") |
| 2112 | (if supers | 2712 | (if supers |
| 2113 | (insert " " | 2713 | (insert " " |
| 2114 | (format (cadr antlr-special-file-formats) | 2714 | (format (cadr antlr-special-file-formats) |
| 2115 | (file-name-sans-extension (car dep))))) | 2715 | (file-name-sans-extension (car dep))))) |
| 2116 | (dolist (class-def (caadr dep)) | 2716 | (dolist (class-def (cl-caadr dep)) |
| 2117 | (let ((sep gen-sep)) | 2717 | (let ((sep gen-sep)) |
| 2118 | (dolist (class-file (cadr lang)) | 2718 | (dolist (class-file (cadr lang)) |
| 2119 | (insert sep (format class-file (car class-def))) | 2719 | (insert sep (format class-file (car class-def))) |
| 2120 | (setq sep " ")))) | 2720 | (setq sep " ")))) |
| 2121 | (dolist (evocab (caaddr dep)) | 2721 | (dolist (evocab (cl-caaddr dep)) |
| 2122 | (let ((sep gen-sep)) | 2722 | (let ((sep gen-sep)) |
| 2123 | (dolist (vocab-file (cons (car antlr-special-file-formats) | 2723 | (dolist (vocab-file (cons (car antlr-special-file-formats) |
| 2124 | (car lang))) | 2724 | (car lang))) |
| @@ -2126,7 +2726,7 @@ command `antlr-show-makefile-rules' for detail." | |||
| 2126 | (setq sep " ")))) | 2726 | (setq sep " ")))) |
| 2127 | (antlr-makefile-insert-variable n "\n$(" ")") | 2727 | (antlr-makefile-insert-variable n "\n$(" ")") |
| 2128 | (insert ": " (car dep)) | 2728 | (insert ": " (car dep)) |
| 2129 | (dolist (ivocab (cdaddr dep)) | 2729 | (dolist (ivocab (cl-cdaddr dep)) |
| 2130 | (insert " " (format (car antlr-special-file-formats) ivocab))) | 2730 | (insert " " (format (car antlr-special-file-formats) ivocab))) |
| 2131 | (let ((glibs (antlr-superclasses-glibs supers classes))) | 2731 | (let ((glibs (antlr-superclasses-glibs supers classes))) |
| 2132 | (if (cadr glibs) (setq with-error t)) | 2732 | (if (cadr glibs) (setq with-error t)) |
| @@ -2136,7 +2736,7 @@ command `antlr-show-makefile-rules' for detail." | |||
| 2136 | (insert " " (format (car antlr-special-file-formats) | 2736 | (insert " " (format (car antlr-special-file-formats) |
| 2137 | (cdr super))))) | 2737 | (cdr super))))) |
| 2138 | (insert "\n\t" | 2738 | (insert "\n\t" |
| 2139 | (caddr antlr-makefile-specification) | 2739 | (cl-caddr antlr-makefile-specification) |
| 2140 | (car glibs) | 2740 | (car glibs) |
| 2141 | " $<\n" | 2741 | " $<\n" |
| 2142 | (car antlr-makefile-specification))))) | 2742 | (car antlr-makefile-specification))))) |
| @@ -2146,8 +2746,10 @@ command `antlr-show-makefile-rules' for detail." | |||
| 2146 | (while (<= (cl-incf i) n) | 2746 | (while (<= (cl-incf i) n) |
| 2147 | (antlr-makefile-insert-variable i " $(" ")")) | 2747 | (antlr-makefile-insert-variable i " $(" ")")) |
| 2148 | (insert "\n" (car antlr-makefile-specification)))) | 2748 | (insert "\n" (car antlr-makefile-specification)))) |
| 2149 | (if (string-equal (car antlr-makefile-specification) "\n") | 2749 | (if (bobp) |
| 2150 | (delete-char -1)) | 2750 | (setq with-error t) |
| 2751 | (if (string-equal (car antlr-makefile-specification) "\n") | ||
| 2752 | (delete-char -1))) | ||
| 2151 | (when with-error | 2753 | (when with-error |
| 2152 | (goto-char (point-min)) | 2754 | (goto-char (point-min)) |
| 2153 | (insert antlr-help-unknown-file-text)) | 2755 | (insert antlr-help-unknown-file-text)) |
| @@ -2160,6 +2762,8 @@ command `antlr-show-makefile-rules' for detail." | |||
| 2160 | ;;;###autoload | 2762 | ;;;###autoload |
| 2161 | (defun antlr-show-makefile-rules () | 2763 | (defun antlr-show-makefile-rules () |
| 2162 | "Show Makefile rules for all grammar files in the current directory. | 2764 | "Show Makefile rules for all grammar files in the current directory. |
| 2765 | This command is for ANTLR v2 grammars only. | ||
| 2766 | |||
| 2163 | If the `major-mode' of the current buffer has the value `makefile-mode', | 2767 | If the `major-mode' of the current buffer has the value `makefile-mode', |
| 2164 | the rules are directory inserted at point. Otherwise, a *Help* buffer | 2768 | the rules are directory inserted at point. Otherwise, a *Help* buffer |
| 2165 | is shown with the rules which are also put into the `kill-ring' for | 2769 | is shown with the rules which are also put into the `kill-ring' for |
| @@ -2175,10 +2779,12 @@ are used according to variable `antlr-unknown-file-formats' and a | |||
| 2175 | commentary with value `antlr-help-unknown-file-text' is added. The | 2779 | commentary with value `antlr-help-unknown-file-text' is added. The |
| 2176 | *Help* buffer always starts with the text in `antlr-help-rules-intro'." | 2780 | *Help* buffer always starts with the text in `antlr-help-rules-intro'." |
| 2177 | (interactive) | 2781 | (interactive) |
| 2782 | (unless (eq antlr-tool-version 'antlr-v2) | ||
| 2783 | (user-error (substitute-command-keys | ||
| 2784 | "Run \\[antlr-run-tool] with option \"-depend\" instead"))) | ||
| 2178 | (if (null (derived-mode-p 'makefile-mode)) | 2785 | (if (null (derived-mode-p 'makefile-mode)) |
| 2179 | (with-output-to-temp-buffer "*Help*" | 2786 | (with-output-to-temp-buffer (help-buffer) |
| 2180 | (save-excursion | 2787 | (save-excursion (antlr-insert-makefile-rules))) |
| 2181 | (antlr-insert-makefile-rules))) | ||
| 2182 | (push-mark) | 2788 | (push-mark) |
| 2183 | (antlr-insert-makefile-rules t))) | 2789 | (antlr-insert-makefile-rules t))) |
| 2184 | 2790 | ||
| @@ -2189,18 +2795,18 @@ commentary with value `antlr-help-unknown-file-text' is added. The | |||
| 2189 | 2795 | ||
| 2190 | (defun antlr-indent-line () | 2796 | (defun antlr-indent-line () |
| 2191 | "Indent the current line as ANTLR grammar code. | 2797 | "Indent the current line as ANTLR grammar code. |
| 2192 | The indentation of grammar lines are calculated by `c-basic-offset', | 2798 | The default indentation of grammar lines are calculated by |
| 2193 | multiplied by: | 2799 | `c-basic-offset', multiplied by: |
| 2194 | - the level of the paren/brace/bracket depth, | 2800 | - the level of the paren/brace/bracket depth, |
| 2195 | - plus 0/2/1, depending on the position inside the rule: header, body, | 2801 | - plus 0/2/1, depending on the position inside the rule: header, body, |
| 2196 | exception part, | 2802 | exception part, customized by `antlr-base-offset-alist', |
| 2197 | - minus 1 if `antlr-indent-item-regexp' matches the beginning of the | 2803 | - minus 1 if `antlr-indent-item-regexp' matches the beginning of the |
| 2198 | line starting from the first non-whitespace. | 2804 | line starting from the first non-whitespace. |
| 2199 | 2805 | ||
| 2200 | Lines inside block comments are indented by `c-indent-line' according to | 2806 | Lines inside block comments are indented by `c-indent-line' according to |
| 2201 | `antlr-indent-comment'. | 2807 | `antlr-indent-comment'. |
| 2202 | 2808 | ||
| 2203 | Lines in actions except top-level actions in a header part or an option | 2809 | Lines in actions except top level actions in a header part or an option |
| 2204 | area are indented by `c-indent-line'. | 2810 | area are indented by `c-indent-line'. |
| 2205 | 2811 | ||
| 2206 | Lines in header actions are indented at column 0 if `antlr-language' | 2812 | Lines in header actions are indented at column 0 if `antlr-language' |
| @@ -2209,10 +2815,11 @@ the first non-whitespace is matched by the corresponding value. | |||
| 2209 | 2815 | ||
| 2210 | For the initialization of `c-basic-offset', see `antlr-indent-style' and, | 2816 | For the initialization of `c-basic-offset', see `antlr-indent-style' and, |
| 2211 | to a lesser extent, `antlr-tab-offset-alist'." | 2817 | to a lesser extent, `antlr-tab-offset-alist'." |
| 2818 | ;; TODO: this function needs to be rewritten | ||
| 2212 | (save-restriction | 2819 | (save-restriction |
| 2213 | (let ((orig (point)) | 2820 | (let ((orig (point)) |
| 2214 | (min0 (point-min)) | 2821 | (min0 (point-min)) |
| 2215 | bol boi indent syntax cc-syntax) | 2822 | bol boi indent syntax cc-syntax boa pdepth) |
| 2216 | (widen) | 2823 | (widen) |
| 2217 | (beginning-of-line) | 2824 | (beginning-of-line) |
| 2218 | (setq bol (point)) | 2825 | (setq bol (point)) |
| @@ -2221,32 +2828,64 @@ to a lesser extent, `antlr-tab-offset-alist'." | |||
| 2221 | (skip-chars-forward " \t") | 2828 | (skip-chars-forward " \t") |
| 2222 | (setq boi (point)) | 2829 | (setq boi (point)) |
| 2223 | ;; check syntax at beginning of indentation ---------------------------- | 2830 | ;; check syntax at beginning of indentation ---------------------------- |
| 2224 | (with-syntax-table antlr-action-syntax-table | 2831 | (let* ((ppss (syntax-ppss)) |
| 2225 | (antlr-invalidate-context-cache) | 2832 | (context (antlr-syntactic-context ppss)) |
| 2226 | (setq syntax (antlr-syntactic-context)) | 2833 | (open (nth 9 ppss))) ; TODO Emacs: syntax-ppss-open-positions |
| 2227 | (cond ((symbolp syntax) | 2834 | (setq syntax (or context 0)) |
| 2228 | (setq indent nil)) ; block-comments, strings, (comments) | 2835 | (setq pdepth (car ppss)) |
| 2229 | ((progn | 2836 | ;; TODO: should boa = first non-?\( in (nth 9 ppss) ? |
| 2230 | (antlr-next-rule -1 t) | 2837 | (when (numberp context) ; boa = beginning of action |
| 2231 | (if (antlr-search-forward ":") (< boi (1- (point))) t)) | 2838 | (setq boa (nth (- (length open) context) open)))) |
| 2232 | (setq indent 0)) ; in rule header | 2839 | (cond ((symbolp syntax) |
| 2233 | ((if (antlr-search-forward ";") (< boi (point)) t) | 2840 | (setq indent nil)) ; block-comments, strings, (comments) -> cc engine |
| 2234 | (setq indent 2)) ; in rule body | 2841 | ((progn |
| 2235 | (t | 2842 | (antlr-next-rule -1 t) ; to start of rule |
| 2236 | (forward-char) | 2843 | (= (point) boi)) |
| 2237 | (antlr-skip-exception-part nil) | 2844 | (setq indent 0)) ; rule start always at 0 |
| 2238 | (setq indent (if (> (point) boi) 1 0))))) ; in exception part? | 2845 | ;; TODO: use antlr-skip-to-colon-or-semi |
| 2846 | |||
| 2847 | ((if (let ((r (antlr-search-forward antlr-rule-body-start-op))) | ||
| 2848 | (while (and r (eq (char-after) ?:)) ; skip double-colon | ||
| 2849 | (forward-char) | ||
| 2850 | (setq r (antlr-search-forward antlr-rule-body-start-op))) | ||
| 2851 | r) | ||
| 2852 | (< boi (1- (point))) | ||
| 2853 | t) | ||
| 2854 | (setq indent | ||
| 2855 | (or (cdr (assq :header antlr-base-offset-alist)) 0))) | ||
| 2856 | ((eq (char-after boi) ?:) | ||
| 2857 | (setq indent | ||
| 2858 | (or (cdr (assq :colon antlr-base-offset-alist)) | ||
| 2859 | (cdr (assq :body antlr-base-offset-alist)) | ||
| 2860 | 2))) | ||
| 2861 | ((if (antlr-search-forward ";" antlr-skip-line-regexp) | ||
| 2862 | (< boi (point)) | ||
| 2863 | t) | ||
| 2864 | (setq indent | ||
| 2865 | (or (cdr (assq :body antlr-base-offset-alist)) 2))) | ||
| 2866 | (t | ||
| 2867 | (forward-char) | ||
| 2868 | (antlr-skip-rule-postlude nil) | ||
| 2869 | (setq indent | ||
| 2870 | (if (> (point) boi) | ||
| 2871 | (or (cdr (assq :exception antlr-base-offset-alist)) 1) | ||
| 2872 | 0)))) ; in exception part? | ||
| 2239 | ;; check whether to use indentation engine of cc-mode ------------------ | 2873 | ;; check whether to use indentation engine of cc-mode ------------------ |
| 2240 | (antlr-invalidate-context-cache) | ||
| 2241 | (goto-char boi) | 2874 | (goto-char boi) |
| 2242 | (when (and indent (> syntax 0)) | 2875 | (when (and indent (> syntax 0)) |
| 2243 | (cond ((> syntax 1) ; block in action => use cc-mode | 2876 | (cond ((> syntax 1) ; block in action => use cc-mode (or nothing) |
| 2244 | (setq indent nil)) | 2877 | (setq indent nil) |
| 2245 | ((and (= indent 0) | 2878 | (when antlr-indent-action-line |
| 2246 | (assq antlr-language antlr-indent-at-bol-alist) | 2879 | (setq syntax 'non-cc))) |
| 2247 | (looking-at (cdr (assq antlr-language | 2880 | ((and (= indent 0) ; TODO: recheck |
| 2881 | (assq antlr-action-mode antlr-indent-at-bol-alist) | ||
| 2882 | (looking-at (cdr (assq antlr-action-mode | ||
| 2248 | antlr-indent-at-bol-alist)))) | 2883 | antlr-indent-at-bol-alist)))) |
| 2249 | (setq syntax 'bol)) | 2884 | (setq syntax 'bol)) |
| 2885 | ((memq (char-after) '(?\} ?\]))) ; close the block -> usual grammar indent | ||
| 2886 | (antlr-indent-action-line | ||
| 2887 | ;; TODO: parameters, and mode-specific - should we handle options{} and tokens{} extra? | ||
| 2888 | (setq indent nil syntax 'non-cc)) | ||
| 2250 | ((setq cc-syntax (c-guess-basic-syntax)) | 2889 | ((setq cc-syntax (c-guess-basic-syntax)) |
| 2251 | (let ((cc cc-syntax) symbol) | 2890 | (let ((cc cc-syntax) symbol) |
| 2252 | (while (setq symbol (pop cc)) | 2891 | (while (setq symbol (pop cc)) |
| @@ -2255,30 +2894,29 @@ to a lesser extent, `antlr-tab-offset-alist'." | |||
| 2255 | antlr-disabling-cc-syntactic-symbols) | 2894 | antlr-disabling-cc-syntactic-symbols) |
| 2256 | (setq indent nil)) | 2895 | (setq indent nil)) |
| 2257 | (setq cc nil))))))) | 2896 | (setq cc nil))))))) |
| 2258 | ;;; ((= indent 1) ; exception part => use cc-mode | 2897 | ;; compute the corresponding indentation and indent -------------------- |
| 2259 | ;;; (setq indent nil)) | ||
| 2260 | ;;; ((save-restriction ; not in option part => cc-mode | ||
| 2261 | ;;; (goto-char (scan-lists (point) -1 1)) | ||
| 2262 | ;;; (skip-chars-backward " \t\n") | ||
| 2263 | ;;; (narrow-to-region (point-min) (point)) | ||
| 2264 | ;;; (not (re-search-backward "\\<options\\'" nil t))) | ||
| 2265 | ;;; (setq indent nil))))) | ||
| 2266 | ;; compute the corresponding indentation and indent -------------------- | ||
| 2267 | (if (null indent) | 2898 | (if (null indent) |
| 2268 | ;; Use the indentation engine of cc-mode | 2899 | ;; Use the indentation engine of cc-mode |
| 2269 | (progn | 2900 | (progn |
| 2270 | (goto-char orig) | 2901 | (goto-char orig) |
| 2271 | (if (or (numberp syntax) | 2902 | (cond ((eq syntax 'non-cc) |
| 2272 | (if (eq syntax 'string) nil (eq antlr-indent-comment t))) | 2903 | ;; TODO: we might check whether the current line is the |
| 2273 | (c-indent-line cc-syntax))) | 2904 | ;; first code in the action -> then we simply indent |
| 2905 | ;; according to indent-level (then we do not have to check | ||
| 2906 | ;; whether the LANGUAGE indents at col 0 (and use C indent) | ||
| 2907 | (funcall antlr-indent-action-line boa)) | ||
| 2908 | ((or (numberp syntax) | ||
| 2909 | (if (eq syntax 'string) nil (eq antlr-indent-comment t))) | ||
| 2910 | (c-indent-line cc-syntax)))) | ||
| 2274 | ;; do it ourselves | 2911 | ;; do it ourselves |
| 2275 | (goto-char boi) | 2912 | (goto-char boi) |
| 2276 | (unless (symbolp syntax) ; direct indentation | 2913 | (unless (symbolp syntax) ; direct indentation |
| 2277 | ;;(antlr-invalidate-context-cache) | 2914 | (cl-incf indent pdepth) |
| 2278 | (cl-incf indent (antlr-syntactic-context)) | 2915 | (and (> indent 0) (looking-at antlr-indent-item-regexp) |
| 2279 | (and (> indent 0) (looking-at antlr-indent-item-regexp) (decf indent)) | 2916 | (cl-decf indent)) |
| 2280 | (setq indent (* indent c-basic-offset))) | 2917 | (setq indent (* indent c-basic-offset))) |
| 2281 | ;; the usual major-mode indent stuff --------------------------------- | 2918 | ;; the usual major-mode indent stuff --------------------------------- |
| 2919 | ;; TODO: use `indent-line-to' instead? | ||
| 2282 | (setq orig (- (point-max) orig)) | 2920 | (setq orig (- (point-max) orig)) |
| 2283 | (unless (= (current-column) indent) | 2921 | (unless (= (current-column) indent) |
| 2284 | (delete-region bol boi) | 2922 | (delete-region bol boi) |
| @@ -2290,12 +2928,13 @@ to a lesser extent, `antlr-tab-offset-alist'." | |||
| 2290 | (goto-char (- (point-max) orig))))))) | 2928 | (goto-char (- (point-max) orig))))))) |
| 2291 | 2929 | ||
| 2292 | (defun antlr-indent-command (&optional arg) | 2930 | (defun antlr-indent-command (&optional arg) |
| 2931 | ;; TODO: drop this command if there is a extra function for `indent-region' | ||
| 2293 | "Indent the current line or insert tabs/spaces. | 2932 | "Indent the current line or insert tabs/spaces. |
| 2294 | With optional prefix argument ARG or if the previous command was this | 2933 | With optional prefix argument ARG, insert ARG tabs or spaces according |
| 2295 | command, insert ARG tabs or spaces according to `indent-tabs-mode'. | 2934 | to `indent-tabs-mode'. |
| 2296 | Otherwise, indent the current line with `antlr-indent-line'." | 2935 | Otherwise, indent the current line with `antlr-indent-line'." |
| 2297 | (interactive "*P") | 2936 | (interactive "*P") |
| 2298 | (if (or arg (eq last-command 'antlr-indent-command)) | 2937 | (if arg |
| 2299 | (insert-tab arg) | 2938 | (insert-tab arg) |
| 2300 | (let ((antlr-indent-comment (and antlr-indent-comment t))) ; dynamic | 2939 | (let ((antlr-indent-comment (and antlr-indent-comment t))) ; dynamic |
| 2301 | (antlr-indent-line)))) | 2940 | (antlr-indent-line)))) |
| @@ -2317,114 +2956,183 @@ ANTLR's syntax and influences the auto indentation, see | |||
| 2317 | (interactive "*P") | 2956 | (interactive "*P") |
| 2318 | (if (or arg | 2957 | (if (or arg |
| 2319 | (save-excursion (skip-chars-backward " \t") (not (bolp))) | 2958 | (save-excursion (skip-chars-backward " \t") (not (bolp))) |
| 2320 | (with-syntax-table antlr-action-syntax-table | 2959 | (let ((context (antlr-syntactic-context))) |
| 2321 | (antlr-invalidate-context-cache) | 2960 | (and context |
| 2322 | (let ((context (antlr-syntactic-context))) | 2961 | (not (and (numberp context) |
| 2323 | (not (and (numberp context) | 2962 | (memq last-command-event '(?\{ ?\}))))))) |
| 2324 | (or (zerop context) | ||
| 2325 | (memq last-command-event '(?\{ ?\})))))))) | ||
| 2326 | (self-insert-command (prefix-numeric-value arg)) | 2963 | (self-insert-command (prefix-numeric-value arg)) |
| 2327 | (self-insert-command (prefix-numeric-value arg)) | 2964 | (self-insert-command (prefix-numeric-value arg)) |
| 2328 | (antlr-indent-line))) | 2965 | (antlr-indent-line))) |
| 2329 | 2966 | ||
| 2967 | (defun antlr-insert-keyword-rule (&optional keyword) | ||
| 2968 | "Insert token rule for an case-insensitive keyword KEYWORD at point." | ||
| 2969 | (interactive "sKeyword: ") | ||
| 2970 | ;; Should be probably made a bit customizable... | ||
| 2971 | (insert (upcase keyword) " : " | ||
| 2972 | (mapconcat (lambda (c) | ||
| 2973 | (let ((d (downcase c)) (u (upcase c))) | ||
| 2974 | (cond ((eq d u) (string ?\' c ?\')) | ||
| 2975 | ((eq antlr-tool-version 'antlr-v4) | ||
| 2976 | (string ?\[ d u ?\])) | ||
| 2977 | (t (string ?\( ?\' d ?\' ?| ?\' u ?\' ?\)))))) | ||
| 2978 | keyword "") | ||
| 2979 | " ;\n")) | ||
| 2980 | |||
| 2330 | 2981 | ||
| 2331 | ;;;=========================================================================== | 2982 | ;;;=========================================================================== |
| 2332 | ;;; Mode entry | 2983 | ;;; Mode entry |
| 2333 | ;;;=========================================================================== | 2984 | ;;;=========================================================================== |
| 2334 | 2985 | ||
| 2335 | (defun antlr-c-init-language-vars () | 2986 | (defun antlr-guess-language () |
| 2336 | "Like `c-init-language-vars-for' when using cc-mode before v5.29." | 2987 | "Find language in `antlr-language-list' for language option. |
| 2337 | (let ((settings ; (cdr '(setq...)) will be optimized | 2988 | If not found, use the default, which is the first element." |
| 2338 | (if (eq antlr-language 'c++-mode) | 2989 | ;; TODO: think about save-restriction & widen |
| 2339 | (cdr '(setq ;' from `c++-mode' v5.20, v5.28 | 2990 | (save-excursion |
| 2340 | c-keywords (c-identifier-re c-C++-keywords) | 2991 | (goto-char (point-min)) |
| 2341 | c-conditional-key c-C++-conditional-key | 2992 | (when (re-search-forward (cdr antlr-language-limit-n-regexp) |
| 2342 | c-comment-start-regexp c-C++-comment-start-regexp | 2993 | (+ (point) |
| 2343 | c-class-key c-C++-class-key | 2994 | (car antlr-language-limit-n-regexp)) |
| 2344 | c-extra-toplevel-key c-C++-extra-toplevel-key | 2995 | t) |
| 2345 | c-access-key c-C++-access-key | 2996 | (car (cl-find (match-string-no-properties 1) antlr-language-list |
| 2346 | c-recognize-knr-p nil | 2997 | :key 'cdr :test 'member))))) |
| 2347 | c-bitfield-key c-C-bitfield-key ; v5.28 | 2998 | |
| 2348 | )) | 2999 | (defun antlr-guess-tool-version () |
| 2349 | (cdr '(setq ; from `java-mode' v5.20, v5.28 | 3000 | "Guess whether current grammar is for ANTLR v2 or v3. |
| 2350 | c-keywords (c-identifier-re c-Java-keywords) | 3001 | By default, we assume v3. Only if we find a keyword 'class' or |
| 2351 | c-conditional-key c-Java-conditional-key | 3002 | 'header' at the beginning of a line before any 'grammar' keyword, |
| 2352 | c-comment-start-regexp c-Java-comment-start-regexp | 3003 | we assume v2." |
| 2353 | c-class-key c-Java-class-key | 3004 | (save-excursion |
| 2354 | c-method-key nil | 3005 | (goto-char (point-min)) |
| 2355 | c-baseclass-key nil | 3006 | (if (and (antlr-re-search-forward "^\\(lexer[ \t]+grammar\\|parser[ \t]+grammar\\|tree[ \t]+grammar\\|grammar\\|\\(class\\|header\\)\\)\\_>" (+ (point) (car antlr-language-limit-n-regexp))) |
| 2356 | c-recognize-knr-p nil | 3007 | (match-beginning 2)) ; class or header |
| 2357 | c-access-key c-Java-access-key ; v5.20 | 3008 | 'antlr-v2 |
| 2358 | c-inexpr-class-key c-Java-inexpr-class-key ; v5.28 | 3009 | 'antlr-v3))) |
| 2359 | ))))) | 3010 | |
| 2360 | (while settings | 3011 | (defun antlr-skip-import-statement () |
| 2361 | (when (boundp (car settings)) | 3012 | "Skip whitespaces, comments and special declarations after the header. |
| 2362 | (ignore-errors | 3013 | See `antlr-skip-line-regexp', which skips the 'scope' declaration in |
| 2363 | (set (car settings) (eval (cadr settings) t)))) | 3014 | ANTLR v3, and the 'import' declaration in ANTLR v4." |
| 2364 | (setq settings (cddr settings))))) | 3015 | (if (not (and antlr-skip-line-regexp (looking-at antlr-skip-line-regexp))) |
| 2365 | 3016 | (antlr-skip-sexps 1) | |
| 2366 | (defun antlr-language-option (search) | 3017 | (goto-char (match-end 0)) |
| 2367 | "Find language in `antlr-language-alist' for language option. | 3018 | (prog1 (point) |
| 2368 | If SEARCH is non-nil, find element for language option. Otherwise, find | 3019 | (antlr-c-forward-sws)))) |
| 2369 | the default language." | 3020 | |
| 2370 | (let ((value | 3021 | (defun antlr-set-local-variables (selector-symbol selector variables) |
| 2371 | (and search | 3022 | ;; checkdoc-order: nil |
| 2372 | (save-excursion | 3023 | "Set SELECTOR dependent local variables for VARIABLES. |
| 2373 | (goto-char (point-min)) | 3024 | Also set SELECTOR-SYMBOL to SELECTOR. |
| 2374 | (re-search-forward (cdr antlr-language-limit-n-regexp) | 3025 | See `antlr-tool-version-variables' and `antlr-language-variables'." |
| 2375 | (+ (point) | 3026 | (unless (symbolp selector) |
| 2376 | (car antlr-language-limit-n-regexp)) | 3027 | (error "Illegal selector %s" selector)) |
| 2377 | t)) | 3028 | (let ((required t) (prefix (symbol-name selector))) |
| 2378 | (match-string 1))) | 3029 | (dolist (var variables) |
| 2379 | (seq antlr-language-alist) | 3030 | (if (eq var '&optional) |
| 2380 | r) | 3031 | (setq required nil) |
| 2381 | ;; Like (find VALUE antlr-language-alist :key 'cddr :test 'member) | 3032 | (let ((name (symbol-name var))) |
| 2382 | (while seq | 3033 | (unless (and (string-match "\\`antlr-" name) (boundp var)) |
| 2383 | (setq r (pop seq)) | 3034 | (error "Illegal element %s" var)) |
| 2384 | (if (member value (cddr r)) | 3035 | (let ((valsym (intern (concat prefix (substring name 5))))) |
| 2385 | (setq seq nil) ; stop | 3036 | (when (or (boundp valsym) required) |
| 2386 | (setq r nil))) ; no result yet | 3037 | (set (make-local-variable var) (symbol-value valsym))))))) |
| 2387 | (car r))) | 3038 | (set (make-local-variable selector-symbol) selector) |
| 3039 | nil)) | ||
| 3040 | |||
| 3041 | ;; I would have guessed that there is a possibility to run code at the end of | ||
| 3042 | ;; initializing a major mode which is definitely run at the end (with or | ||
| 3043 | ;; without local variables enabled). That is not the case... (only hard-coded | ||
| 3044 | ;; for font-lock). Hence, we run some code twice with local variables... | ||
| 3045 | |||
| 3046 | (defun antlr-hack-local-variables-hook () | ||
| 3047 | "Late setup for buffers with a local variables spec. | ||
| 3048 | This function is used in `hack-local-variables-hook'." | ||
| 3049 | (and (derived-mode-p 'antlr-mode) | ||
| 3050 | (or (assq 'antlr-tool-version file-local-variables-alist) | ||
| 3051 | (assq 'antlr-language file-local-variables-alist)) | ||
| 3052 | (antlr-set-tool-version-and-mode-line))) | ||
| 3053 | |||
| 3054 | (add-hook 'hack-local-variables-hook 'antlr-hack-local-variables-hook) | ||
| 3055 | |||
| 3056 | (defun antlr-set-tool-version-and-mode-line () | ||
| 3057 | "Late setup for `antlr-mode' and sub modes." | ||
| 3058 | ;; tool and language version and dependent variables ----------------------- | ||
| 3059 | (let ((guess (if (local-variable-p 'antlr-tool-version) | ||
| 3060 | ;; backward-compatibility: | ||
| 3061 | (if (numberp antlr-tool-version) 'antlr-v2 antlr-tool-version) | ||
| 3062 | (antlr-guess-tool-version)))) | ||
| 3063 | (when (with-demoted-errors "File mode error for `antlr-tool-version': %s" | ||
| 3064 | (antlr-set-local-variables 'antlr-tool-version guess | ||
| 3065 | antlr-tool-version-variables)) | ||
| 3066 | (antlr-set-local-variables 'antlr-tool-version 'antlr-v3 | ||
| 3067 | antlr-tool-version-variables))) | ||
| 3068 | (let ((guess (if (local-variable-p 'antlr-language) | ||
| 3069 | (or (cdr (assq antlr-language ; backward compatibility | ||
| 3070 | '((java-mode . antlr-java) (c++-mode . antlr-cpp)))) | ||
| 3071 | antlr-language) | ||
| 3072 | (antlr-guess-language)))) | ||
| 3073 | (when (with-demoted-errors "File mode error for `antlr-language': %s" | ||
| 3074 | (antlr-set-local-variables 'antlr-language | ||
| 3075 | (or guess (caar antlr-language-list)) | ||
| 3076 | antlr-language-variables)) | ||
| 3077 | (antlr-set-local-variables 'antlr-language 'antlr-java | ||
| 3078 | antlr-language-variables))) | ||
| 3079 | ;; language-dependent initializations -------------------------------------- | ||
| 3080 | (c-init-language-vars-for antlr-init-cc-mode) | ||
| 3081 | (c-basic-common-init antlr-init-cc-mode ; sets `indent-line-function' etc | ||
| 3082 | (or antlr-indent-style "gnu")) | ||
| 3083 | (funcall antlr-init-submode) | ||
| 3084 | (set (make-local-variable 'indent-line-function) #'antlr-indent-line) | ||
| 3085 | (set (make-local-variable 'indent-region-function) nil) ; TODO | ||
| 3086 | ;; syntax-propertize ------------------------------------------------------- | ||
| 3087 | (when antlr-syntax-propertize | ||
| 3088 | (setq-local syntax-propertize-function (car antlr-syntax-propertize)) | ||
| 3089 | (unless (eq (cadr antlr-syntax-propertize) t) | ||
| 3090 | (if (functionp (cadr antlr-syntax-propertize)) | ||
| 3091 | (add-hook 'syntax-propertize-extend-region-functions | ||
| 3092 | (cadr antlr-syntax-propertize) 'append 'local) | ||
| 3093 | (setq-local syntax-propertize-extend-region-functions | ||
| 3094 | (cadr antlr-syntax-propertize)))) | ||
| 3095 | (when (nth 2 antlr-syntax-propertize) | ||
| 3096 | (setq-local c-multiline-string-start-char | ||
| 3097 | (if c-multiline-string-start-char t | ||
| 3098 | (nth 2 antlr-syntax-propertize)))) | ||
| 3099 | (when antlr-do-syntax-propertize ; at least for imenu in Emacs-24.5 | ||
| 3100 | (syntax-propertize (point-max)))) | ||
| 3101 | ;; Before I had moved `imenu-add-to-menubar' from function `antlr-mode', it | ||
| 3102 | ;; had already scanned the buffer before I have set `antlr-tool-version' here | ||
| 3103 | ;; (variables which depend on it). Thus, I move the imenu function to this | ||
| 3104 | ;; function, too... (do we need to explicitly call `imenu-update-menubar' to | ||
| 3105 | ;; be on the safe side?) | ||
| 3106 | (and antlr-imenu-name ; there should be a global variable... | ||
| 3107 | (fboundp 'imenu-add-to-menubar) | ||
| 3108 | (imenu-add-to-menubar | ||
| 3109 | (if (stringp antlr-imenu-name) antlr-imenu-name "Index"))) | ||
| 3110 | (setq mode-name ; TODO: or use ("" ...)? | ||
| 3111 | (concat antlr-tool-mode-name "." antlr-language-mode-name))) | ||
| 3112 | |||
| 3113 | |||
| 3114 | (defvar antlr-delayed-mode-hook '(antlr-set-tool-version-and-mode-line) | ||
| 3115 | "Hook run after entering Antlr mode or a derived mode.") | ||
| 2388 | 3116 | ||
| 2389 | ;;;###autoload | 3117 | ;;;###autoload |
| 2390 | (define-derived-mode antlr-mode prog-mode | 3118 | (define-derived-mode antlr-mode prog-mode |
| 2391 | ;; FIXME: Since it uses cc-mode, it bumps into c-update-modeline's | ||
| 2392 | ;; limitation to mode-name being a string. | ||
| 2393 | ;; '("Antlr." (:eval (cadr (assq antlr-language antlr-language-alist)))) | ||
| 2394 | "Antlr" | 3119 | "Antlr" |
| 2395 | "Major mode for editing ANTLR grammar files." | 3120 | "Major mode for editing ANTLR grammar files." |
| 2396 | :abbrev-table antlr-mode-abbrev-table | 3121 | :abbrev-table antlr-mode-abbrev-table |
| 2397 | (c-initialize-cc-mode) ; cc-mode is required | 3122 | (c-initialize-cc-mode) ; cc-mode is required |
| 2398 | (unless (fboundp 'c-forward-sws) ; see above | 3123 | (set (make-local-variable 'require-final-newline) mode-require-final-newline) |
| 2399 | (fset 'antlr-c-forward-sws 'c-forward-syntactic-ws)) | ||
| 2400 | ;; ANTLR specific ---------------------------------------------------------- | ||
| 2401 | (unless antlr-language | ||
| 2402 | (set (make-local-variable 'antlr-language) | ||
| 2403 | (or (antlr-language-option t) (antlr-language-option nil)))) | ||
| 2404 | (if (stringp (cadr (assq antlr-language antlr-language-alist))) | ||
| 2405 | (setq mode-name | ||
| 2406 | (concat "Antlr." | ||
| 2407 | (cadr (assq antlr-language antlr-language-alist))))) | ||
| 2408 | ;; indentation, for the C engine ------------------------------------------- | ||
| 2409 | (setq c-buffer-is-cc-mode antlr-language) | ||
| 2410 | (c-init-language-vars-for antlr-language) | ||
| 2411 | (c-basic-common-init antlr-language (or antlr-indent-style "gnu")) | ||
| 2412 | (set (make-local-variable 'outline-regexp) "[^#\n\^M]") | 3124 | (set (make-local-variable 'outline-regexp) "[^#\n\^M]") |
| 2413 | (set (make-local-variable 'outline-level) #'c-outline-level) ;TODO: define own | 3125 | (set (make-local-variable 'outline-level) #'c-outline-level) ;TODO: define own |
| 2414 | (set (make-local-variable 'indent-line-function) #'antlr-indent-line) | ||
| 2415 | (set (make-local-variable 'indent-region-function) nil) ; too lazy | ||
| 2416 | (setq comment-start "// " | 3126 | (setq comment-start "// " |
| 2417 | comment-end "" | 3127 | comment-end "" |
| 2418 | comment-start-skip "/\\*+ *\\|// *") | 3128 | comment-start-skip "/\\*+ *\\|//+ *") |
| 2419 | ;; various ----------------------------------------------------------------- | 3129 | ;; various ----------------------------------------------------------------- |
| 2420 | (set (make-local-variable 'font-lock-defaults) antlr-font-lock-defaults) | 3130 | (set (make-local-variable 'font-lock-defaults) antlr-font-lock-defaults) |
| 2421 | (set (make-local-variable 'imenu-create-index-function) | 3131 | (set (make-local-variable 'imenu-create-index-function) |
| 2422 | #'antlr-imenu-create-index-function) | 3132 | #'antlr-imenu-create-index-function) |
| 2423 | (set (make-local-variable 'imenu-generic-expression) t) ; fool stupid test | 3133 | (set (make-local-variable 'imenu-generic-expression) t) ; fool stupid test |
| 2424 | (and antlr-imenu-name ; there should be a global variable... | 3134 | (easy-menu-add antlr-mode-menu) |
| 2425 | (imenu-add-to-menubar | 3135 | (run-mode-hooks 'antlr-delayed-mode-hook)) |
| 2426 | (if (stringp antlr-imenu-name) antlr-imenu-name "Index"))) | ||
| 2427 | (antlr-set-tabs)) | ||
| 2428 | 3136 | ||
| 2429 | ;; A smarter version of `group-buffers-menu-by-mode-then-alphabetically' (in | 3137 | ;; A smarter version of `group-buffers-menu-by-mode-then-alphabetically' (in |
| 2430 | ;; XEmacs) could use the following property. The header of the submenu would | 3138 | ;; XEmacs) could use the following property. The header of the submenu would |
| @@ -2432,9 +3140,18 @@ the default language." | |||
| 2432 | (put 'antlr-mode 'mode-name "Antlr") | 3140 | (put 'antlr-mode 'mode-name "Antlr") |
| 2433 | 3141 | ||
| 2434 | ;;;###autoload | 3142 | ;;;###autoload |
| 3143 | (define-derived-mode antlr-v4-mode antlr-mode | ||
| 3144 | "Antlr" ; use this in the menubar, see below for the mode line | ||
| 3145 | "Major mode for editing ANTLR v4 grammar files." | ||
| 3146 | :syntax-table nil | ||
| 3147 | :abbrev-table nil | ||
| 3148 | (set (make-local-variable 'antlr-tool-version) 'antlr-v4)) | ||
| 3149 | |||
| 3150 | ;;;###autoload | ||
| 2435 | (defun antlr-set-tabs () | 3151 | (defun antlr-set-tabs () |
| 2436 | "Use ANTLR's convention for TABs according to `antlr-tab-offset-alist'. | 3152 | "Use ANTLR's convention for TABs according to `antlr-tab-offset-alist'. |
| 2437 | Used in `antlr-mode'. Also a useful function in `java-mode-hook'." | 3153 | Used in `antlr-mode' for cc-mode-based languages. |
| 3154 | It is probably better to automatically deduce the TAB setting." | ||
| 2438 | (if buffer-file-name | 3155 | (if buffer-file-name |
| 2439 | (let ((alist antlr-tab-offset-alist) elem) | 3156 | (let ((alist antlr-tab-offset-alist) elem) |
| 2440 | (while alist | 3157 | (while alist |
| @@ -2442,12 +3159,237 @@ Used in `antlr-mode'. Also a useful function in `java-mode-hook'." | |||
| 2442 | (and (or (null (car elem)) (eq (car elem) major-mode)) | 3159 | (and (or (null (car elem)) (eq (car elem) major-mode)) |
| 2443 | (or (null (cadr elem)) | 3160 | (or (null (cadr elem)) |
| 2444 | (string-match (cadr elem) buffer-file-name)) | 3161 | (string-match (cadr elem) buffer-file-name)) |
| 2445 | (setq tab-width (caddr elem) | 3162 | (setq tab-width (cl-caddr elem) |
| 2446 | indent-tabs-mode (cadddr elem) | 3163 | indent-tabs-mode (cl-cadddr elem) |
| 2447 | alist nil)))))) | 3164 | alist nil)))))) |
| 2448 | 3165 | ||
| 2449 | (provide 'antlr-mode) | ||
| 2450 | 3166 | ||
| 2451 | ;; Local IspellPersDict: .ispell_antlr | 3167 | ;;;=========================================================================== |
| 3168 | ;;; CC-mode languages | ||
| 3169 | ;;;=========================================================================== | ||
| 3170 | |||
| 3171 | (defvar antlr-c-language-mode-name "C" | ||
| 3172 | "Value for `antlr-language-mode-name' when using language `antlr-c'.") | ||
| 3173 | (defvar antlr-cpp-language-mode-name "Cpp" | ||
| 3174 | "Value for `antlr-language-mode-name' when using language `antlr-cpp'.") | ||
| 3175 | (defvar antlr-objc-language-mode-name "ObjC" | ||
| 3176 | "Value for `antlr-language-mode-name' when using language `antlr-objc'.") | ||
| 3177 | |||
| 3178 | (defvar antlr-c-action-mode 'c-mode | ||
| 3179 | "Value for `antlr-action-mode' when using language `antlr-c'.") | ||
| 3180 | (defvar antlr-cpp-action-mode 'c++-mode | ||
| 3181 | "Value for `antlr-action-mode' when using language `antlr-cpp'.") | ||
| 3182 | (defvar antlr-objc-action-mode 'objc-mode | ||
| 3183 | "Value for `antlr-action-mode' when using language `antlr-objc'.") | ||
| 3184 | |||
| 3185 | (defvar antlr-c-init-cc-mode 'c-mode | ||
| 3186 | "Value for `antlr-init-cc-mode' when using language `antlr-c'.") | ||
| 3187 | (defvar antlr-cpp-init-cc-mode 'c++-mode | ||
| 3188 | "Value for `antlr-init-cc-mode' when using language `antlr-cpp'.") | ||
| 3189 | (defvar antlr-obj-init-cc-mode 'objc-mode | ||
| 3190 | "Value for `antlr-init-cc-mode' when using language `antlr-objc'.") | ||
| 3191 | |||
| 3192 | (defvar antlr-c-action-font-lock-keywords | ||
| 3193 | '(antlr-no-action-keywords | ||
| 3194 | c-font-lock-keywords-1 c-font-lock-keywords-2 | ||
| 3195 | c-font-lock-keywords-3) | ||
| 3196 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-c'.") | ||
| 3197 | (defvar antlr-cpp-action-font-lock-keywords | ||
| 3198 | '(antlr-no-action-keywords | ||
| 3199 | c++-font-lock-keywords-1 c++-font-lock-keywords-2 | ||
| 3200 | c++-font-lock-keywords-3) | ||
| 3201 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-cpp'.") | ||
| 3202 | (defvar antlr-objc-action-font-lock-keywords | ||
| 3203 | '(antlr-no-action-keywords | ||
| 3204 | objc-font-lock-keywords-1 objc-font-lock-keywords-2 | ||
| 3205 | objc-font-lock-keywords-3) | ||
| 3206 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-objc'.") | ||
| 3207 | |||
| 3208 | |||
| 3209 | ;;;=========================================================================== | ||
| 3210 | ;;; JavaScript | ||
| 3211 | ;;;=========================================================================== | ||
| 3212 | |||
| 3213 | (declare-function js-indent-line "js") | ||
| 3214 | ;; TODO: better support for js2-mode? | ||
| 3215 | |||
| 3216 | (defvar antlr-js-language-mode-name "Js" | ||
| 3217 | "Value for `antlr-language-mode-name' when using language `antlr-js'.") | ||
| 3218 | |||
| 3219 | (defvar antlr-js-action-mode 'js-mode | ||
| 3220 | "Value for `antlr-action-mode' when using language `antlr-js'.") | ||
| 3221 | |||
| 3222 | (defvar antlr-js-init-submode 'antlr-init-js | ||
| 3223 | "Value for `antlr-init-submode' when using language `antlr-js'.") | ||
| 3224 | |||
| 3225 | (defvar antlr-js-action-font-lock-keywords | ||
| 3226 | '(antlr-no-action-keywords | ||
| 3227 | ;; do not use `js--font-lock-keywords-3' ! | ||
| 3228 | js--font-lock-keywords-1 js--font-lock-keywords-2) | ||
| 3229 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-js'.") | ||
| 2452 | 3230 | ||
| 3231 | (defvar antlr-js-indent-action-line 'antlr-js-indent-action-line | ||
| 3232 | "Value for `antlr-indent-action-line' when using language `antlr-js'.") | ||
| 3233 | |||
| 3234 | (defun antlr-init-js () | ||
| 3235 | "Initialize action language `antlr-js'." | ||
| 3236 | (require 'js)) | ||
| 3237 | |||
| 3238 | (defun antlr-js-indent-action-line (_boa) | ||
| 3239 | "Indent the current line in an JavaScript action." | ||
| 3240 | (js-indent-line)) | ||
| 3241 | |||
| 3242 | |||
| 3243 | ;;;=========================================================================== | ||
| 3244 | ;;; Delphi (opascal) | ||
| 3245 | ;;;=========================================================================== | ||
| 3246 | |||
| 3247 | (declare-function opascal-indent-line "opascal") | ||
| 3248 | (defvar opascal-compound-block-indent) | ||
| 3249 | (defvar opascal-indent-level) | ||
| 3250 | (defvar opascal-case-label-indent) | ||
| 3251 | |||
| 3252 | (defvar antlr-delphi-language-mode-name "Delphi" | ||
| 3253 | "Value for `antlr-language-mode-name' when using language `antlr-delphi'.") | ||
| 3254 | |||
| 3255 | (defvar antlr-delphi-action-mode 'opascal-mode | ||
| 3256 | "Value for `antlr-action-mode' when using language `antlr-delphi'.") | ||
| 3257 | |||
| 3258 | (defvar antlr-delphi-init-submode 'antlr-init-delphi | ||
| 3259 | "Value for `antlr-init-submode' when using language `antlr-delphi'.") | ||
| 3260 | |||
| 3261 | (defvar antlr-delphi-action-font-lock-keywords | ||
| 3262 | '(antlr-no-action-keywords | ||
| 3263 | opascal-font-lock-keywords) | ||
| 3264 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-delphi'.") | ||
| 3265 | |||
| 3266 | (defvar antlr-delphi-indent-action-line 'antlr-delphi-indent-action-line | ||
| 3267 | "Value for `antlr-indent-action-line' when using language `antlr-delphi'.") | ||
| 3268 | |||
| 3269 | (defun antlr-init-delphi () | ||
| 3270 | "Initialize action language `antlr-delphi'." | ||
| 3271 | (require 'opascal) | ||
| 3272 | (when (integerp c-basic-offset) | ||
| 3273 | (when (equal opascal-compound-block-indent opascal-indent-level) | ||
| 3274 | (setq-local opascal-compound-block-indent c-basic-offset)) | ||
| 3275 | (when (equal opascal-case-label-indent opascal-indent-level) | ||
| 3276 | (setq-local opascal-case-label-indent c-basic-offset)) | ||
| 3277 | (setq-local opascal-indent-level c-basic-offset))) | ||
| 3278 | |||
| 3279 | (defun antlr-delphi-indent-action-line (boa) | ||
| 3280 | "Indent the current line in a Delphi (opascal) action. | ||
| 3281 | Argument BOA is the start position of the action." | ||
| 3282 | (narrow-to-region (1+ boa) (point-at-eol)) | ||
| 3283 | ;; make Pascal mode only checks the code fragment after the opening brace, | ||
| 3284 | ;; otherwise its indentation gets confused as {...} are block comments | ||
| 3285 | (opascal-indent-line) | ||
| 3286 | ;; or use low-level `opascal-corrected-indentation' - but that does not have | ||
| 3287 | ;; a docstring, i.e. not really official ? | ||
| 3288 | (widen) | ||
| 3289 | (unless (memq (char-after (point-at-bol)) '(?\ ?\t)) | ||
| 3290 | ;; no indentation -> considered top-level -> indentation can also be | ||
| 3291 | ;; performed by c-mode | ||
| 3292 | (c-indent-line))) | ||
| 3293 | |||
| 3294 | |||
| 3295 | ;;;=========================================================================== | ||
| 3296 | ;;; Ruby | ||
| 3297 | ;;;=========================================================================== | ||
| 3298 | |||
| 3299 | (declare-function ruby-indent-line "ruby-mode") | ||
| 3300 | (defvar ruby-indent-level) | ||
| 3301 | (defvar ruby-use-smie) | ||
| 3302 | |||
| 3303 | (defvar antlr-ruby-language-mode-name "Ruby" | ||
| 3304 | "Value for `antlr-language-mode-name' when using language `antlr-ruby'.") | ||
| 3305 | |||
| 3306 | (defvar antlr-ruby-action-mode 'ruby-mode | ||
| 3307 | "Value for `antlr-action-mode' when using language `antlr-ruby'.") | ||
| 3308 | |||
| 3309 | (defvar antlr-ruby-init-submode 'antlr-init-ruby | ||
| 3310 | "Value for `antlr-init-submode' when using language `antlr-ruby'.") | ||
| 3311 | |||
| 3312 | (defvar antlr-ruby-action-font-lock-keywords | ||
| 3313 | '(antlr-no-action-keywords | ||
| 3314 | ruby-font-lock-keywords) | ||
| 3315 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-ruby'.") | ||
| 3316 | |||
| 3317 | (defvar antlr-ruby-indent-action-line 'antlr-ruby-indent-action-line | ||
| 3318 | "Value for `antlr-indent-action-line' when using language `antlr-ruby'.") | ||
| 3319 | |||
| 3320 | (defun antlr-init-ruby () | ||
| 3321 | "Initialize action language `antlr-ruby'." | ||
| 3322 | (require 'ruby-mode) | ||
| 3323 | (setq-local ruby-indent-level c-basic-offset) | ||
| 3324 | ;; Disable smie as long as we do not have a function for a part of | ||
| 3325 | ;; `ruby-mode-variables' | ||
| 3326 | (setq-local ruby-use-smie nil)) | ||
| 3327 | |||
| 3328 | (defun antlr-ruby-indent-action-line (boa) | ||
| 3329 | "Indent the current line in a Ruby action. | ||
| 3330 | Argument BOA is the start position of the action." | ||
| 3331 | (narrow-to-region (1+ boa) (point-at-eol)) | ||
| 3332 | (ruby-indent-line) | ||
| 3333 | (widen) | ||
| 3334 | (unless (memq (char-after (point-at-bol)) '(?\ ?\t)) | ||
| 3335 | ;; no indentation -> considered top-level -> indentation can also be | ||
| 3336 | ;; performed by cc-mode | ||
| 3337 | (c-indent-line))) | ||
| 3338 | |||
| 3339 | |||
| 3340 | ;;;=========================================================================== | ||
| 3341 | ;;; Python | ||
| 3342 | ;;;=========================================================================== | ||
| 3343 | |||
| 3344 | (declare-function python-indent-line "python") | ||
| 3345 | (defvar prog-indentation-context) | ||
| 3346 | |||
| 3347 | (defvar antlr-python-language-mode-name "Python" | ||
| 3348 | "Value for `antlr-language-mode-name' when using language `antlr-python'.") | ||
| 3349 | |||
| 3350 | (defvar antlr-python-action-mode 'python-mode | ||
| 3351 | "Value for `antlr-action-mode' when using language `antlr-python'.") | ||
| 3352 | |||
| 3353 | (defvar antlr-python-init-submode 'antlr-init-python | ||
| 3354 | "Value for `antlr-init-submode' when using language `antlr-python'.") | ||
| 3355 | |||
| 3356 | (defvar antlr-python-action-font-lock-keywords | ||
| 3357 | '(antlr-no-action-keywords | ||
| 3358 | python-font-lock-keywords) | ||
| 3359 | "Value for `antlr-action-font-lock-keywords' when using language `antlr-python'.") | ||
| 3360 | |||
| 3361 | (defvar antlr-python-indent-action-line 'antlr-python-indent-action-line | ||
| 3362 | "Value for `antlr-indent-action-line' when using language `antlr-python'.") | ||
| 3363 | |||
| 3364 | (defun antlr-init-python () | ||
| 3365 | "Initialize action language `antlr-python'." | ||
| 3366 | (require 'python)) | ||
| 3367 | |||
| 3368 | (defun antlr-python-indent-action-line (boa) | ||
| 3369 | "Indent the current line in a Python action. | ||
| 3370 | Argument BOA is the start position of the action." | ||
| 3371 | (let (leftouter) | ||
| 3372 | (save-excursion | ||
| 3373 | (goto-char boa) | ||
| 3374 | (setq leftouter (current-indentation)) | ||
| 3375 | (forward-char) | ||
| 3376 | (skip-chars-forward " \t") | ||
| 3377 | (setq boa (and (eq (char-after) ?\n) (point)))) | ||
| 3378 | ;; a multi-line Python action does not start in its own line: this is a bad | ||
| 3379 | ;; idea -> we do not touch those actions | ||
| 3380 | (when (and boa | ||
| 3381 | (eq antlr-indent-comment t) ; indent-region | ||
| 3382 | (boundp 'prog-indentation-context)) ; Emacs 24.5 or later | ||
| 3383 | (let ((syntax-ppss-cache nil) ;#dynamic, in older Emacs... | ||
| 3384 | (syntax-ppss-last nil) ;#dynamic, in older Emacs... | ||
| 3385 | ;; TODO: do we also need to call `syntax-propertize' or | ||
| 3386 | ;; `syntax-ppss-flush-cache'? and/or bind | ||
| 3387 | ;; `syntax-propertize-function'? | ||
| 3388 | (prog-indentation-context ;#dynamic | ||
| 3389 | (list (+ leftouter c-basic-offset) (list (1+ boa))))) | ||
| 3390 | (narrow-to-region (1+ boa) (point-max)) | ||
| 3391 | (python-indent-line (eq this-command 'antlr-indent-command)))))) | ||
| 3392 | |||
| 3393 | |||
| 3394 | (provide 'antlr-mode) | ||
| 2453 | ;;; antlr-mode.el ends here | 3395 | ;;; antlr-mode.el ends here |