branch: externals/phps-mode commit b2c3fa066b094616a150a99d65bec40021b3d365 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
More work on parser generation automation --- Makefile | 2 +- admin/phps-mode-automation.el | 160 ++++++++++++++++++++++------------------ phps-mode-automation-grammar.el | 64 +++++++++++++--- 3 files changed, 144 insertions(+), 82 deletions(-) diff --git a/Makefile b/Makefile index 1359ab8..5157f8f 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ clean: .PHONY: generate-parser generate-parser: - $(EMACS_CMD) -L ~/.emacs.d/emacs-parser-generator/ -l phps-mode-lexer.el -l admin/phps-mode-automation.el + $(EMACS_CMD) -L ~/.emacs.d/emacs-parser/ -l phps-mode-lexer.el -l admin/phps-mode-automation.el -e "(progn (require 'parser-generator-lr-export)(phps-mode-automation))" .PHONY: compile compile: diff --git a/admin/phps-mode-automation.el b/admin/phps-mode-automation.el index 013b11f..2ce8f7b 100644 --- a/admin/phps-mode-automation.el +++ b/admin/phps-mode-automation.el @@ -29,76 +29,96 @@ (require 'phps-mode-automation-grammar) -(when (fboundp 'parser-generator-lr-export-to-elisp) - - (let ((php-yacc-url "https://raw.githubusercontent.com/php/php-src/php-8.0.0/Zend/zend_language_parser.y") - (php-yacc-file (expand-file-name "zend_language_parser.y"))) - - ;; Download Yacc if not available - (unless (file-exists-p php-yacc-file) - (message "Downloading PHP 8.0 YACC grammar..") - (url-copy-file php-yacc-url php-yacc-file t t) - (message "Download of PHP 8.0 YACC grammar completed")) - - ;; Prepare export - (when (fboundp 'parser-generator-set-grammar) - (parser-generator-set-grammar - `( - ,phps-mode-automation-grammar-non-terminals - ,phps-mode-automation-grammar-terminals - ,phps-mode-automation-grammar-productions - ,phps-mode-automation-grammar-start - ) - )) - (when (fboundp 'parser-generator-set-look-ahead-number) - (parser-generator-set-look-ahead-number - phps-mode-automation-grammar-look-ahead-number)) - (when (boundp 'parser-generator--e-identifier) - (setq - parser-generator--e-identifier - phps-mode-automation-grammar-e-identifier)) - (when (boundp 'parser-generator--eof-identifier) - (setq - parser-generator--eof-identifier - phps-mode-automation-grammar-eof-identifier)) - (when (boundp 'parser-generator-lex-analyzer--function) - (setq - parser-generator-lex-analyzer--function - phps-mode-automation-grammar-lex-analyzer-function)) - (when (boundp 'parser-generator-lex-analyzer--get-function) - (setq - parser-generator-lex-analyzer--get-function - phps-mode-automation-grammar-lex-analyzer-get-function)) - (when (boundp 'parser-generator-lr--precedence-attribute) - (setq - parser-generator-lr--precedence-attribute - phps-mode-automation-grammar-precendece-attribute)) - (when (boundp 'parser-generator-lr--precedence-comparison-function) - (setq - parser-generator-lr--precedence-comparison-function - phps-mode-automation-grammar-precedence-comparison-function)) - (when (boundp 'parser-generator--global-declaration) - (setq - parser-generator--global-declaration - phps-mode-automation-grammar-global-declaration)) - (when (boundp 'parser-generator--context-sensitive-attributes) - (setq - parser-generator--context-sensitive-attributes - phps-mode-automation-grammar-context-sensitive-attributes)) - (when (boundp 'parser-generator--global-attributes) - (setq - parser-generator--global-attributes - phps-mode-automation-grammar-global-declaration)) - (when (fboundp 'parser-generator-process-grammar) - (parser-generator-process-grammar)) - (when (fboundp 'parser-generator-lr-generate-parser-tables) - (parser-generator-lr-generate-parser-tables)) - - ;; Export - (let ((export (parser-generator-lr-export-to-elisp "phps-mode-parser"))) - (message "export: %s" export)) - - (message "Automation completed"))) +(defun phps-mode-automation () + "Generate parser." + (when (fboundp 'parser-generator-lr-export-to-elisp) + + (let ((php-yacc-url "https://raw.githubusercontent.com/php/php-src/php-8.0.0/Zend/zend_language_parser.y") + (php-yacc-file (expand-file-name "zend_language_parser.y"))) + + ;; Download Yacc if not available + (unless (file-exists-p php-yacc-file) + (message "Downloading PHP 8.0 YACC grammar..") + (url-copy-file php-yacc-url php-yacc-file t t) + (message "Download of PHP 8.0 YACC grammar completed")) + + ;; Prepare export + (when (fboundp 'parser-generator-set-grammar) + (parser-generator-set-grammar + `( + ,phps-mode-automation-grammar-non-terminals + ,phps-mode-automation-grammar-terminals + ,phps-mode-automation-grammar-productions + ,phps-mode-automation-grammar-start + ) + )) + (when (fboundp 'parser-generator-set-look-ahead-number) + (parser-generator-set-look-ahead-number + phps-mode-automation-grammar-look-ahead-number)) + (when (boundp 'parser-generator--e-identifier) + (setq + parser-generator--e-identifier + phps-mode-automation-grammar-e-identifier)) + (when (boundp 'parser-generator--eof-identifier) + (setq + parser-generator--eof-identifier + phps-mode-automation-grammar-eof-identifier)) + (when (boundp 'parser-generator-lex-analyzer--function) + (setq + parser-generator-lex-analyzer--function + phps-mode-automation-grammar-lex-analyzer-function)) + + (when (boundp 'parser-generator-lex-analyzer--get-function) + (setq + parser-generator-lex-analyzer--get-function + phps-mode-automation-grammar-lex-analyzer-get-function)) + + (when (boundp 'parser-generator--global-attributes) + (setq + parser-generator--global-attributes + phps-mode-automation-grammar-global-declaration)) + + (when (boundp 'parser-generator-lr--global-precedence-attributes) + (setq + parser-generator-lr--global-precedence-attributes + phps-mode-lr--global-precedence-attributes)) + + (when (boundp 'parser-generator--context-sensitive-attributes) + (setq + parser-generator--context-sensitive-attributes + phps-mode-automation-grammar-context-sensitive-attributes)) + + (when (boundp 'parser-generator-lr--context-sensitive-precedence-attribute) + (setq + parser-generator-lr--context-sensitive-precedence-attribute + phps-mode-automation-lr--context-sensitive-precedence-attribute)) + + (when (boundp 'parser-generator-lr--precedence-attribute) + (setq + parser-generator-lr--precedence-attribute + phps-mode-automation-grammar-precendece-attribute)) + + (when (boundp 'parser-generator-lr--precedence-comparison-function) + (setq + parser-generator-lr--precedence-comparison-function + phps-mode-automation-grammar-precedence-comparison-function)) + + (when (boundp 'parser-generator--global-declaration) + (setq + parser-generator--global-declaration + phps-mode-automation-grammar-global-declaration)) + + (when (fboundp 'parser-generator-process-grammar) + (parser-generator-process-grammar)) + + (when (fboundp 'parser-generator-lr-generate-parser-tables) + (parser-generator-lr-generate-parser-tables)) + + ;; Export + (let ((export (parser-generator-lr-export-to-elisp "phps-mode-parser"))) + (message "export: %s" export)) + + (message "Automation completed")))) (provide 'phps-mode-automation) ;;; phps-mode-automation.el ends here diff --git a/phps-mode-automation-grammar.el b/phps-mode-automation-grammar.el index 8612a5c..da7858c 100644 --- a/phps-mode-automation-grammar.el +++ b/phps-mode-automation-grammar.el @@ -32,11 +32,21 @@ "List of context-sensitive attributes.") (defconst + phps-mode-automation-lr--context-sensitive-precedence-attribute + '%prec + "The LR-parser's context-sensitive precedence attribute.") + +(defconst phps-mode-automation-grammar-global-attributes - '(%precedence %left %right %nonassoc) + '(%left %nonassoc %precedence %right) "List of valid global attributes.") (defconst + phps-mode-lr--global-precedence-attributes + '%prec + "The LR-parser's list of global precedence attributes.") + +(defconst phps-mode-automation-grammar-global-declaration '( (%precedence T_THROW) @@ -865,7 +875,7 @@ ) (if_stmt - (if_stmt_without_else (%prec T_NOELSE)) + (if_stmt_without_else %prec T_NOELSE) (if_stmt_without_else T_ELSE statement) ) @@ -1127,8 +1137,8 @@ (expr "%" expr) (expr T_SL expr) (expr T_SR expr) - ("+" (expr (%prec "~"))) - ("-" (expr (%prec "~"))) + ("+" expr %prec "~") + ("-" expr %prec "~") ("!" expr) ("~" expr) (expr T_IS_IDENTICAL expr) @@ -1186,7 +1196,7 @@ %empty) (backup_fn_flags - (%empty (%prec PREC_ARROW_FUNCTION))) + (%empty %prec PREC_ARROW_FUNCTION)) (backup_lex_pos %empty) @@ -1449,13 +1459,45 @@ "The custom lex-analyzer.") (defconst - phps-mode-automation-grammar-precendece-attribute - '%prec - "The precedence attribute of the grammar.") - -(defconst phps-mode-automation-grammar-precedence-comparison-function - #'> + (lambda(a-type a-value _b-type b-value) + (cond + + ((and + a-value + b-value) + (cond + ((> a-value b-value) + t) + + ((< a-value b-value) + nil) + + ((= a-value b-value) + + (cond + ((equal a-type '%left) + t) + + ((equal a-type '%right) + nil) + + ((equal a-type '%precedence) + t)) + + ))) + + ((and + a-value + (not b-value)) + t) + + ((and + (not a-value) + (not b-value)) + nil) + + )) "The precedence comparison function of the grammar.") (defconst