# 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