aa67aa0ba570c0a8d802ff357cfb0fe63cb09547
[cl-opossum.git] / opossum.peg
blobaa67aa0ba570c0a8d802ff357cfb0fe63cb09547
1 ## -*- mode: peg -*-
2 ## $Id$ 
3 ## PEG syntax in PEG as in the original report
5 # Process this file with an existing peg parser to bootstrap.
6 # The output needs to be adjusted by replacing the package OPOSSUM
7 # by OPOSSUM-SYSTEM if you want to use it as a replacement of
8 # the shipped pegparser-boot.lisp
10 # This fie needs a cleanup wrt. linebreaks once we bootstrapped off
11 # the metapeg parser which is crippled.
13 # Hierarchical syntax
14 PEG-Grammar <- Spacing Definition+ EndOfFile {
15         `((eval-when (:compile-toplevel :load-toplevel :execute)        
16           (declaim (optimize (speed 0) (safety 3) (debug 3))))
17           (defun opossum-parser ()
18             (let ((*context* (make-instance 'context :start-index 0))) #'
19               (funcall (|PEG-Grammar|) 0)))
20            ,@(second data))
21         }
23 Definition <- Identifier LEFTARROW Expression {
24         `(,(opossum::make-name (first data)) #'(lambda () ,(third data))) ;'
25         } 
27 Expression <- Sequence (SLASH Sequence)* { (if (null (second data))
28                                                (first data)
29                                                (let ((tail (second (cadr data))))
30                                                   (if (equal (first tail) 'seq) 
31                                                       `(seq ,(first data) ,@(rest tail))
32                                                       `(seq ,(first data) ,tail)))) ;'
33          }
35 Sequence <- Prefix* { `(many ,(first data)) }
37 Prefix <-   (AND Suffix) {
38          `(follow ,(second data)) 
39                 } / (NOT Suffix) {
40          `(negate ,(second data))
41          }
43 Suffix <-   Primary QUESTION { `(optional ,(first data))
44         } / Primary STAR     { `(many ,(first data)) 
45         } / Primary PLUS     { `(many1 ,(first data)) }
47 Primary <- Identifier !LEFTARROW { (first data)
48         } / OPEN Expression CLOSE { (second data) 
49         } / Literal            { (first data) 
50         } / Class              { (first data) 
51         } / DOT                { `(match-any-char ,data) }
53 # Lexical syntax
54 Identifier <- [a-zA-Z_] [a-zA-Z0-9_]* Spacing { (concatenate 'string (first data) (second data)) } 
56 Literal    <-     ['] (!['] Char)* ['] Spacing { 
57                 (second data)
58               } / ["] (!["] Char)* ["] Spacing  {
59                 (second data)   }
60 # "
61 Class      <- "[" (!"]" Range)* "]" Spacing { (second data) }
62
63 Range <-     Char "-" Char     { 
64           `(match-char-range ,(first data) ,(third data))
65          } / Char              { (first data) }
66 # FIXME: needs to be repaired when metapeg traces are gone
67 Char <-     "\\" [nrt'"]           { data
68         } / "\\["                  { data 
69         } / "\\]"                  { data
70         } / "\\\\"                 { data
71         } / "\\" [0-2] [0-7] [0-7]  { `(match-octal-char-code ,(second data) ,(third data) ,(fourth data))
72         } / "\\" [0-7] [0-7]?       { 
73           (if (third data)
74                  `(match-octal-char-code 0 ,(second data) ,(third data))
75                  `(match-octal-char-code 0 0 ,(second data)))
76         } / !"\\" .                { (last data) }
79 LEFTARROW <- "<-" Spacing { (first data) }
80 SLASH     <- "/"  Spacing { (first data) }
81 AND       <- "&"  Spacing { (first data) }
82 NOT       <- "!"  Spacing { (first data) }
83 QUESTION  <- "?"  Spacing { (first data) }
84 STAR      <- "*"  Spacing { (first data) }
85 PLUS      <- "+"  Spacing { (first data) }
86 OPEN      <- "("  Spacing { (first data) }
87 CLOSE     <- ")"  Spacing { (first data) }
88 DOT       <- "."  Spacing { (first data) }
89 Spacing   <- (Space / Comment)*
90 Comment   <- "#" (!EndOfLine .)* EndOfLine
91 Space     <- " " / "\t" / EndOfLine
92 EndOfLine <- "\r\n" / "\n" / "\r"
93 EndOfFile <- !.