emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/parser-generator 16bb2d8 262/434: Added translation exa


From: ELPA Syncer
Subject: [elpa] externals/parser-generator 16bb2d8 262/434: Added translation example LRk parser
Date: Mon, 29 Nov 2021 15:59:54 -0500 (EST)

branch: externals/parser-generator
commit 16bb2d8863a0f637bb16965654cb5fed1e006817
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>

    Added translation example LRk parser
---
 docs/Syntax-Analysis/LRk.md | 111 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 97 insertions(+), 14 deletions(-)

diff --git a/docs/Syntax-Analysis/LRk.md b/docs/Syntax-Analysis/LRk.md
index 6c6eec7..04c8d59 100644
--- a/docs/Syntax-Analysis/LRk.md
+++ b/docs/Syntax-Analysis/LRk.md
@@ -15,12 +15,12 @@ A valid LR-item for a viable prefix has this structure:
 Example with grammar with production: S -> SaSb and S is non-terminal and a, b 
are terminals. Look-ahead number: 1
 
 ``` emacs-lisp
-(S nil (S a S b) (a))
+((S) nil (S a S b) (a))
 ```
 
 * A is the production LHS
-* B, C is parts of the production RHS, if the dot is the left B is nil and C 
is the entire RHS. If the dot is at the right then B is the production RHS and 
C is nil, otherwise B and C contains parts of the RHS
-* L is the terminal look-ahead
+* B, C is parts of the production RHS, if the dot is at the left B is nil and 
C is the entire RHS. If the dot is at the right then B is the production RHS 
and C is nil, otherwise B and C contains parts of the RHS
+* L is the item look-ahead
 
 ## LR items for prefix (S)
 
@@ -35,12 +35,12 @@ Calculate the set of LR items valid for any viable prefix S.
 
 (should
   (equal
-    '((S nil (S a S b) (a))
-      (S nil (S a S b) (e))
-      (S nil nil (a))
-      (S nil nil (e))
-      (Sp nil (S) (e)))
-    (parser--lr-items-for-prefix 'e)))
+   '(((S) nil (S a S b) ($))
+     ((S) nil (S a S b) (a))
+     ((S) nil nil ($))
+     ((S) nil nil (a))
+     ((Sp) nil (S) ($)))
+   (parser-generator-lr--items-for-prefix 'e)))
 ```
 
 ``` emacs-lisp
@@ -52,10 +52,10 @@ Calculate the set of LR items valid for any viable prefix S.
 
 (should
   (equal
-    '((S (S) (a S b) (a))
-      (S (S) (a S b) (e))
-      (Sp (S) nil (e)))
-    (parser--lr-items-for-prefix 'S)))
+   '(((S) (S) (a S b) ($))
+     ((S) (S) (a S b) (a))
+     ((Sp) (S) nil ($)))
+   (parser-generator-lr--items-for-prefix 'S)))
 ```
 
 ## Parse
@@ -93,6 +93,89 @@ Perform a right-parse of input-stream.
 
 ## Translate
 
-Coming soon!
+Each production RHS can optionally contain a lambda-expression that will be 
called if specified when a reduction is made, example:
+
+```emacs-lisp
+(let ((buffer (generate-new-buffer "*a*")))
+    (switch-to-buffer buffer)
+    (insert "if (a) { b; }")
+
+    (parser-generator-set-grammar '((Sp S) (";" OPEN_ROUND_BRACKET 
CLOSE_ROUND_BRACKET ECHO IF OPEN_CURLY_BRACKET CLOSE_CURLY_BRACKET VARIABLE) 
((Sp S) (S (IF OPEN_ROUND_BRACKET VARIABLE CLOSE_ROUND_BRACKET 
OPEN_CURLY_BRACKET VARIABLE ";" CLOSE_CURLY_BRACKET (lambda(args) (format 
"(when %s %s)" (nth 2 args) (nth 5 args)))))) Sp))
+    (parser-generator-set-look-ahead-number 1)
+    (parser-generator-process-grammar)
+    (parser-generator-lr-generate-parser-tables)
+
+    (setq
+     parser-generator-lex-analyzer--function
+     (lambda (index)
+       (with-current-buffer buffer
+         (unless (>= index (point-max))
+           (goto-char index)
+           (unless (looking-at "[^ \n\t]")
+             (search-forward-regexp "[^ \n\t]" nil t nil)
+             (forward-char -1))
+           (let ((token))
+             (cond
+              ((looking-at "if")
+               (setq token `(IF ,(match-beginning 0) . ,(match-end 0))))
+              ((looking-at "echo")
+               (setq token `(ECHO ,(match-beginning 0) . ,(match-end 0))))
+              ((looking-at "(")
+               (setq token `(OPEN_ROUND_BRACKET ,(match-beginning 0) . 
,(match-end 0))))
+              ((looking-at ")")
+               (setq token `(CLOSE_ROUND_BRACKET ,(match-beginning 0) . 
,(match-end 0))))
+              ((looking-at "{")
+               (setq token `(OPEN_CURLY_BRACKET ,(match-beginning 0) . 
,(match-end 0))))
+              ((looking-at "}")
+               (setq token `(CLOSE_CURLY_BRACKET ,(match-beginning 0) . 
,(match-end 0))))
+              ((looking-at ";")
+               (setq token `(";" ,(match-beginning 0) . ,(match-end 0))))
+              ((looking-at "[a-zA-Z]+")
+               (setq token `(VARIABLE ,(match-beginning 0) . ,(match-end 0))))
+              (t (error "Invalid syntax! Could not lex-analyze at %s!" 
(point))))
+             token)))))
+
+    (setq
+     parser-generator-lex-analyzer--get-function
+     (lambda (token)
+       (with-current-buffer buffer
+         (let ((start (car (cdr token)))
+               (end (cdr (cdr token))))
+           (when (<= end (point-max))
+             (buffer-substring-no-properties start end))))))
+
+    (should
+     (equal
+      "(when a b)"
+      (parser-generator-lr-translate)))
+    (message "Passed test with non-nested translation")
+
+    (switch-to-buffer buffer)
+    (kill-region (point-min) (point-max))
+
+    (parser-generator-set-grammar '((Sp S T) (";" OPEN_ROUND_BRACKET 
CLOSE_ROUND_BRACKET ECHO IF OPEN_CURLY_BRACKET CLOSE_CURLY_BRACKET VARIABLE) 
((Sp S) (S (IF OPEN_ROUND_BRACKET VARIABLE CLOSE_ROUND_BRACKET 
OPEN_CURLY_BRACKET T CLOSE_CURLY_BRACKET (lambda(args) (format "(when %s %s)" 
(nth 2 args) (nth 5 args))))) (T (ECHO VARIABLE ";" (lambda(args) (format 
"(message %s)" (nth 1 args)))) (VARIABLE ";" (lambda(args) (format "%s" (nth 0 
args)))))) Sp))
+    (parser-generator-set-look-ahead-number 1)
+    (parser-generator-process-grammar)
+    (parser-generator-lr-generate-parser-tables)
+
+    (insert "if (a) { echo b; }")
+
+    (should
+     (equal
+      "(when a (message b))"
+      (parser-generator-lr-translate)))
+
+    (message "Passed test with nested-translation with depth 2")
+
+    (switch-to-buffer buffer)
+    (kill-region (point-min) (point-max))
+    (goto-char 1)
+    (insert "if (a) { echo b }")
+
+    (should-error
+     (parser-generator-lr-parse))
+
+    (kill-buffer buffer))
+```
 
 [Back to syntax analysis](../../Syntax-Analysis.md)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]