1# -*- text -*-
2#
3# Parsing Expression Grammar declaring a syntax for Parsing Expression
4# Grammars, to use in a PEG-based parser generator. This specification
5# is self-referential, it uses the grammar described by to describe
6# said grammar.
7
8PEG pg::peg::grammar (Grammar)
9
10	# --------------------------------------------------------------------
11        # Syntactical constructs
12
13        Grammar         <- SPACE Header Definition+ Final EOF ;
14
15        Header          <- PEG Identifier StartExpr ;
16        Definition      <- Attribute? Identifier IS Expression SEMICOLON ;
17        Attribute       <- (VOID / LEAF / MATCH) COLON ;
18        Expression      <- Sequence (SLASH Sequence)* ;
19        Sequence        <- Prefix+ ;
20        Prefix          <- (AND / NOT)? Suffix ;
21        Suffix          <- Primary (QUESTION / STAR / PLUS)? ;
22        Primary         <- ALNUM / ALPHA / Identifier
23                        /  OPEN Expression CLOSE
24                        /  Literal
25                        /  Class
26                        /  DOT
27                        ;
28        Literal         <- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH  SPACE
29                        /  DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH SPACE ;
30        Class           <- OPENB (!CLOSEB Range)* CLOSEB SPACE ;
31        Range           <- Char TO Char / Char ;
32
33        StartExpr       <- OPEN Expression CLOSE ;
34void:   Final           <- END SEMICOLON SPACE ;
35
36        # --------------------------------------------------------------------
37        # Lexing constructs
38
39        Identifier      <- Ident SPACE ;
40match:  Ident           <- ('_' / ':' / <alpha>) ('_' / ':' / <alnum>)* ;
41        Char            <- CharSpecial / CharOctalFull / CharOctalPart
42                        /  CharUnicode / CharUnescaped
43                        ;
44
45match:  CharSpecial     <- "\\" [nrt'"\[\]\\] ;
46match:  CharOctalFull   <- "\\" [0-2][0-7][0-7] ;
47match:  CharOctalPart   <- "\\" [0-7][0-7]? ;
48match:  CharUnicode     <- "\\" 'u' HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
49match:  CharUnescaped   <- !"\\" . ;
50
51void:   HexDigit        <- [0-9a-fA-F] ;
52
53void:   TO              <- '-'           ;
54void:   OPENB           <- "["           ;
55void:   CLOSEB          <- "]"           ;
56void:   APOSTROPH       <- "'"           ;
57void:   DAPOSTROPH      <- '"'           ;
58void:   PEG             <- "PEG"   SPACE ;
59void:   IS              <- "<-"    SPACE ;
60leaf:   VOID            <- "void"  SPACE ; # Implies that definition has no semantic value.
61leaf:   LEAF            <- "leaf"  SPACE ; # Implies that definition has no terminals.
62leaf:   MATCH           <- "match" SPACE ; # Implies that semantic value is the matched string,
63                                           # not the parse tree from the symbol.
64void:   END             <- "END"   SPACE ;
65void:   SEMICOLON       <- ";"     SPACE ;
66void:   COLON           <- ":"     SPACE ;
67void:   SLASH           <- "/"     SPACE ;
68leaf:   AND             <- "&"     SPACE ;
69leaf:   NOT             <- "!"     SPACE ;
70leaf:   QUESTION        <- "?"     SPACE ;
71leaf:   STAR            <- "*"     SPACE ;
72leaf:   PLUS            <- "+"     SPACE ;
73void:   OPEN            <- "("     SPACE ;
74void:   CLOSE           <- ")"     SPACE ;
75leaf:   DOT             <- "."     SPACE ;
76leaf:   ALPHA           <- "<alpha>" SPACE ;
77leaf:   ALNUM           <- "<alnum>" SPACE ;
78
79void:   SPACE           <- (" " / "\t" / EOL / COMMENT)* ;
80void:   COMMENT         <- '#' (!EOL .)* EOL ;
81void:   EOL             <- "\n\r" / "\n" / "\r" ;
82void:   EOF             <- !. ;
83
84        # --------------------------------------------------------------------
85END;
86
87