First Parser

I’ve been trying to learn how to use the PLT Scheme parser-tools collection. As a learning exercise I’ve written a small parser and lexer.

The parser will read in a file with the format of the named.conf configuration files used by the Unix DNS daemon Bind. They look (in part) like this:

zone "" IN {
	type master;
	file "zone/";
	allow-update {;

And it will output it as an s-expression that looks like this:

((zone  |""|  |IN|
 ((type master)
 (file |"zone/"|)

Here is the code for the parser and lexer:

(require (lib "" "parser-tools")
         (lib "" "parser-tools")
         (lib "" "syntax"))

(define-tokens value-tokens (STRING))
(define-empty-tokens stanza-tokens (OB CB SEMI EOF))

 (lower-letter (- "a" "z"))
 (upper-letter (- #A #Z))
 (digit (- "0" "9"))
 (string (+ (: lower-letter upper-letter digit "." "-" "_" )))
 (qstring (@ #\" (+ (^ #\")) #\"))

(define confl
   ((eof) 'EOF)
   ((: #tab #space #newline) (confl input-port))
   ("{" 'OB)
   ("}" 'CB)
   (";" 'SEMI)
   (qstring (token-STRING (string->symbol lexeme)))
   (string (token-STRING (string->symbol lexeme)))))

(define confp
   (start start)
   (end EOF)
   (tokens value-tokens stanza-tokens)
   (error (lambda (a b c) (void)))


    (start ((statement_list) $1))
     ((OB statement_list CB)  (list $2)))
     ((string) (list $1) )
     ((block) $1))
     ((element) $1)
     ((element_list element) (append $1 $2)))
     ((element_list SEMI) (list $1)))
     ((statement) $1)
     ((statement_list statement) (append $1 $2))))))

(define runp
  (lambda () (confp (lambda () (confl (current-input-port))))))

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s