summaryrefslogtreecommitdiff
path: root/syntax-highlight/lexers.scm
diff options
context:
space:
mode:
authorJulien Lepiller <julien@lepiller.eu>2021-08-21 14:45:28 +0200
committerDavid Thompson <dthompson@vistahigherlearning.com>2021-08-21 09:03:20 -0400
commit7d8ed073db9028593ff87c1699ffc47525451476 (patch)
treeb81eb25701c9ae49613feea1f9884956d9a88dcc /syntax-highlight/lexers.scm
parent8f109c9054da3b7f8cb19421dcd0263c9b34b580 (diff)
Add css lexer.
Diffstat (limited to 'syntax-highlight/lexers.scm')
-rw-r--r--syntax-highlight/lexers.scm49
1 files changed, 41 insertions, 8 deletions
diff --git a/syntax-highlight/lexers.scm b/syntax-highlight/lexers.scm
index 0591da2..4367c82 100644
--- a/syntax-highlight/lexers.scm
+++ b/syntax-highlight/lexers.scm
@@ -63,10 +63,13 @@
lex-maybe
lex-regexp
lex-string
+ lex-char
lex-char-set
lex-whitespace
lex-delimited
- lex-tag))
+ lex-tag
+ lex-group
+ lex-peek))
(define (string-prefix?* s1 s2 start-s2)
(string-prefix? s1 s2 0 (string-length s1) start-s2))
@@ -300,7 +303,7 @@ STR."
(move-cursor-by cursor (string-length str)))
(fail))))
-(define (lex-char-set char-set)
+(define* (lex-char-set char-set #:key (min 1) (max #f))
"Return a lexer that succeeds with the nonempty input prefix that
matches CHAR-SET, or fails if the first input character does not
belong to CHAR-SET."
@@ -308,7 +311,7 @@ belong to CHAR-SET."
(let ((len (string-length str)))
(let loop ((index start))
(cond
- ((>= index len)
+ ((or (>= index len) (and max (>= (- index start) max)))
(substring str start len))
((char-set-contains? char-set (string-ref str index))
(loop (1+ index)))
@@ -316,11 +319,22 @@ belong to CHAR-SET."
(substring str start index))))))
(lambda (tokens cursor)
- (match (char-set-substring (cursor-text cursor) (cursor-position cursor))
- ("" (fail))
- (str
- (values (token-add tokens str)
- (move-cursor-by cursor (string-length str)))))))
+ (let ((str (char-set-substring (cursor-text cursor) (cursor-position cursor))))
+ (cond
+ ((equal? str "") (fail))
+ ((< (string-length str) min) (fail))
+ (else
+ (values (token-add tokens str)
+ (move-cursor-by cursor (string-length str))))))))
+
+(define (lex-char char-set)
+ "Lex exactly one character in the given CHAR-SET."
+ (lambda (tokens cursor)
+ (let ((chr (string-ref (cursor-text cursor) (cursor-position cursor))))
+ (if (char-set-contains? char-set chr)
+ (values (token-add tokens (string chr))
+ (move-cursor-by cursor 1))
+ (fail)))))
(define lex-whitespace
(lex-char-set char-set:whitespace))
@@ -370,3 +384,22 @@ itself."
(list tag (token-peek result)))
remainder)
(fail)))))
+
+(define (lex-group lexer)
+ "Group the elements returned by LEXER under a single token. LEXER must return
+a list of strings, with no tags."
+ (lambda (tokens cursor)
+ (let-values (((result remainder) (lexer empty-tokens cursor)))
+ (if result
+ (values (token-add tokens (apply string-append (tokens->list result)))
+ remainder)
+ (fail)))))
+
+(define (lex-peek lexer)
+ "Runs a lexer on the rest of the string, but does not advance the token. Fails
+if LEXER failed, succeeds otherwise"
+ (lambda (tokens cursor)
+ (let-values (((result remainder) (lexer empty-tokens cursor)))
+ (if result
+ (values tokens cursor)
+ (fail)))))