Codebase list golang-github-pointlander-peg / fresh-snapshots/main peg.peg
fresh-snapshots/main

Tree @fresh-snapshots/main (Download .tar.gz)

peg.peg @fresh-snapshots/mainraw · history · blame

# PE Grammar for PE Grammars
#
# Adapted from [1] by Ian Piumarta <first-name at last-name point com>.
#
# 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.

package main

import "github.com/pointlander/peg/tree"

# parser declaration

type Peg Peg {
 *tree.Tree
}

# Hierarchical syntax
Grammar		<- Spacing 'package' MustSpacing Identifier      { p.AddPackage(text) }
			   Import*
                           'type' MustSpacing Identifier         { p.AddPeg(text) }
                           'Peg' Spacing Action              { p.AddState(text) }
                           Definition+ EndOfFile

Import		<- 'import' Spacing (MultiImport / SingleImport) Spacing
SingleImport	<- ImportName 
MultiImport	<- '(' Spacing (ImportName '\n' Spacing)* Spacing ')' 

ImportName	<- ["] < [0-9a-zA-Z_/.\-]+ > ["]	{ p.AddImport(text) }

Definition	<- Identifier 			{ p.AddRule(text) }
		     LeftArrow Expression 	{ p.AddExpression() } &(Identifier LeftArrow / !.)
Expression	<- Sequence (Slash Sequence	{ p.AddAlternate() }
			    )* (Slash           { p.AddNil(); p.AddAlternate() }
                               )?
                 /				{ p.AddNil() }
Sequence	<- Prefix (Prefix		{ p.AddSequence() }
			  )*
Prefix		<- And Action			{ p.AddPredicate(text) }
		 / Not Action			{ p.AddStateChange(text) }
		 / And Suffix			{ p.AddPeekFor() }
		 / Not Suffix			{ p.AddPeekNot() }
		 /     Suffix
Suffix          <- Primary (Question            { p.AddQuery() }
                           / Star               { p.AddStar() }
                           / Plus               { p.AddPlus() }
                           )?
Primary	        <- Identifier !LeftArrow        { p.AddName(text) }
                 / Open Expression Close
                 / Literal
                 / Class
                 / Dot                          { p.AddDot() }
                 / Action                       { p.AddAction(text) }
                 / Begin Expression End         { p.AddPush() }

# Lexical syntax

#PrivateIdentifier <- < [a-z_] IdentCont* > Spacing
Identifier	<- < IdentStart IdentCont* > Spacing
IdentStart	<- [[a-z_]]
IdentCont	<- IdentStart / [0-9]
Literal		<- ['] (!['] Char)? (!['] Char                { p.AddSequence() }
                                    )* ['] Spacing
		 / ["] (!["] DoubleChar)? (!["] DoubleChar    { p.AddSequence() }
                                          )* ["] Spacing
Class		<- ( '[[' ( '^' DoubleRanges              { p.AddPeekNot(); p.AddDot(); p.AddSequence() }
                          / DoubleRanges )?
                     ']]'
                   / '[' ( '^' Ranges                     { p.AddPeekNot(); p.AddDot(); p.AddSequence() }
                         / Ranges )?
                     ']' )
                   Spacing
Ranges		<- !']' Range (!']' Range  { p.AddAlternate() }
                              )*
DoubleRanges	<- !']]' DoubleRange (!']]' DoubleRange  { p.AddAlternate() }
                                     )*
Range		<- Char '-' Char              { p.AddRange() }
                 / Char
DoubleRange	<- Char '-' Char              { p.AddDoubleRange() }
                 / DoubleChar
Char            <- Escape
                 / !'\\' <.>                  { p.AddCharacter(text) }
DoubleChar	<- Escape
		 / <[a-zA-Z]>                 { p.AddDoubleCharacter(text) }
                 / !'\\' <.>                  { p.AddCharacter(text) }
Escape          <- "\\a"                      { p.AddCharacter("\a") }   # bell
                 / "\\b"                      { p.AddCharacter("\b") }   # bs
                 / "\\e"                      { p.AddCharacter("\x1B") } # esc
                 / "\\f"                      { p.AddCharacter("\f") }   # ff
                 / "\\n"                      { p.AddCharacter("\n") }   # nl
                 / "\\r"                      { p.AddCharacter("\r") }   # cr
                 / "\\t"                      { p.AddCharacter("\t") }   # ht
                 / "\\v"                      { p.AddCharacter("\v") }   # vt
                 / "\\'"		      { p.AddCharacter("'") }
                 / '\\"'		      { p.AddCharacter("\"") }
                 / '\\['                      { p.AddCharacter("[") }
                 / '\\]'                      { p.AddCharacter("]") }
                 / '\\-'                      { p.AddCharacter("-") }
                 / '\\' "0x"<[0-9a-fA-F]+>     { p.AddHexaCharacter(text) }
                 / '\\' <[0-3][0-7][0-7]>     { p.AddOctalCharacter(text) }
                 / '\\' <[0-7][0-7]?>         { p.AddOctalCharacter(text) }
                 / '\\\\'                     { p.AddCharacter("\\") }
LeftArrow	<- ('<-' / '\0x2190') Spacing
Slash		<- '/' Spacing
And		<- '&' Spacing
Not		<- '!' Spacing
Question	<- '?' Spacing
Star		<- '*' Spacing
Plus		<- '+' Spacing
Open		<- '(' Spacing
Close		<- ')' Spacing
Dot		<- '.' Spacing
SpaceComment	<- (Space / Comment)
Spacing		<- SpaceComment*
MustSpacing	<- SpaceComment+
Comment		<- ('#' / '//') (!EndOfLine .)* EndOfLine
Space		<- ' ' / '\t' / EndOfLine
EndOfLine	<- '\r\n' / '\n' / '\r'
EndOfFile	<- !.
Action		<- '{' < ActionBody* > '}' Spacing
ActionBody	<- [^{}] / '{' ActionBody* '}'
Begin		<- '<' Spacing
End		<- '>' Spacing