[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/parser-generator a046c8584d 73/82: Started on documenta
From: |
Christian Johansson |
Subject: |
[elpa] externals/parser-generator a046c8584d 73/82: Started on documentation for LL(k) and LL(1) |
Date: |
Thu, 12 May 2022 13:28:19 -0400 (EDT) |
branch: externals/parser-generator
commit a046c8584ded8dc73567ad7b078bc048a34d3859
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>
Started on documentation for LL(k) and LL(1)
---
docs/Syntax-Analysis.md | 4 +-
docs/Syntax-Analysis/LL1.md | 110 ++++++++++++++++++++++++++++++++++++++
docs/Syntax-Analysis/LLk.md | 111 +++++++++++++++++++++++++++++++++++++++
parser-generator.el | 2 +-
test/parser-generator-ll-test.el | 49 +++++++++++++++--
5 files changed, 269 insertions(+), 7 deletions(-)
diff --git a/docs/Syntax-Analysis.md b/docs/Syntax-Analysis.md
index daaa363800..c391d346f0 100644
--- a/docs/Syntax-Analysis.md
+++ b/docs/Syntax-Analysis.md
@@ -11,8 +11,8 @@ We use push down transducer (PDT) based algorithms.
## Without Backtracking
-* LL(1) *WIP*
-* LL(k) *WIP*
+* [LL(1)](Syntax-Analysis/LL1.md)
+* [LL(k)](Syntax-Analysis/LLk.md)
* [LR(k)](Syntax-Analysis/LRk.md)
* [LR(0)](Syntax-Analysis/LR0.md)
* Formal Shift-Reduce Parsing Algorithms *WIP*
diff --git a/docs/Syntax-Analysis/LL1.md b/docs/Syntax-Analysis/LL1.md
new file mode 100644
index 0000000000..50c74d9650
--- /dev/null
+++ b/docs/Syntax-Analysis/LL1.md
@@ -0,0 +1,110 @@
+# LL(1) Parser
+
+LL(1) parser is a Left-to-right, Leftmost derivation with look-ahead number k
= 1.
+
+This library contains functions to parse, translate, validate grammars.
+
+## Parse
+
+Perform a left-parse of input-stream.
+
+```emacs-lisp
+(require 'parser-generator-ll)
+(require 'ert)
+(parser-generator-set-eof-identifier '$)
+(parser-generator-set-e-identifier 'e)
+(parser-generator-set-look-ahead-number 1)
+(parser-generator-set-grammar
+ '(
+ (S A)
+ (a b)
+ (
+ (S (a A S) b)
+ (A a (b S A))
+ )
+ S
+ )
+ )
+(parser-generator-process-grammar)
+(parser-generator-ll-generate-table)
+(setq
+ parser-generator-lex-analyzer--function
+ (lambda (index)
+ (let* ((string '((a 1 . 2) (b 2 . 3) (b 3 . 4) (a 4 . 5) (b 5 . 6)))
+ (string-length (length string))
+ (max-index index)
+ (tokens))
+ (while (and
+ (< (1- index) string-length)
+ (< (1- index) max-index))
+ (push (nth (1- index) string) tokens)
+ (setq index (1+ index)))
+ (nreverse tokens))))
+(setq
+ parser-generator-lex-analyzer--get-function
+ (lambda (token)
+ (car token)))
+(parser-generator-ll-parse)
+(should
+ (equal
+ '(0 3 1 2 1) ;; Example is indexed from 1 so that is why they have '(1 4 2 3
2)
+ (parser-generator-ll-parse)))
+(message "Passed example 5.5 p. 340")
+```
+
+## Translate
+
+Each production RHS can optionally contain a lambda-expression that will be
called if specified when stack is reduced:
+
+```emacs-lisp
+ (parser-generator-set-eof-identifier '$)
+ (parser-generator-set-e-identifier 'e)
+ (parser-generator-set-look-ahead-number 2)
+ (parser-generator-set-grammar
+ '(
+ (S A)
+ (a b)
+ (
+ (S
+ (a A a a (lambda(a b) (format "alfa %s laval" (nth 1 a))))
+ (b A b a (lambda(a b) (format "delta %s laval" (nth 1 a))))
+ )
+ (A
+ (b (lambda(a b) "sven"))
+ (e (lambda(a b) "ingrid"))
+ )
+ )
+ S
+ )
+ )
+ (parser-generator-process-grammar)
+ (parser-generator-ll-generate-table)
+ (setq
+ parser-generator-lex-analyzer--function
+ (lambda (index)
+ (let* ((string '((b 1 . 2) (b 2 . 3) (a 3 . 4)))
+ (string-length (length string))
+ (max-index index)
+ (tokens))
+ (while (and
+ (< (1- index) string-length)
+ (< (1- index) max-index))
+ (push (nth (1- index) string) tokens)
+ (setq index (1+ index)))
+ (nreverse tokens))))
+ (setq
+ parser-generator-lex-analyzer--get-function
+ (lambda (token)
+ (car token)))
+ (should
+ (equal
+ "delta ingrid laval"
+ (parser-generator-ll-translate)))
+ (message "Passed translation test 1")
+```
+
+## Export
+
+*WIP*
+
+[Back to syntax analysis](../Syntax-Analysis.md)
diff --git a/docs/Syntax-Analysis/LLk.md b/docs/Syntax-Analysis/LLk.md
new file mode 100644
index 0000000000..9881f3a7f2
--- /dev/null
+++ b/docs/Syntax-Analysis/LLk.md
@@ -0,0 +1,111 @@
+# LL(k) Parser
+
+LL(k) parser is a Left-to-right, Leftmost derivation with look-ahead number k
> 1.
+
+This library contains functions to parse, translate, validate grammars.
+
+## Parse
+
+Perform a left-parse of input-stream.
+
+```emacs-lisp
+(require 'parser-generator-ll)
+(require 'ert)
+
+(parser-generator-set-eof-identifier '$)
+(parser-generator-set-e-identifier 'e)
+(parser-generator-set-look-ahead-number 2)
+(parser-generator-set-grammar
+ '(
+ (S A)
+ (a b)
+ (
+ (S (a A a a) (b A b a))
+ (A b e)
+ )
+ S
+ )
+ )
+(parser-generator-process-grammar)
+(parser-generator-ll-generate-table)
+(setq
+ parser-generator-lex-analyzer--function
+ (lambda (index)
+ (let* ((string '((b 1 . 2) (b 2 . 3) (a 3 . 4)))
+ (string-length (length string))
+ (max-index index)
+ (tokens))
+ (while (and
+ (< (1- index) string-length)
+ (< (1- index) max-index))
+ (push (nth (1- index) string) tokens)
+ (setq index (1+ index)))
+ (nreverse tokens))))
+(setq
+ parser-generator-lex-analyzer--get-function
+ (lambda (token)
+ (car token)))
+
+(should
+ (equal
+ '(1 3) ;; Example is indexed from 1 so that is why they have '(2 4)
+ (parser-generator-ll-parse)))
+(message "Passed example 5.16 p. 352")
+```
+
+## Translate
+
+Each production RHS can optionally contain a lambda-expression that will be
called if specified when stack is reduced:
+
+```emacs-lisp
+ (parser-generator-set-eof-identifier '$)
+ (parser-generator-set-e-identifier 'e)
+ (parser-generator-set-look-ahead-number 2)
+ (parser-generator-set-grammar
+ '(
+ (S A)
+ (a b)
+ (
+ (S
+ (a A a a (lambda(a b) (format "alfa %s laval" (nth 1 a))))
+ (b A b a (lambda(a b) (format "delta %s laval" (nth 1 a))))
+ )
+ (A
+ (b (lambda(a b) "sven"))
+ (e (lambda(a b) "ingrid"))
+ )
+ )
+ S
+ )
+ )
+ (parser-generator-process-grammar)
+ (parser-generator-ll-generate-table)
+ (setq
+ parser-generator-lex-analyzer--function
+ (lambda (index)
+ (let* ((string '((b 1 . 2) (b 2 . 3) (a 3 . 4)))
+ (string-length (length string))
+ (max-index index)
+ (tokens))
+ (while (and
+ (< (1- index) string-length)
+ (< (1- index) max-index))
+ (push (nth (1- index) string) tokens)
+ (setq index (1+ index)))
+ (nreverse tokens))))
+ (setq
+ parser-generator-lex-analyzer--get-function
+ (lambda (token)
+ (car token)))
+ (should
+ (equal
+ "delta ingrid laval"
+ (parser-generator-ll-translate)))
+ (message "Passed translation test 1")
+```
+
+## Export
+
+*WIP*
+
+[Back to syntax analysis](../Syntax-Analysis.md)
diff --git a/parser-generator.el b/parser-generator.el
index 4b749f7f31..dfd698663e 100644
--- a/parser-generator.el
+++ b/parser-generator.el
@@ -45,7 +45,7 @@
(defvar
parser-generator--debug
- nil
+ t
"Whether to print debug messages or not.")
(defvar
diff --git a/test/parser-generator-ll-test.el b/test/parser-generator-ll-test.el
index d59f9ddbcb..e5cf346430 100644
--- a/test/parser-generator-ll-test.el
+++ b/test/parser-generator-ll-test.el
@@ -280,8 +280,6 @@
parser-generator-lex-analyzer--get-function
(lambda (token)
(car token)))
- ;; (message "parsing-table: %S" (parser-generator--hash-to-list
parser-generator-ll--table t))
-
(should
(equal
'(1 3) ;; Example is indexed from 1 so that is why they have '(2 4)
@@ -321,7 +319,6 @@
parser-generator-lex-analyzer--get-function
(lambda (token)
(car token)))
- (parser-generator-ll-parse)
(should
(equal
'(1 2 0) ;; Example is indexed from 1 so that is why they have '(2 3 1)
@@ -361,7 +358,6 @@
parser-generator-lex-analyzer--get-function
(lambda (token)
(car token)))
- (parser-generator-ll-parse)
(should
(equal
'(0 3 1 2 1) ;; Example is indexed from 1 so that is why they have '(1 4 2
3 2)
@@ -480,6 +476,51 @@
(parser-generator-ll-translate)))
(message "Passed translation test 2")
+ (parser-generator-set-eof-identifier '$)
+ (parser-generator-set-e-identifier 'e)
+ (parser-generator-set-look-ahead-number 1)
+ (parser-generator-set-grammar
+ '(
+ (S A)
+ (a b)
+ (
+ (S
+ (a A S (lambda(a b) (format "alfa %s %s" (nth 1 a) (nth 2 a))))
+ (b (lambda(a b) "beta"))
+ )
+ (A
+ (a (lambda(a b) "delta"))
+ (b S A (lambda(a b) (format "gamma %s %s" (nth 1 a) (nth 2 a))))
+ )
+ )
+ S
+ )
+ )
+ (parser-generator-process-grammar)
+ (parser-generator-ll-generate-table)
+ (setq
+ parser-generator-lex-analyzer--function
+ (lambda (index)
+ (let* ((string '((a 1 . 2) (b 2 . 3) (b 3 . 4) (a 4 . 5) (b 5 . 6)))
+ (string-length (length string))
+ (max-index index)
+ (tokens))
+ (while (and
+ (< (1- index) string-length)
+ (< (1- index) max-index))
+ (push (nth (1- index) string) tokens)
+ (setq index (1+ index)))
+ (nreverse tokens))))
+ (setq
+ parser-generator-lex-analyzer--get-function
+ (lambda (token)
+ (car token)))
+ (should
+ (equal
+ "delta sven laval"
+ (parser-generator-ll-translate)))
+ (message "Passed translation test 3")
+
(message "Passed tests for (parser-generator-ll-translate)"))
(defun parser-generator-ll-test-generate-table ()
- [elpa] externals/parser-generator 5c0bcd5f9a 36/82: Passing test for LL-table generation example 5.17, (continued)
- [elpa] externals/parser-generator 5c0bcd5f9a 36/82: Passing test for LL-table generation example 5.17, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 1290048b84 39/82: Improved documentation, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 57c6fdda2f 43/82: Passing test for generating LL-parser hash-table, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator b37ba1eddf 52/82: Created TODO item, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator af3740c46a 59/82: More refactoring, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 3d373f4dfa 60/82: Updated docs, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 020969094c 61/82: More refactoring, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 08ed55d35a 62/82: More work on k=1, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 4f85cc5616 66/82: Passes byte-compilation tests, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 7a265c9a84 67/82: LL-tests now runs on make tests command, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator a046c8584d 73/82: Started on documentation for LL(k) and LL(1),
Christian Johansson <=
- [elpa] externals/parser-generator f07939a440 76/82: Added example from Wikipedia and passing test, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 03a11c4369 14/82: Started test for LL(k) parser-table generation, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 9d6ca94d0e 02/82: More work on LL(k) parser, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 6ce0dd9429 04/82: Improved function to calculate merge max terminal sets, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 52734d7160 16/82: Updated TODO items, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 7b77032f71 22/82: Parser table generation for LLk now works for productions, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator fe728f8ad8 23/82: Passing test for generating LLk parser table, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 3b9977b51b 28/82: More work on LLk test, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator f23bc217d8 30/82: More wrestling, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 6e91a4b498 32/82: More work on helper functions, Christian Johansson, 2022/05/12