import.scm 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. ;;; nyacc/import.scm
  2. ;;;
  3. ;;; Copyright (C) 2015 Matthew R. Wette
  4. ;;;
  5. ;;; This library is free software; you can redistribute it and/or
  6. ;;; modify it under the terms of the GNU Lesser General Public
  7. ;;; License as published by the Free Software Foundation; either
  8. ;;; version 3 of the License, or (at your option) any later version.
  9. ;;;
  10. ;;; This library is distributed in the hope that it will be useful,
  11. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;; Lesser General Public License for more details.
  14. ;;;
  15. ;;; You should have received a copy of the GNU Lesser General Public License
  16. ;;; along with this library; if not, see <http://www.gnu.org/licenses/>
  17. ;; Convert guile lalr grammar to nyacc grammar.
  18. ;; What is *eoi* for?
  19. (define-module (nyacc import)
  20. ;;#:export-syntax (lalr-parser)
  21. #:export (lalr-parser guile-lalr->nyacc-lalr)
  22. #:use-module ((srfi srfi-1) #:select (fold-right))
  23. )
  24. (define (convert-tree spec0)
  25. (let* ((terms (cons '*eoi* (car spec0)))
  26. (start (caadr spec0))
  27. (wrap-symb
  28. (lambda (s) (cons (if (memq s terms) 'terminal 'non-terminal) s))))
  29. (let iter ((prl1 '()) ; new production rules
  30. (prl0 (cdr spec0)) ; old production rules
  31. (lhs #f) ; LHS
  32. (rhs1-l #f) ; new RHS list
  33. (rhs0-l #f)) ; old RHS list
  34. (cond
  35. ((pair? rhs0-l) ;; convert RHS
  36. (iter prl1 prl0 lhs
  37. (cons
  38. (fold-right ;; s1 ... : a => (('terminal . s) ... ('$$ . a))
  39. (lambda (symb seed) (cons (wrap-symb symb) seed))
  40. (list (list '$$ (cdar rhs0-l)))
  41. (caar rhs0-l))
  42. rhs1-l)
  43. (cdr rhs0-l)))
  44. ((null? rhs0-l) ;; roll up LHS+RHSs to new rule
  45. (iter (cons (cons lhs (reverse rhs1-l)) prl1) prl0 #f #f #f))
  46. ((pair? prl0) ;; next production rule
  47. (iter prl1 (cdr prl0) (caar prl0) '() (cdar prl0)))
  48. (else ;; return spec in preliminary form
  49. (list
  50. 'lalr-spec
  51. `(start ,start)
  52. `(grammar ,(reverse prl1))))))))
  53. (define-syntax parse-rhs-list
  54. (syntax-rules (:)
  55. ((_ (<rhs0sym> ...) : <rhs0act> <rhs1> ...)
  56. (cons (cons '(<rhs0sym> ...) '<rhs0act>)
  57. (parse-rhs-list <rhs1> ...)))
  58. ((_) (list))))
  59. (define-syntax parse-prod-list
  60. (syntax-rules ()
  61. ((_ (<lhs> <rhs> ...) <prod1> ...)
  62. (cons (cons '<lhs> (parse-rhs-list <rhs> ...))
  63. (parse-prod-list <prod1> ...)))
  64. ((_) (list))))
  65. (define-syntax lalr-parser
  66. (syntax-rules ()
  67. ((_ <tokens> <prod0> ...)
  68. (convert-tree
  69. (cons '<tokens> (parse-prod-list <prod0> ...))))))
  70. (define (guile-lalr->nyacc-lalr match-table spec)
  71. (letrec
  72. ((mark (lambda (s) (if (symbol? s) `(quote ,s) s)))
  73. (rmt (map (lambda (p) (cons (cdr p) (mark (car p)))) match-table))
  74. (clean
  75. (lambda (dt)
  76. (cond
  77. ((null? dt) '())
  78. ((pair? dt)
  79. (case (car dt)
  80. ((non-terminal) (cdr dt))
  81. ((terminal)
  82. (cond
  83. ((assq-ref rmt (cdr dt)))
  84. ((symbol? (cdr dt)) (simple-format #f "~A" (cdr dt)))
  85. (else (cdr dt))))
  86. ((start) dt)
  87. (else
  88. (cons (clean (car dt)) (clean (cdr dt))))))
  89. (else
  90. dt))))
  91. )
  92. (clean spec)))
  93. ;;; --- last line ---