public
Description: An implementation of markdown in C, using a PEG grammar
Clone URL: git://github.com/jgm/peg-markdown.git
peg-markdown / peg-0.1.4 / peg.peg
100644 78 lines (71 sloc) 3.022 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# PE Grammar for PE Grammars
#
# Adapted from [1] by Ian Piumarta <first-name at last-name point com>.
#
# Local modifications (marked '#ikp') to support:
# C text in '{ ... }' copied verbatim to output as 'semantic action'
# input consumed between '<' and '>' is 'char yytext[]' in semantic actions
#
# Best viewed using 140 columns monospaced with tabs every 8.
#
# [1] Bryan Ford. "Parsing Expression Grammars: A Recognition-Based Syntactic
# Foundation." Symposium on Principles of Programming Languages,
# January 14--16, 2004, Venice, Italy.
#
# Last edited: 2007-05-15 10:32:44 by piumarta on emilia
 
# Hierarchical syntax
 
Grammar    <- Spacing Definition+ EndOfFile
 
Definition  <- Identifier       { if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); }
     LEFTARROW Expression  { Node *e= pop(); Rule_setExpression(pop(), e); } &{ YYACCEPT }
Expression  <- Sequence (SLASH Sequence  { Node *f= pop(); push(Alternate_append(pop(), f)); }
       )*
Sequence  <- Prefix (Prefix    { Node *f= pop(); push(Sequence_append(pop(), f)); }  #ikp expanded from 'Seq <- Prefix*'
       )*
     /         { push(makePredicate("1")); }        #ikp added
Prefix    <- AND Action      { push(makePredicate(yytext)); }  #ikp added
     / AND Suffix      { push(makePeekFor(pop())); }    #ikp expanded from 'Prefix <- (AND/NOT)? Suffix'
     / NOT Suffix      { push(makePeekNot(pop())); }
     / Suffix
Suffix    <- Primary (QUESTION    { push(makeQuery(pop())); }
       / STAR    { push(makeStar (pop())); }
       / PLUS    { push(makePlus (pop())); }
       )?
Primary    <- Identifier !LEFTARROW  { push(makeName(findRule(yytext))); }
     / OPEN Expression CLOSE
     / Literal      { push(makeString(yytext)); }
     / Class      { push(makeClass(yytext)); }
     / DOT        { push(makeDot()); }
     / Action      { push(makeAction(yytext)); }    #ikp added
     / BEGIN      { push(makePredicate("YY_BEGIN")); }  #ikp added
     / END        { push(makePredicate("YY_END")); }  #ikp added
 
# Lexical syntax
 
Identifier  <- < IdentStart IdentCont* > Spacing    #ikp inserted < ... >
IdentStart  <- [a-zA-Z_]
IdentCont  <- IdentStart / [0-9]
Literal    <- ['] < (!['] Char )* > ['] Spacing    #ikp inserted < ... >
     / ["] < (!["] Char )* > ["] Spacing    #ikp inserted < ... >
Class    <- '[' < (!']' Range)* > ']' Spacing    #ikp inserted < ... >
Range    <- Char '-' Char / Char
Char    <- '\\' [abefnrtv'"\[\]\\]      #ikp added missing ANSI escapes: abefv
     / '\\' [0-3][0-7][0-7]
     / '\\' [0-7][0-7]?
     / '\\' '-'          #ikp added
     / !'\\' .
LEFTARROW  <- '<-' Spacing
SLASH    <- '/' Spacing
AND    <- '&' Spacing
NOT    <- '!' Spacing
QUESTION  <- '?' Spacing
STAR    <- '*' Spacing
PLUS    <- '+' Spacing
OPEN    <- '(' Spacing
CLOSE    <- ')' Spacing
DOT    <- '.' Spacing
Spacing    <- (Space / Comment)*
Comment    <- '#' (!EndOfLine .)* EndOfLine
Space    <- ' ' / '\t' / EndOfLine
EndOfLine  <- '\r\n' / '\n' / '\r'
EndOfFile  <- !.
 
Action    <- '{' < [^}]* > '}' Spacing    #ikp added
BEGIN    <- '<' Spacing        #ikp added
END    <- '>' Spacing        #ikp added