Skip to content

Commit 3cdcd90

Browse files
committed
Added parser-error generating to src/parser
1 parent 651f974 commit 3cdcd90

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

DiffBackend/src/parser.lisp

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
(uiop:define-package :diff-backend/parser
22
(:nicknames :parser)
3-
(:use :cl :diff-backend/lexer)
3+
(:use :cl :diff-backend/lexer
4+
:diff-backend/utils)
45
(:import-from :alexandria
5-
:eswitch)
6+
:eswitch)
67
(:export #:parser))
78

89
(in-package :diff-backend/parser)
@@ -14,21 +15,39 @@
1415

1516
(defvar *cur-lex* nil)
1617

18+
(defclass* parser-error-info ()
19+
((error-text
20+
:accessor error-text
21+
:initarg :error-text)
22+
(error-lex-id
23+
:accessor error-lex-id
24+
:initarg :error-lex-id)))
25+
1726
(defun next-lexem ()
1827
(progn
1928
(setf *cur-lex* (first *lexems-rest*))
2029
(setf *lexems-rest* (rest *lexems-rest*))
2130
*cur-lex*))
2231

23-
(defun cur-lexem ()
24-
*cur-lex*)
32+
(defun throw-error (error-text error-lex)
33+
(throw 'parser-start
34+
(values nil
35+
(make-instance
36+
'parser-error-info
37+
:error-text
38+
(format nil "At (~S:~S) ~A"
39+
(lexem-line error-lex)
40+
(lexem-column error-lex)
41+
error-text)
42+
:error-lex-id (id error-lex)))))
2543

2644
(defun parser (lexems)
2745
(let ((*lexems-rest* lexems)
2846
(s-expr-l))
29-
(loop :while *lexems-rest*
30-
:do (push (s-expr-rule (next-lexem)) s-expr-l))
31-
`(:top () ,@(reverse s-expr-l))))
47+
(catch 'parser-start
48+
(loop :while *lexems-rest*
49+
:do (push (s-expr-rule (next-lexem)) s-expr-l))
50+
`(:top () ,@(reverse s-expr-l)))))
3251

3352
(defun s-expr-rule (lex)
3453
(ecase (lexem-type lex)
@@ -37,17 +56,26 @@
3756
((:left-parent)
3857
(list-rule lex))
3958
((:quote)
40-
`(:quote ((:coord ,(lexem-line lex)
41-
,(lexem-column lex)))
42-
,(s-expr-rule (next-lexem))))))
59+
(let ((next-lex (next-lexem)))
60+
(when (or (null next-lex)
61+
(eq (lexem-type next-lex) :right-parent))
62+
(throw-error "no s-expr after '" lex))
63+
`(:quote
64+
((:coord ,(lexem-line lex)
65+
,(lexem-column lex)))
66+
,(s-expr-rule next-lex))))
67+
((:right-parent)
68+
(throw-error "unmatched close parenthesis" lex))))
4369

4470
(defun list-rule (left-parent-lexem)
4571
(do ((s-expr-l nil)
4672
(lex (next-lexem) (next-lexem)))
47-
((eq (lexem-type lex) :right-parent)
73+
((when lex (eq (lexem-type lex) :right-parent))
4874
`(:list ((:lparen-coord ,(lexem-line left-parent-lexem)
4975
,(lexem-column left-parent-lexem))
5076
(:rparen-coord ,(lexem-line lex)
5177
,(lexem-column lex)))
5278
,@(reverse s-expr-l)))
79+
(unless lex
80+
(throw-error "unclosed parenthesis" left-parent-lexem))
5381
(push (s-expr-rule lex) s-expr-l)))

0 commit comments

Comments
 (0)