From 2e3618d4b01d741c5af6fc4574d8f669fecd7a26 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Tue, 4 Mar 2014 11:35:26 +0800 Subject: [PATCH 01/13] Initial LEG Declaration support --- Makefile | 12 +- bootstrap/leg/leg.go | 1 + bootstrap/leg/main.go | 734 +++++++++++++++++++ bootstrap/leg/set.go | 1 + bootstrap/main.go | 733 ------------------- bootstrap/peg.go | 1 - bootstrap/set.go | 1 - leg.go | 1549 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 2293 insertions(+), 739 deletions(-) create mode 120000 bootstrap/leg/leg.go create mode 100644 bootstrap/leg/main.go create mode 120000 bootstrap/leg/set.go delete mode 100644 bootstrap/main.go delete mode 120000 bootstrap/peg.go delete mode 120000 bootstrap/set.go create mode 100644 leg.go diff --git a/Makefile b/Makefile index 48fe55c..7863c29 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,13 @@ peg: bootstrap.peg.go peg.go main.go go build -bootstrap.peg.go: bootstrap/main.go peg.go - cd bootstrap; go build - bootstrap/bootstrap +bootstrap.peg.go: bootstrap/peg/main.go peg.go + cd bootstrap/peg; go build + bootstrap/peg/peg + +bootstrap.leg.go: bootstrap/leg/main.go leg.go + cd bootstrap/leg; go build + bootstrap/leg/leg clean: - rm -f bootstrap/bootstrap peg peg.peg.go + rm -f bootstrap/peg/peg bootstrap/leg/leg peg peg.peg.go diff --git a/bootstrap/leg/leg.go b/bootstrap/leg/leg.go new file mode 120000 index 0000000..46c40ef --- /dev/null +++ b/bootstrap/leg/leg.go @@ -0,0 +1 @@ +../../leg.go \ No newline at end of file diff --git a/bootstrap/leg/main.go b/bootstrap/leg/main.go new file mode 100644 index 0000000..c3958a2 --- /dev/null +++ b/bootstrap/leg/main.go @@ -0,0 +1,734 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "runtime" +) + +func main() { + runtime.GOMAXPROCS(2) + t := New(true, true) + + /*package main + type Peg Peg { + *Tree + }*/ + t.AddPackage("main") + t.AddLeg("Leg") + t.AddState(` + *Tree +`) + t.AddDeclaration("\n//This is a declaration test\n") + + /* Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } + 'type' Spacing Identifier { p.AddPeg(buffer[begin:end]) } + 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } + Definition+ EndOfFile */ + t.AddRule("Grammar") + t.AddName("Spacing") + t.AddCharacter(`p`) + t.AddCharacter(`a`) + t.AddSequence() + t.AddCharacter(`c`) + t.AddSequence() + t.AddCharacter(`k`) + t.AddSequence() + t.AddCharacter(`a`) + t.AddSequence() + t.AddCharacter(`g`) + t.AddSequence() + t.AddCharacter(`e`) + t.AddSequence() + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddName("Identifier") + t.AddSequence() + t.AddAction(" p.AddPackage(buffer[begin:end]) ") + t.AddSequence() + t.AddCharacter(`t`) + t.AddCharacter(`y`) + t.AddSequence() + t.AddCharacter(`p`) + t.AddSequence() + t.AddCharacter(`e`) + t.AddSequence() + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddName("Identifier") + t.AddSequence() + t.AddAction(" p.AddPeg(buffer[begin:end]) ") + t.AddSequence() + t.AddCharacter(`P`) + t.AddCharacter(`e`) + t.AddSequence() + t.AddCharacter(`g`) + t.AddSequence() + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddName("Action") + t.AddSequence() + t.AddAction(" p.AddState(buffer[begin:end]) ") + t.AddSequence() + t.AddName("Definition") + t.AddPlus() + t.AddSequence() + t.AddName("EndOfFile") + t.AddSequence() + t.AddExpression() + + /* Definition <- Identifier { p.AddRule(buffer[begin:end]) } + LeftArrow Expression { p.AddExpression() } &(Identifier LeftArrow / !.)*/ + t.AddRule("Definition") + t.AddName("Identifier") + t.AddAction(" p.AddRule(buffer[begin:end]) ") + t.AddSequence() + t.AddName("LeftArrow") + t.AddSequence() + t.AddName("Expression") + t.AddSequence() + t.AddAction(" p.AddExpression() ") + t.AddSequence() + t.AddName("Identifier") + t.AddName("LeftArrow") + t.AddSequence() + t.AddDot() + t.AddPeekNot() + t.AddAlternate() + t.AddPeekFor() + t.AddSequence() + t.AddExpression() + + /* Expression <- Sequence (Slash Sequence { p.AddAlternate() } + )* (Slash { p.AddNil(); p.AddAlternate() } + )? + / { p.AddNil() } */ + t.AddRule("Expression") + t.AddName("Sequence") + t.AddName("Slash") + t.AddName("Sequence") + t.AddSequence() + t.AddAction(" p.AddAlternate() ") + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddName("Slash") + t.AddAction(" p.AddNil(); p.AddAlternate() ") + t.AddSequence() + t.AddQuery() + t.AddSequence() + t.AddAction(" p.AddNil() ") + t.AddAlternate() + t.AddExpression() + + /* Sequence <- Prefix (Prefix { p.AddSequence() } + )* */ + t.AddRule("Sequence") + t.AddName("Prefix") + t.AddName("Prefix") + t.AddAction(" p.AddSequence() ") + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddExpression() + + /* Prefix <- And Action { p.AddPredicate(buffer[begin:end]) } + / And Suffix { p.AddPeekFor() } + / Not Suffix { p.AddPeekNot() } + / Suffix */ + t.AddRule("Prefix") + t.AddName("And") + t.AddName("Action") + t.AddSequence() + t.AddAction(" p.AddPredicate(buffer[begin:end]) ") + t.AddSequence() + t.AddName("And") + t.AddName("Suffix") + t.AddSequence() + t.AddAction(" p.AddPeekFor() ") + t.AddSequence() + t.AddAlternate() + t.AddName("Not") + t.AddName("Suffix") + t.AddSequence() + t.AddAction(" p.AddPeekNot() ") + t.AddSequence() + t.AddAlternate() + t.AddName("Suffix") + t.AddAlternate() + t.AddExpression() + + /* Suffix <- Primary (Question { p.AddQuery() } + / Star { p.AddStar() } + / Plus { p.AddPlus() } + )? */ + t.AddRule("Suffix") + t.AddName("Primary") + t.AddName("Question") + t.AddAction(" p.AddQuery() ") + t.AddSequence() + t.AddName("Star") + t.AddAction(" p.AddStar() ") + t.AddSequence() + t.AddAlternate() + t.AddName("Plus") + t.AddAction(" p.AddPlus() ") + t.AddSequence() + t.AddAlternate() + t.AddQuery() + t.AddSequence() + t.AddExpression() + + /* Primary <- Identifier !LeftArrow { p.AddName(buffer[begin:end]) } + / Open Expression Close + / Literal + / Class + / Dot { p.AddDot() } + / Action { p.AddAction(buffer[begin:end]) } + / Begin Expression End { p.AddPush() }*/ + t.AddRule("Primary") + t.AddName("Identifier") + t.AddName("LeftArrow") + t.AddPeekNot() + t.AddSequence() + t.AddAction(" p.AddName(buffer[begin:end]) ") + t.AddSequence() + t.AddName("Open") + t.AddName("Expression") + t.AddSequence() + t.AddName("Close") + t.AddSequence() + t.AddAlternate() + t.AddName("Literal") + t.AddAlternate() + t.AddName("Class") + t.AddAlternate() + t.AddName("Dot") + t.AddAction(" p.AddDot() ") + t.AddSequence() + t.AddAlternate() + t.AddName("Action") + t.AddAction(" p.AddAction(buffer[begin:end]) ") + t.AddSequence() + t.AddAlternate() + t.AddName("Begin") + t.AddName("Expression") + t.AddSequence() + t.AddName("End") + t.AddSequence() + t.AddAction(" p.AddPush() ") + t.AddSequence() + t.AddAlternate() + t.AddExpression() + + /* Identifier <- < IdentStart IdentCont* > Spacing */ + t.AddRule("Identifier") + t.AddName("IdentStart") + t.AddName("IdentCont") + t.AddStar() + t.AddSequence() + t.AddPush() + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* IdentStart <- [[a-z_]] */ + t.AddRule("IdentStart") + t.AddCharacter(`a`) + t.AddCharacter(`z`) + t.AddDoubleRange() + t.AddCharacter(`_`) + t.AddAlternate() + t.AddExpression() + + /* IdentCont <- IdentStart / [0-9] */ + t.AddRule("IdentCont") + t.AddName("IdentStart") + t.AddCharacter(`0`) + t.AddCharacter(`9`) + t.AddRange() + t.AddAlternate() + t.AddExpression() + + /* Literal <- ['] (!['] Char)? (!['] Char { p.AddSequence() } + )* ['] Spacing + / ["] (!["] DoubleChar)? (!["] DoubleChar { p.AddSequence() } + )* ["] Spacing */ + t.AddRule("Literal") + t.AddCharacter(`'`) + t.AddCharacter(`'`) + t.AddPeekNot() + t.AddName("Char") + t.AddSequence() + t.AddQuery() + t.AddSequence() + t.AddCharacter(`'`) + t.AddPeekNot() + t.AddName("Char") + t.AddSequence() + t.AddAction(` p.AddSequence() `) + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddCharacter(`'`) + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddCharacter(`"`) + t.AddCharacter(`"`) + t.AddPeekNot() + t.AddName("DoubleChar") + t.AddSequence() + t.AddQuery() + t.AddSequence() + t.AddCharacter(`"`) + t.AddPeekNot() + t.AddName("DoubleChar") + t.AddSequence() + t.AddAction(` p.AddSequence() `) + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddCharacter(`"`) + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddAlternate() + t.AddExpression() + + /* Class <- ( '[[' ( '^' DoubleRanges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } + / DoubleRanges )? + ']]' + / '[' ( '^' Ranges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } + / Ranges )? + ']' ) + Spacing */ + t.AddRule("Class") + t.AddCharacter(`[`) + t.AddCharacter(`[`) + t.AddSequence() + t.AddCharacter(`^`) + t.AddName("DoubleRanges") + t.AddSequence() + t.AddAction(` p.AddPeekNot(); p.AddDot(); p.AddSequence() `) + t.AddSequence() + t.AddName("DoubleRanges") + t.AddAlternate() + t.AddQuery() + t.AddSequence() + t.AddCharacter(`]`) + t.AddCharacter(`]`) + t.AddSequence() + t.AddSequence() + t.AddCharacter(`[`) + t.AddCharacter(`^`) + t.AddName("Ranges") + t.AddSequence() + t.AddAction(` p.AddPeekNot(); p.AddDot(); p.AddSequence() `) + t.AddSequence() + t.AddName("Ranges") + t.AddAlternate() + t.AddQuery() + t.AddSequence() + t.AddCharacter(`]`) + t.AddSequence() + t.AddAlternate() + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Ranges <- !']' Range (!']' Range { p.AddAlternate() } + )* */ + t.AddRule("Ranges") + t.AddCharacter(`]`) + t.AddPeekNot() + t.AddName("Range") + t.AddSequence() + t.AddCharacter(`]`) + t.AddPeekNot() + t.AddName("Range") + t.AddSequence() + t.AddAction(" p.AddAlternate() ") + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddExpression() + + /* DoubleRanges <- !']]' DoubleRange (!']]' DoubleRange { p.AddAlternate() } + )* */ + t.AddRule("DoubleRanges") + t.AddCharacter(`]`) + t.AddCharacter(`]`) + t.AddSequence() + t.AddPeekNot() + t.AddName("DoubleRange") + t.AddSequence() + t.AddCharacter(`]`) + t.AddCharacter(`]`) + t.AddSequence() + t.AddPeekNot() + t.AddName("DoubleRange") + t.AddSequence() + t.AddAction(" p.AddAlternate() ") + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddExpression() + + /* Range <- Char '-' Char { p.AddRange() } + / Char */ + t.AddRule("Range") + t.AddName("Char") + t.AddCharacter(`-`) + t.AddSequence() + t.AddName("Char") + t.AddSequence() + t.AddAction(" p.AddRange() ") + t.AddSequence() + t.AddName("Char") + t.AddAlternate() + t.AddExpression() + + /* DoubleRange <- Char '-' Char { p.AddDoubleRange() } + / DoubleChar */ + t.AddRule("DoubleRange") + t.AddName("Char") + t.AddCharacter(`-`) + t.AddSequence() + t.AddName("Char") + t.AddSequence() + t.AddAction(" p.AddDoubleRange() ") + t.AddSequence() + t.AddName("DoubleChar") + t.AddAlternate() + t.AddExpression() + + /* Char <- Escape + / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } */ + t.AddRule("Char") + t.AddName("Escape") + t.AddCharacter("\\") + t.AddPeekNot() + t.AddDot() + t.AddPush() + t.AddSequence() + t.AddAction(` p.AddCharacter(buffer[begin:end]) `) + t.AddSequence() + t.AddAlternate() + t.AddExpression() + + /* DoubleChar <- Escape + / <[a-zA-Z]> { p.AddDoubleCharacter(buffer[begin:end]) } + / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } */ + t.AddRule("DoubleChar") + t.AddName("Escape") + t.AddCharacter(`a`) + t.AddCharacter(`z`) + t.AddRange() + t.AddCharacter(`A`) + t.AddCharacter(`Z`) + t.AddRange() + t.AddAlternate() + t.AddPush() + t.AddAction(` p.AddDoubleCharacter(buffer[begin:end]) `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddPeekNot() + t.AddDot() + t.AddPush() + t.AddSequence() + t.AddAction(` p.AddCharacter(buffer[begin:end]) `) + t.AddSequence() + t.AddAlternate() + t.AddExpression() + + /* 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("-") } + / '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(buffer[begin:end]) } + / '\\' <[0-7][0-7]?> { p.AddOctalCharacter(buffer[begin:end]) } + / '\\\\' { p.AddCharacter("\\") } */ + t.AddRule("Escape") + t.AddCharacter("\\") + t.AddDoubleCharacter(`a`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\a") `) + t.AddSequence() + t.AddCharacter("\\") + t.AddDoubleCharacter(`b`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\b") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddDoubleCharacter(`e`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\x1B") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddDoubleCharacter(`f`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\f") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddDoubleCharacter(`n`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\n") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddDoubleCharacter(`r`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\r") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddDoubleCharacter(`t`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\t") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddDoubleCharacter(`v`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\v") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`'`) + t.AddSequence() + t.AddAction(` p.AddCharacter("'") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`"`) + t.AddSequence() + t.AddAction(` p.AddCharacter("\"") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`[`) + t.AddSequence() + t.AddAction(` p.AddCharacter("[") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`]`) + t.AddSequence() + t.AddAction(` p.AddCharacter("]") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`-`) + t.AddSequence() + t.AddAction(` p.AddCharacter("-") `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`0`) + t.AddCharacter(`3`) + t.AddRange() + t.AddCharacter(`0`) + t.AddCharacter(`7`) + t.AddRange() + t.AddSequence() + t.AddCharacter(`0`) + t.AddCharacter(`7`) + t.AddRange() + t.AddSequence() + t.AddPush() + t.AddSequence() + t.AddAction(` p.AddOctalCharacter(buffer[begin:end]) `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter(`0`) + t.AddCharacter(`7`) + t.AddRange() + t.AddCharacter(`0`) + t.AddCharacter(`7`) + t.AddRange() + t.AddQuery() + t.AddSequence() + t.AddPush() + t.AddSequence() + t.AddAction(` p.AddOctalCharacter(buffer[begin:end]) `) + t.AddSequence() + t.AddAlternate() + t.AddCharacter("\\") + t.AddCharacter("\\") + t.AddSequence() + t.AddAction(` p.AddCharacter("\\") `) + t.AddSequence() + t.AddAlternate() + t.AddExpression() + + /* LeftArrow <- '<-' Spacing */ + t.AddRule("LeftArrow") + t.AddCharacter(`<`) + t.AddCharacter(`-`) + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Slash <- '/' Spacing */ + t.AddRule("Slash") + t.AddCharacter(`/`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* And <- '&' Spacing */ + t.AddRule("And") + t.AddCharacter(`&`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Not <- '!' Spacing */ + t.AddRule("Not") + t.AddCharacter(`!`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Question <- '?' Spacing */ + t.AddRule("Question") + t.AddCharacter(`?`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Star <- '*' Spacing */ + t.AddRule("Star") + t.AddCharacter(`*`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Plus <- '+' Spacing */ + t.AddRule("Plus") + t.AddCharacter(`+`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Open <- '(' Spacing */ + t.AddRule("Open") + t.AddCharacter(`(`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Close <- ')' Spacing */ + t.AddRule("Close") + t.AddCharacter(`)`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Dot <- '.' Spacing */ + t.AddRule("Dot") + t.AddCharacter(`.`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Spacing <- (Space / Comment)* */ + t.AddRule("Spacing") + t.AddName("Space") + t.AddName("Comment") + t.AddAlternate() + t.AddStar() + t.AddExpression() + + /* Comment <- '#' (!EndOfLine .)* EndOfLine */ + t.AddRule("Comment") + t.AddCharacter(`#`) + t.AddName("EndOfLine") + t.AddPeekNot() + t.AddDot() + t.AddSequence() + t.AddStar() + t.AddSequence() + t.AddName("EndOfLine") + t.AddSequence() + t.AddExpression() + + /* Space <- ' ' / '\t' / EndOfLine */ + t.AddRule("Space") + t.AddCharacter(` `) + t.AddCharacter("\t") + t.AddAlternate() + t.AddName("EndOfLine") + t.AddAlternate() + t.AddExpression() + + /* EndOfLine <- '\r\n' / '\n' / '\r' */ + t.AddRule("EndOfLine") + t.AddCharacter("\r") + t.AddCharacter("\n") + t.AddSequence() + t.AddCharacter("\n") + t.AddAlternate() + t.AddCharacter("\r") + t.AddAlternate() + t.AddExpression() + + /* EndOfFile <- !. */ + t.AddRule("EndOfFile") + t.AddDot() + t.AddPeekNot() + t.AddExpression() + + /* Action <- '{' < [^}]* > '}' Spacing */ + t.AddRule("Action") + t.AddCharacter(`{`) + t.AddCharacter(`}`) + t.AddPeekNot() + t.AddDot() + t.AddSequence() + t.AddStar() + t.AddPush() + t.AddSequence() + t.AddCharacter(`}`) + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Begin <- '<' Spacing */ + t.AddRule("Begin") + t.AddCharacter(`<`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* End <- '>' Spacing */ + t.AddRule("End") + t.AddCharacter(`>`) + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + t.Compile("bootstrap.leg.go") +} diff --git a/bootstrap/leg/set.go b/bootstrap/leg/set.go new file mode 120000 index 0000000..630e9a3 --- /dev/null +++ b/bootstrap/leg/set.go @@ -0,0 +1 @@ +../../set.go \ No newline at end of file diff --git a/bootstrap/main.go b/bootstrap/main.go deleted file mode 100644 index a03aae9..0000000 --- a/bootstrap/main.go +++ /dev/null @@ -1,733 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "runtime" -) - -func main() { - runtime.GOMAXPROCS(2) - t := New(true, true) - - /*package main - type Peg Peg { - *Tree - }*/ - t.AddPackage("main") - t.AddPeg("Peg") - t.AddState(` - *Tree -`) - - /* Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } - 'type' Spacing Identifier { p.AddPeg(buffer[begin:end]) } - 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } - Definition+ EndOfFile */ - t.AddRule("Grammar") - t.AddName("Spacing") - t.AddCharacter(`p`) - t.AddCharacter(`a`) - t.AddSequence() - t.AddCharacter(`c`) - t.AddSequence() - t.AddCharacter(`k`) - t.AddSequence() - t.AddCharacter(`a`) - t.AddSequence() - t.AddCharacter(`g`) - t.AddSequence() - t.AddCharacter(`e`) - t.AddSequence() - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddName("Identifier") - t.AddSequence() - t.AddAction(" p.AddPackage(buffer[begin:end]) ") - t.AddSequence() - t.AddCharacter(`t`) - t.AddCharacter(`y`) - t.AddSequence() - t.AddCharacter(`p`) - t.AddSequence() - t.AddCharacter(`e`) - t.AddSequence() - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddName("Identifier") - t.AddSequence() - t.AddAction(" p.AddPeg(buffer[begin:end]) ") - t.AddSequence() - t.AddCharacter(`P`) - t.AddCharacter(`e`) - t.AddSequence() - t.AddCharacter(`g`) - t.AddSequence() - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddName("Action") - t.AddSequence() - t.AddAction(" p.AddState(buffer[begin:end]) ") - t.AddSequence() - t.AddName("Definition") - t.AddPlus() - t.AddSequence() - t.AddName("EndOfFile") - t.AddSequence() - t.AddExpression() - - /* Definition <- Identifier { p.AddRule(buffer[begin:end]) } - LeftArrow Expression { p.AddExpression() } &(Identifier LeftArrow / !.)*/ - t.AddRule("Definition") - t.AddName("Identifier") - t.AddAction(" p.AddRule(buffer[begin:end]) ") - t.AddSequence() - t.AddName("LeftArrow") - t.AddSequence() - t.AddName("Expression") - t.AddSequence() - t.AddAction(" p.AddExpression() ") - t.AddSequence() - t.AddName("Identifier") - t.AddName("LeftArrow") - t.AddSequence() - t.AddDot() - t.AddPeekNot() - t.AddAlternate() - t.AddPeekFor() - t.AddSequence() - t.AddExpression() - - /* Expression <- Sequence (Slash Sequence { p.AddAlternate() } - )* (Slash { p.AddNil(); p.AddAlternate() } - )? - / { p.AddNil() } */ - t.AddRule("Expression") - t.AddName("Sequence") - t.AddName("Slash") - t.AddName("Sequence") - t.AddSequence() - t.AddAction(" p.AddAlternate() ") - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddName("Slash") - t.AddAction(" p.AddNil(); p.AddAlternate() ") - t.AddSequence() - t.AddQuery() - t.AddSequence() - t.AddAction(" p.AddNil() ") - t.AddAlternate() - t.AddExpression() - - /* Sequence <- Prefix (Prefix { p.AddSequence() } - )* */ - t.AddRule("Sequence") - t.AddName("Prefix") - t.AddName("Prefix") - t.AddAction(" p.AddSequence() ") - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddExpression() - - /* Prefix <- And Action { p.AddPredicate(buffer[begin:end]) } - / And Suffix { p.AddPeekFor() } - / Not Suffix { p.AddPeekNot() } - / Suffix */ - t.AddRule("Prefix") - t.AddName("And") - t.AddName("Action") - t.AddSequence() - t.AddAction(" p.AddPredicate(buffer[begin:end]) ") - t.AddSequence() - t.AddName("And") - t.AddName("Suffix") - t.AddSequence() - t.AddAction(" p.AddPeekFor() ") - t.AddSequence() - t.AddAlternate() - t.AddName("Not") - t.AddName("Suffix") - t.AddSequence() - t.AddAction(" p.AddPeekNot() ") - t.AddSequence() - t.AddAlternate() - t.AddName("Suffix") - t.AddAlternate() - t.AddExpression() - - /* Suffix <- Primary (Question { p.AddQuery() } - / Star { p.AddStar() } - / Plus { p.AddPlus() } - )? */ - t.AddRule("Suffix") - t.AddName("Primary") - t.AddName("Question") - t.AddAction(" p.AddQuery() ") - t.AddSequence() - t.AddName("Star") - t.AddAction(" p.AddStar() ") - t.AddSequence() - t.AddAlternate() - t.AddName("Plus") - t.AddAction(" p.AddPlus() ") - t.AddSequence() - t.AddAlternate() - t.AddQuery() - t.AddSequence() - t.AddExpression() - - /* Primary <- Identifier !LeftArrow { p.AddName(buffer[begin:end]) } - / Open Expression Close - / Literal - / Class - / Dot { p.AddDot() } - / Action { p.AddAction(buffer[begin:end]) } - / Begin Expression End { p.AddPush() }*/ - t.AddRule("Primary") - t.AddName("Identifier") - t.AddName("LeftArrow") - t.AddPeekNot() - t.AddSequence() - t.AddAction(" p.AddName(buffer[begin:end]) ") - t.AddSequence() - t.AddName("Open") - t.AddName("Expression") - t.AddSequence() - t.AddName("Close") - t.AddSequence() - t.AddAlternate() - t.AddName("Literal") - t.AddAlternate() - t.AddName("Class") - t.AddAlternate() - t.AddName("Dot") - t.AddAction(" p.AddDot() ") - t.AddSequence() - t.AddAlternate() - t.AddName("Action") - t.AddAction(" p.AddAction(buffer[begin:end]) ") - t.AddSequence() - t.AddAlternate() - t.AddName("Begin") - t.AddName("Expression") - t.AddSequence() - t.AddName("End") - t.AddSequence() - t.AddAction(" p.AddPush() ") - t.AddSequence() - t.AddAlternate() - t.AddExpression() - - /* Identifier <- < IdentStart IdentCont* > Spacing */ - t.AddRule("Identifier") - t.AddName("IdentStart") - t.AddName("IdentCont") - t.AddStar() - t.AddSequence() - t.AddPush() - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* IdentStart <- [[a-z_]] */ - t.AddRule("IdentStart") - t.AddCharacter(`a`) - t.AddCharacter(`z`) - t.AddDoubleRange() - t.AddCharacter(`_`) - t.AddAlternate() - t.AddExpression() - - /* IdentCont <- IdentStart / [0-9] */ - t.AddRule("IdentCont") - t.AddName("IdentStart") - t.AddCharacter(`0`) - t.AddCharacter(`9`) - t.AddRange() - t.AddAlternate() - t.AddExpression() - - /* Literal <- ['] (!['] Char)? (!['] Char { p.AddSequence() } - )* ['] Spacing - / ["] (!["] DoubleChar)? (!["] DoubleChar { p.AddSequence() } - )* ["] Spacing */ - t.AddRule("Literal") - t.AddCharacter(`'`) - t.AddCharacter(`'`) - t.AddPeekNot() - t.AddName("Char") - t.AddSequence() - t.AddQuery() - t.AddSequence() - t.AddCharacter(`'`) - t.AddPeekNot() - t.AddName("Char") - t.AddSequence() - t.AddAction(` p.AddSequence() `) - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddCharacter(`'`) - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddCharacter(`"`) - t.AddCharacter(`"`) - t.AddPeekNot() - t.AddName("DoubleChar") - t.AddSequence() - t.AddQuery() - t.AddSequence() - t.AddCharacter(`"`) - t.AddPeekNot() - t.AddName("DoubleChar") - t.AddSequence() - t.AddAction(` p.AddSequence() `) - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddCharacter(`"`) - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddAlternate() - t.AddExpression() - - /* Class <- ( '[[' ( '^' DoubleRanges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } - / DoubleRanges )? - ']]' - / '[' ( '^' Ranges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } - / Ranges )? - ']' ) - Spacing */ - t.AddRule("Class") - t.AddCharacter(`[`) - t.AddCharacter(`[`) - t.AddSequence() - t.AddCharacter(`^`) - t.AddName("DoubleRanges") - t.AddSequence() - t.AddAction(` p.AddPeekNot(); p.AddDot(); p.AddSequence() `) - t.AddSequence() - t.AddName("DoubleRanges") - t.AddAlternate() - t.AddQuery() - t.AddSequence() - t.AddCharacter(`]`) - t.AddCharacter(`]`) - t.AddSequence() - t.AddSequence() - t.AddCharacter(`[`) - t.AddCharacter(`^`) - t.AddName("Ranges") - t.AddSequence() - t.AddAction(` p.AddPeekNot(); p.AddDot(); p.AddSequence() `) - t.AddSequence() - t.AddName("Ranges") - t.AddAlternate() - t.AddQuery() - t.AddSequence() - t.AddCharacter(`]`) - t.AddSequence() - t.AddAlternate() - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Ranges <- !']' Range (!']' Range { p.AddAlternate() } - )* */ - t.AddRule("Ranges") - t.AddCharacter(`]`) - t.AddPeekNot() - t.AddName("Range") - t.AddSequence() - t.AddCharacter(`]`) - t.AddPeekNot() - t.AddName("Range") - t.AddSequence() - t.AddAction(" p.AddAlternate() ") - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddExpression() - - /* DoubleRanges <- !']]' DoubleRange (!']]' DoubleRange { p.AddAlternate() } - )* */ - t.AddRule("DoubleRanges") - t.AddCharacter(`]`) - t.AddCharacter(`]`) - t.AddSequence() - t.AddPeekNot() - t.AddName("DoubleRange") - t.AddSequence() - t.AddCharacter(`]`) - t.AddCharacter(`]`) - t.AddSequence() - t.AddPeekNot() - t.AddName("DoubleRange") - t.AddSequence() - t.AddAction(" p.AddAlternate() ") - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddExpression() - - /* Range <- Char '-' Char { p.AddRange() } - / Char */ - t.AddRule("Range") - t.AddName("Char") - t.AddCharacter(`-`) - t.AddSequence() - t.AddName("Char") - t.AddSequence() - t.AddAction(" p.AddRange() ") - t.AddSequence() - t.AddName("Char") - t.AddAlternate() - t.AddExpression() - - /* DoubleRange <- Char '-' Char { p.AddDoubleRange() } - / DoubleChar */ - t.AddRule("DoubleRange") - t.AddName("Char") - t.AddCharacter(`-`) - t.AddSequence() - t.AddName("Char") - t.AddSequence() - t.AddAction(" p.AddDoubleRange() ") - t.AddSequence() - t.AddName("DoubleChar") - t.AddAlternate() - t.AddExpression() - - /* Char <- Escape - / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } */ - t.AddRule("Char") - t.AddName("Escape") - t.AddCharacter("\\") - t.AddPeekNot() - t.AddDot() - t.AddPush() - t.AddSequence() - t.AddAction(` p.AddCharacter(buffer[begin:end]) `) - t.AddSequence() - t.AddAlternate() - t.AddExpression() - - /* DoubleChar <- Escape - / <[a-zA-Z]> { p.AddDoubleCharacter(buffer[begin:end]) } - / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } */ - t.AddRule("DoubleChar") - t.AddName("Escape") - t.AddCharacter(`a`) - t.AddCharacter(`z`) - t.AddRange() - t.AddCharacter(`A`) - t.AddCharacter(`Z`) - t.AddRange() - t.AddAlternate() - t.AddPush() - t.AddAction(` p.AddDoubleCharacter(buffer[begin:end]) `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddPeekNot() - t.AddDot() - t.AddPush() - t.AddSequence() - t.AddAction(` p.AddCharacter(buffer[begin:end]) `) - t.AddSequence() - t.AddAlternate() - t.AddExpression() - - /* 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("-") } - / '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(buffer[begin:end]) } - / '\\' <[0-7][0-7]?> { p.AddOctalCharacter(buffer[begin:end]) } - / '\\\\' { p.AddCharacter("\\") } */ - t.AddRule("Escape") - t.AddCharacter("\\") - t.AddDoubleCharacter(`a`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\a") `) - t.AddSequence() - t.AddCharacter("\\") - t.AddDoubleCharacter(`b`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\b") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddDoubleCharacter(`e`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\x1B") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddDoubleCharacter(`f`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\f") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddDoubleCharacter(`n`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\n") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddDoubleCharacter(`r`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\r") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddDoubleCharacter(`t`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\t") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddDoubleCharacter(`v`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\v") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`'`) - t.AddSequence() - t.AddAction(` p.AddCharacter("'") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`"`) - t.AddSequence() - t.AddAction(` p.AddCharacter("\"") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`[`) - t.AddSequence() - t.AddAction(` p.AddCharacter("[") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`]`) - t.AddSequence() - t.AddAction(` p.AddCharacter("]") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`-`) - t.AddSequence() - t.AddAction(` p.AddCharacter("-") `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`0`) - t.AddCharacter(`3`) - t.AddRange() - t.AddCharacter(`0`) - t.AddCharacter(`7`) - t.AddRange() - t.AddSequence() - t.AddCharacter(`0`) - t.AddCharacter(`7`) - t.AddRange() - t.AddSequence() - t.AddPush() - t.AddSequence() - t.AddAction(` p.AddOctalCharacter(buffer[begin:end]) `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter(`0`) - t.AddCharacter(`7`) - t.AddRange() - t.AddCharacter(`0`) - t.AddCharacter(`7`) - t.AddRange() - t.AddQuery() - t.AddSequence() - t.AddPush() - t.AddSequence() - t.AddAction(` p.AddOctalCharacter(buffer[begin:end]) `) - t.AddSequence() - t.AddAlternate() - t.AddCharacter("\\") - t.AddCharacter("\\") - t.AddSequence() - t.AddAction(` p.AddCharacter("\\") `) - t.AddSequence() - t.AddAlternate() - t.AddExpression() - - /* LeftArrow <- '<-' Spacing */ - t.AddRule("LeftArrow") - t.AddCharacter(`<`) - t.AddCharacter(`-`) - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Slash <- '/' Spacing */ - t.AddRule("Slash") - t.AddCharacter(`/`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* And <- '&' Spacing */ - t.AddRule("And") - t.AddCharacter(`&`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Not <- '!' Spacing */ - t.AddRule("Not") - t.AddCharacter(`!`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Question <- '?' Spacing */ - t.AddRule("Question") - t.AddCharacter(`?`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Star <- '*' Spacing */ - t.AddRule("Star") - t.AddCharacter(`*`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Plus <- '+' Spacing */ - t.AddRule("Plus") - t.AddCharacter(`+`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Open <- '(' Spacing */ - t.AddRule("Open") - t.AddCharacter(`(`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Close <- ')' Spacing */ - t.AddRule("Close") - t.AddCharacter(`)`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Dot <- '.' Spacing */ - t.AddRule("Dot") - t.AddCharacter(`.`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Spacing <- (Space / Comment)* */ - t.AddRule("Spacing") - t.AddName("Space") - t.AddName("Comment") - t.AddAlternate() - t.AddStar() - t.AddExpression() - - /* Comment <- '#' (!EndOfLine .)* EndOfLine */ - t.AddRule("Comment") - t.AddCharacter(`#`) - t.AddName("EndOfLine") - t.AddPeekNot() - t.AddDot() - t.AddSequence() - t.AddStar() - t.AddSequence() - t.AddName("EndOfLine") - t.AddSequence() - t.AddExpression() - - /* Space <- ' ' / '\t' / EndOfLine */ - t.AddRule("Space") - t.AddCharacter(` `) - t.AddCharacter("\t") - t.AddAlternate() - t.AddName("EndOfLine") - t.AddAlternate() - t.AddExpression() - - /* EndOfLine <- '\r\n' / '\n' / '\r' */ - t.AddRule("EndOfLine") - t.AddCharacter("\r") - t.AddCharacter("\n") - t.AddSequence() - t.AddCharacter("\n") - t.AddAlternate() - t.AddCharacter("\r") - t.AddAlternate() - t.AddExpression() - - /* EndOfFile <- !. */ - t.AddRule("EndOfFile") - t.AddDot() - t.AddPeekNot() - t.AddExpression() - - /* Action <- '{' < [^}]* > '}' Spacing */ - t.AddRule("Action") - t.AddCharacter(`{`) - t.AddCharacter(`}`) - t.AddPeekNot() - t.AddDot() - t.AddSequence() - t.AddStar() - t.AddPush() - t.AddSequence() - t.AddCharacter(`}`) - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* Begin <- '<' Spacing */ - t.AddRule("Begin") - t.AddCharacter(`<`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - /* End <- '>' Spacing */ - t.AddRule("End") - t.AddCharacter(`>`) - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - - t.Compile("bootstrap.peg.go") -} diff --git a/bootstrap/peg.go b/bootstrap/peg.go deleted file mode 120000 index 9bf17c7..0000000 --- a/bootstrap/peg.go +++ /dev/null @@ -1 +0,0 @@ -../peg.go \ No newline at end of file diff --git a/bootstrap/set.go b/bootstrap/set.go deleted file mode 120000 index 859a172..0000000 --- a/bootstrap/set.go +++ /dev/null @@ -1 +0,0 @@ -../set.go \ No newline at end of file diff --git a/leg.go b/leg.go new file mode 100644 index 0000000..ca3f9c1 --- /dev/null +++ b/leg.go @@ -0,0 +1,1549 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "fmt" + "go/parser" + "go/printer" + "go/token" + "os" + "strconv" + "strings" + "text/template" +) + +const LEG_HEADER_TEMPLATE = `package {{.PackageName}} + +import ( + /*"bytes"*/ + "fmt" + "math" + "sort" + "strconv" +) + +const END_SYMBOL rune = {{.EndSymbol}} + +{{range .Declarations}}{{.}} +{{end}} + + +/* The rule types inferred from the grammar are below. */ +type Rule uint8 + +const ( + RuleUnknown Rule = iota + {{range .RuleNames}}Rule{{.String}} + {{end}} + RulePre_ + Rule_In_ + Rule_Suf +) + +var Rul3s = [...]string { + "Unknown", + {{range .RuleNames}}"{{.String}}", + {{end}} + "Pre_", + "_In_", + "_Suf", +} + +type TokenTree interface { + Print() + PrintSyntax() + PrintSyntaxTree(buffer string) + Add(rule Rule, begin, end, next, depth int) + Expand(index int) TokenTree + Tokens() <-chan token32 + Error() []token32 + trim(length int) +} + +{{range .Sizes}} + +/* ${@} bit structure for abstract syntax tree */ +type token{{.}} struct { + Rule + begin, end, next int{{.}} +} + +func (t *token{{.}}) isZero() bool { + return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 +} + +func (t *token{{.}}) isParentOf(u token{{.}}) bool { + return t.begin <= u.begin && t.end >= u.end && t.next > u.next +} + +func (t *token{{.}}) GetToken32() token32 { + return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} +} + +func (t *token{{.}}) String() string { + return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) +} + +type tokens{{.}} struct { + tree []token{{.}} + ordered [][]token{{.}} +} + +func (t *tokens{{.}}) trim(length int) { + t.tree = t.tree[0:length] +} + +func (t *tokens{{.}}) Print() { + for _, token := range t.tree { + fmt.Println(token.String()) + } +} + +func (t *tokens{{.}}) Order() [][]token{{.}} { + if t.ordered != nil { + return t.ordered + } + + depths := make([]int{{.}}, 1, math.MaxInt16) + for i, token := range t.tree { + if token.Rule == RuleUnknown { + t.tree = t.tree[:i] + break + } + depth := int(token.next) + if length := len(depths); depth >= length { + depths = depths[:depth + 1] + } + depths[depth]++ + } + depths = append(depths, 0) + + ordered, pool := make([][]token{{.}}, len(depths)), make([]token{{.}}, len(t.tree) + len(depths)) + for i, depth := range depths { + depth++ + ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 + } + + for i, token := range t.tree { + depth := token.next + token.next = int{{.}}(i) + ordered[depth][depths[depth]] = token + depths[depth]++ + } + t.ordered = ordered + return ordered +} + +type State{{.}} struct { + token{{.}} + depths []int{{.}} + leaf bool +} + +func (t *tokens{{.}}) PreOrder() (<-chan State{{.}}, [][]token{{.}}) { + s, ordered := make(chan State{{.}}, 6), t.Order() + go func() { + var states [8]State{{.}} + for i, _ := range states { + states[i].depths = make([]int{{.}}, len(ordered)) + } + depths, state, depth := make([]int{{.}}, len(ordered)), 0, 1 + write := func(t token{{.}}, leaf bool) { + S := states[state] + state, S.Rule, S.begin, S.end, S.next, S.leaf = (state + 1) % 8, t.Rule, t.begin, t.end, int{{.}}(depth), leaf + copy(S.depths, depths) + s <- S + } + + states[state].token{{.}} = ordered[0][0] + depths[0]++ + state++ + a, b := ordered[depth - 1][depths[depth - 1] - 1], ordered[depth][depths[depth]] + depthFirstSearch: for { + for { + if i := depths[depth]; i > 0 { + if c, j := ordered[depth][i - 1], depths[depth - 1]; a.isParentOf(c) && + (j < 2 || !ordered[depth - 1][j - 2].isParentOf(c)) { + if c.end != b.begin { + write(token{{.}} {Rule: Rule_In_, begin: c.end, end: b.begin}, true) + } + break + } + } + + if a.begin < b.begin { + write(token{{.}} {Rule: RulePre_, begin: a.begin, end: b.begin}, true) + } + break + } + + next := depth + 1 + if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { + write(b, false) + depths[depth]++ + depth, a, b = next, b, c + continue + } + + write(b, true) + depths[depth]++ + c, parent := ordered[depth][depths[depth]], true + for { + if c.Rule != RuleUnknown && a.isParentOf(c) { + b = c + continue depthFirstSearch + } else if parent && b.end != a.end { + write(token{{.}} {Rule: Rule_Suf, begin: b.end, end: a.end}, true) + } + + depth-- + if depth > 0 { + a, b, c = ordered[depth - 1][depths[depth - 1] - 1], a, ordered[depth][depths[depth]] + parent = a.isParentOf(b) + continue + } + + break depthFirstSearch + } + } + + close(s) + }() + return s, ordered +} + +func (t *tokens{{.}}) PrintSyntax() { + tokens, ordered := t.PreOrder() + max := -1 + for token := range tokens { + if !token.leaf { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i] - 1].Rule]) + } + fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) + } else if token.begin == token.end { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i] - 1].Rule]) + } + fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) + } else { + for c, end := token.begin, token.end; c < end; c++ { + if i := int(c); max + 1 < i { + for j := max; j < i; j++ { + fmt.Printf("skip %v %v\n", j, token.String()) + } + max = i + } else if i := int(c); i <= max { + for j := i; j <= max; j++ { + fmt.Printf("dupe %v %v\n", j, token.String()) + } + } else { + max = int(c) + } + fmt.Printf("%v", c) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i] - 1].Rule]) + } + fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) + } + fmt.Printf("\n") + } + } +} + +func (t *tokens{{.}}) PrintSyntaxTree(buffer string) { + tokens, _ := t.PreOrder() + for token := range tokens { + for c := 0; c < int(token.next); c++ { + fmt.Printf(" ") + } + fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) + } +} + +func (t *tokens{{.}}) Add(rule Rule, begin, end, depth, index int) { + t.tree[index] = token{{.}}{Rule: rule, begin: int{{.}}(begin), end: int{{.}}(end), next: int{{.}}(depth)} +} + +func (t *tokens{{.}}) Tokens() <-chan token32 { + s := make(chan token32, 16) + go func() { + for _, v := range t.tree { + s <- v.GetToken32() + } + close(s) + }() + return s +} + +func (t *tokens{{.}}) Error() []token32 { + ordered := t.Order() + length := len(ordered) + tokens, length := make([]token32, length), length - 1 + for i, _ := range tokens { + o := ordered[length - i] + if len(o) > 1 { + tokens[i] = o[len(o) - 2].GetToken32() + } + } + return tokens +} +{{end}} + +func (t *tokens16) Expand(index int) TokenTree { + tree := t.tree + if index >= len(tree) { + expanded := make([]token32, 2 * len(tree)) + for i, v := range tree { + expanded[i] = v.GetToken32() + } + return &tokens32{tree: expanded} + } + return nil +} + +func (t *tokens32) Expand(index int) TokenTree { + tree := t.tree + if index >= len(tree) { + expanded := make([]token32, 2 * len(tree)) + copy(expanded, tree) + t.tree = expanded + } + return nil +} + +type {{.StructName}} struct { + {{.StructVariables}} + Buffer string + buffer []rune + rules [{{.RulesCount}}]func() bool + Parse func(rule ...int) error + Reset func() + TokenTree +} + +type textPosition struct { + line, symbol int +} + +type textPositionMap map[int] textPosition + +func translatePositions(buffer string, positions []int) textPositionMap { + length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 + sort.Ints(positions) + + search: for i, c := range buffer[0:] { + if c == '\n' {line, symbol = line + 1, 0} else {symbol++} + if i == positions[j] { + translations[positions[j]] = textPosition{line, symbol} + for j++; j < length; j++ {if i != positions[j] {continue search}} + break search + } + } + + return translations +} + +type parseError struct { + p *{{.StructName}} +} + +func (e *parseError) Error() string { + tokens, error := e.p.TokenTree.Error(), "\n" + positions, p := make([]int, 2 * len(tokens)), 0 + for _, token := range tokens { + positions[p], p = int(token.begin), p + 1 + positions[p], p = int(token.end), p + 1 + } + translations := translatePositions(e.p.Buffer, positions) + for _, token := range tokens { + begin, end := int(token.begin), int(token.end) + error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", + Rul3s[token.Rule], + translations[begin].line, translations[begin].symbol, + translations[end].line, translations[end].symbol, + /*strconv.Quote(*/e.p.Buffer[begin:end]/*)*/) + } + + return error +} + +func (p *{{.StructName}}) PrintSyntaxTree() { + p.TokenTree.PrintSyntaxTree(p.Buffer) +} + +func (p *{{.StructName}}) Highlighter() { + p.TokenTree.PrintSyntax() +} + +{{if .HasActions}} +func (p *{{.StructName}}) Execute() { + buffer, begin, end := p.Buffer, 0, 0 + for token := range p.TokenTree.Tokens() { + switch (token.Rule) { + case RulePegText: + begin, end = int(token.begin), int(token.end) + {{range .Actions}}case RuleAction{{.GetId}}: + {{.String}} + {{end}} + } + } +} +{{end}} + +func (p *{{.StructName}}) Init() { + p.buffer = []rune(p.Buffer) + if len(p.buffer) == 0 || p.buffer[len(p.buffer) - 1] != END_SYMBOL { + p.buffer = append(p.buffer, END_SYMBOL) + } + + var tree TokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} + position, depth, tokenIndex, buffer, rules := 0, 0, 0, p.buffer, p.rules + + p.Parse = func(rule ...int) error { + r := 1 + if len(rule) > 0 { + r = rule[0] + } + matches := p.rules[r]() + p.TokenTree = tree + if matches { + p.TokenTree.trim(tokenIndex) + return nil + } + return &parseError{p} + } + + p.Reset = func() { + position, tokenIndex, depth = 0, 0, 0 + } + + add := func(rule Rule, begin int) { + if t := tree.Expand(tokenIndex); t != nil { + tree = t + } + tree.Add(rule, begin, position, depth, tokenIndex) + tokenIndex++ + } + + {{if .HasDot}} + matchDot := func() bool { + if buffer[position] != END_SYMBOL { + position++ + return true + } + return false + } + {{end}} + + {{if .HasCharacter}} + /*matchChar := func(c byte) bool { + if buffer[position] == c { + position++ + return true + } + return false + }*/ + {{end}} + + {{if .HasString}} + matchString := func(s string) bool { + i := position + for _, c := range s { + if buffer[i] != c { + return false + } + i++ + } + position = i + return true + } + {{end}} + + {{if .HasRange}} + /*matchRange := func(lower byte, upper byte) bool { + if c := buffer[position]; c >= lower && c <= upper { + position++ + return true + } + return false + }*/ + {{end}} + + rules = [...]func() bool { + nil,` + +type Type uint8 + +const ( + TypeUnknown Type = iota + TypeRule + TypeName + TypeDot + TypeCharacter + TypeRange + TypeString + TypePredicate + TypeCommit + TypeAction + TypePackage + TypeState + TypeAlternate + TypeUnorderedAlternate + TypeSequence + TypePeekFor + TypePeekNot + TypeQuery + TypeStar + TypePlus + TypeLeg + TypePush + TypeImplicitPush + TypeNil + TypeLast +) + +var TypeMap = [...]string{ + "TypeUnknown", + "TypeRule", + "TypeName", + "TypeDot", + "TypeCharacter", + "TypeRange", + "TypeString", + "TypePredicate", + "TypeCommit", + "TypeAction", + "TypePackage", + "TypeState", + "TypeAlternate", + "TypeUnorderedAlternate", + "TypeSequence", + "TypePeekFor", + "TypePeekNot", + "TypeQuery", + "TypeStar", + "TypePlus", + "TypeLeg", + "TypePush", + "TypeImplicitPush", + "TypeNil", + "TypeLast"} + +func (t Type) GetType() Type { + return t +} + +type Node interface { + fmt.Stringer + debug() + + Escaped() string + SetString(s string) + + GetType() Type + SetType(t Type) + + GetId() int + SetId(id int) + + Init() + Front() *node + Next() *node + PushFront(value *node) + PopFront() *node + PushBack(value *node) + Len() int + Copy() *node + Slice() []*node +} + +type node struct { + Type + string + id int + + front *node + back *node + length int + + /* use hash table here instead of Copy? */ + next *node +} + +func (n *node) String() string { + return n.string +} + +func (n *node) debug() { + if len(n.string) == 1 { + fmt.Printf("%v %v '%v' %d\n", n.id, TypeMap[n.Type], n.string, n.string[0]) + } else { + fmt.Printf("%v %v '%v'\n", n.id, TypeMap[n.Type], n.string) + } +} + +func (n *node) Escaped() string { + return escape(n.string) +} + +func (n *node) SetString(s string) { + n.string = s +} + +func (n *node) SetType(t Type) { + n.Type = t +} + +func (n *node) GetId() int { + return n.id +} + +func (n *node) SetId(id int) { + n.id = id +} + +func (n *node) Init() { + n.front = nil + n.back = nil + n.length = 0 +} + +func (n *node) Front() *node { + return n.front +} + +func (n *node) Next() *node { + return n.next +} + +func (n *node) PushFront(value *node) { + if n.back == nil { + n.back = value + } else { + value.next = n.front + } + n.front = value + n.length++ +} + +func (n *node) PopFront() *node { + front := n.front + + switch true { + case front == nil: + panic("tree is empty") + case front == n.back: + n.front, n.back = nil, nil + default: + n.front, front.next = front.next, nil + } + + n.length-- + return front +} + +func (n *node) PushBack(value *node) { + if n.front == nil { + n.front = value + } else { + n.back.next = value + } + n.back = value + n.length++ +} + +func (n *node) Len() (c int) { + return n.length +} + +func (n *node) Copy() *node { + return &node{Type: n.Type, string: n.string, id: n.id, front: n.front, back: n.back, length: n.length} +} + +func (n *node) Slice() []*node { + s := make([]*node, n.length) + for element, i := n.Front(), 0; element != nil; element, i = element.Next(), i+1 { + s[i] = element + } + return s +} + +/* A tree data structure into which a PEG can be parsed. */ +type Tree struct { + Rules map[string]Node + rulesCount map[string]uint + node + inline, _switch bool + + RuleNames []Node + Sizes [2]int + PackageName string + Declarations []string + EndSymbol rune + StructName string + StructVariables string + RulesCount int + Bits int + HasActions bool + Actions []Node + HasCommit bool + HasDot bool + HasCharacter bool + HasString bool + HasRange bool +} + +func New(inline, _switch bool) *Tree { + return &Tree{Rules: make(map[string]Node), + Sizes: [2]int{16, 32}, + rulesCount: make(map[string]uint), + inline: inline, + _switch: _switch} +} + +func (t *Tree) AddRule(name string) { + t.PushFront(&node{Type: TypeRule, string: name, id: t.RulesCount}) + t.RulesCount++ +} + +func (t *Tree) AddExpression() { + expression := t.PopFront() + rule := t.PopFront() + rule.PushBack(expression) + t.PushBack(rule) +} + +func (t *Tree) AddName(text string) { + t.PushFront(&node{Type: TypeName, string: text}) +} + +func (t *Tree) AddDot() { t.PushFront(&node{Type: TypeDot, string: "."}) } +func (t *Tree) AddCharacter(text string) { + t.PushFront(&node{Type: TypeCharacter, string: text}) +} +func (t *Tree) AddDoubleCharacter(text string) { + t.PushFront(&node{Type: TypeCharacter, string: strings.ToLower(text)}) + t.PushFront(&node{Type: TypeCharacter, string: strings.ToUpper(text)}) + t.AddAlternate() +} +func (t *Tree) AddOctalCharacter(text string) { + octal, _ := strconv.ParseInt(text, 8, 8) + t.PushFront(&node{Type: TypeCharacter, string: string(octal)}) +} +func (t *Tree) AddPredicate(text string) { t.PushFront(&node{Type: TypePredicate, string: text}) } +func (t *Tree) AddNil() { t.PushFront(&node{Type: TypeNil, string: ""}) } +func (t *Tree) AddAction(text string) { t.PushFront(&node{Type: TypeAction, string: text}) } +func (t *Tree) AddPackage(text string) { t.PushBack(&node{Type: TypePackage, string: text}) } +func (t *Tree) AddDeclaration(text string) { t.Declarations = append(t.Declarations, text) } +func (t *Tree) AddState(text string) { + leg := t.PopFront() + leg.PushBack(&node{Type: TypeState, string: text}) + t.PushBack(leg) +} + +func (t *Tree) addList(listType Type) { + a := t.PopFront() + b := t.PopFront() + var l *node + if b.GetType() == listType { + l = b + } else { + l = &node{Type: listType} + l.PushBack(b) + } + l.PushBack(a) + t.PushFront(l) +} +func (t *Tree) AddAlternate() { t.addList(TypeAlternate) } +func (t *Tree) AddSequence() { t.addList(TypeSequence) } +func (t *Tree) AddRange() { t.addList(TypeRange) } +func (t *Tree) AddDoubleRange() { + a := t.PopFront() + b := t.PopFront() + + t.AddCharacter(strings.ToLower(b.String())) + t.AddCharacter(strings.ToLower(a.String())) + t.addList(TypeRange) + + t.AddCharacter(strings.ToUpper(b.String())) + t.AddCharacter(strings.ToUpper(a.String())) + t.addList(TypeRange) + + t.AddAlternate() +} + +func (t *Tree) addFix(fixType Type) { + n := &node{Type: fixType} + n.PushBack(t.PopFront()) + t.PushFront(n) +} +func (t *Tree) AddPeekFor() { t.addFix(TypePeekFor) } +func (t *Tree) AddPeekNot() { t.addFix(TypePeekNot) } +func (t *Tree) AddQuery() { t.addFix(TypeQuery) } +func (t *Tree) AddStar() { t.addFix(TypeStar) } +func (t *Tree) AddPlus() { t.addFix(TypePlus) } +func (t *Tree) AddPush() { t.addFix(TypePush) } + +func (t *Tree) AddLeg(text string) { t.PushFront(&node{Type: TypeLeg, string: text}) } + +func join(tasks []func()) { + length := len(tasks) + done := make(chan int, length) + for _, task := range tasks { + go func(task func()) { task(); done <- 1 }(task) + } + for d := <-done; d < length; d += <-done { + } +} + +func escape(c string) string { + switch c { + case "'": + return "\\'" + case "\"": + return "\"" + default: + c = strconv.Quote(c) + return c[1 : len(c)-1] + } + return "" +} + +func (t *Tree) Compile(file string) { + t.EndSymbol = '\u0004' + t.RulesCount++ + + counts := [TypeLast]uint{} + { + var rule *node + var link func(node Node) + link = func(n Node) { + nodeType := n.GetType() + id := counts[nodeType] + counts[nodeType]++ + switch nodeType { + case TypeAction: + n.SetId(int(id)) + copy, name := n.Copy(), fmt.Sprintf("Action%v", id) + t.Actions = append(t.Actions, copy) + n.Init() + n.SetType(TypeName) + n.SetString(name) + n.SetId(t.RulesCount) + + emptyRule := &node{Type: TypeRule, string: name, id: t.RulesCount} + implicitPush := &node{Type: TypeImplicitPush} + emptyRule.PushBack(implicitPush) + implicitPush.PushBack(copy) + implicitPush.PushBack(emptyRule.Copy()) + t.PushBack(emptyRule) + t.RulesCount++ + + t.Rules[name] = emptyRule + t.RuleNames = append(t.RuleNames, emptyRule) + case TypeName: + name := n.String() + if _, ok := t.Rules[name]; !ok { + emptyRule := &node{Type: TypeRule, string: name, id: t.RulesCount} + implicitPush := &node{Type: TypeImplicitPush} + emptyRule.PushBack(implicitPush) + implicitPush.PushBack(&node{Type: TypeNil, string: ""}) + implicitPush.PushBack(emptyRule.Copy()) + t.PushBack(emptyRule) + t.RulesCount++ + + t.Rules[name] = emptyRule + t.RuleNames = append(t.RuleNames, emptyRule) + } + case TypePush: + copy, name := rule.Copy(), "PegText" + copy.SetString(name) + if _, ok := t.Rules[name]; !ok { + emptyRule := &node{Type: TypeRule, string: name, id: t.RulesCount} + emptyRule.PushBack(&node{Type: TypeNil, string: ""}) + t.PushBack(emptyRule) + t.RulesCount++ + + t.Rules[name] = emptyRule + t.RuleNames = append(t.RuleNames, emptyRule) + } + n.PushBack(copy) + fallthrough + case TypeImplicitPush: + link(n.Front()) + case TypeRule, TypeAlternate, TypeUnorderedAlternate, TypeSequence, + TypePeekFor, TypePeekNot, TypeQuery, TypeStar, TypePlus: + for _, node := range n.Slice() { + link(node) + } + } + } + /* first pass */ + for _, node := range t.Slice() { + switch node.GetType() { + case TypePackage: + t.PackageName = node.String() + case TypeLeg: + t.StructName = node.String() + t.StructVariables = node.Front().String() + case TypeRule: + if _, ok := t.Rules[node.String()]; !ok { + expression := node.Front() + copy := expression.Copy() + expression.Init() + expression.SetType(TypeImplicitPush) + expression.PushBack(copy) + expression.PushBack(node.Copy()) + + t.Rules[node.String()] = node + t.RuleNames = append(t.RuleNames, node) + } + } + } + /* second pass */ + for _, node := range t.Slice() { + if node.GetType() == TypeRule { + rule = node + link(node) + } + } + } + + join([]func(){ + func() { + var countRules func(node Node) + ruleReached := make([]bool, t.RulesCount) + countRules = func(node Node) { + switch node.GetType() { + case TypeRule: + name, id := node.String(), node.GetId() + if count, ok := t.rulesCount[name]; ok { + t.rulesCount[name] = count + 1 + } else { + t.rulesCount[name] = 1 + } + if ruleReached[id] { + return + } + ruleReached[id] = true + countRules(node.Front()) + case TypeName: + countRules(t.Rules[node.String()]) + case TypeImplicitPush, TypePush: + countRules(node.Front()) + case TypeAlternate, TypeUnorderedAlternate, TypeSequence, + TypePeekFor, TypePeekNot, TypeQuery, TypeStar, TypePlus: + for _, element := range node.Slice() { + countRules(element) + } + } + } + for _, node := range t.Slice() { + if node.GetType() == TypeRule { + countRules(node) + break + } + } + }, + func() { + var checkRecursion func(node Node) bool + ruleReached := make([]bool, t.RulesCount) + checkRecursion = func(node Node) bool { + switch node.GetType() { + case TypeRule: + id := node.GetId() + if ruleReached[id] { + fmt.Fprintf(os.Stderr, "possible infinite left recursion in rule '%v'\n", node) + return false + } + ruleReached[id] = true + consumes := checkRecursion(node.Front()) + ruleReached[id] = false + return consumes + case TypeAlternate: + for _, element := range node.Slice() { + if !checkRecursion(element) { + return false + } + } + return true + case TypeSequence: + for _, element := range node.Slice() { + if checkRecursion(element) { + return true + } + } + case TypeName: + return checkRecursion(t.Rules[node.String()]) + case TypePlus, TypePush, TypeImplicitPush: + return checkRecursion(node.Front()) + case TypeCharacter, TypeString: + return len(node.String()) > 0 + case TypeDot, TypeRange: + return true + } + return false + } + for _, node := range t.Slice() { + if node.GetType() == TypeRule { + checkRecursion(node) + } + } + }}) + + if t._switch { + var optimizeAlternates func(node Node) (consumes bool, s *set) + cache, firstPass := make([]struct { + reached, consumes bool + s *set + }, t.RulesCount), true + optimizeAlternates = func(n Node) (consumes bool, s *set) { + /*n.debug()*/ + switch n.GetType() { + case TypeRule: + cache := &cache[n.GetId()] + if cache.reached { + consumes, s = cache.consumes, cache.s + return + } + + cache.reached = true + consumes, s = optimizeAlternates(n.Front()) + cache.consumes, cache.s = consumes, s + case TypeName: + consumes, s = optimizeAlternates(t.Rules[n.String()]) + case TypeDot: + consumes, s = true, &set{} + /* TypeDot set doesn't include the EndSymbol */ + s.add(byte(t.EndSymbol)) + s.complement() + case TypeString, TypeCharacter: + consumes, s = true, &set{} + s.add(n.String()[0]) + case TypeRange: + consumes, s = true, &set{} + element := n.Front() + lower := element.String()[0] + element = element.Next() + upper := element.String()[0] + for c := lower; c <= upper; c++ { + s.add(c) + } + case TypeAlternate: + consumes, s = true, &set{} + mconsumes, properties, c := + consumes, make([]struct { + intersects bool + s *set + }, n.Len()), 0 + for _, element := range n.Slice() { + mconsumes, properties[c].s = optimizeAlternates(element) + consumes = consumes && mconsumes + if properties[c].s == nil { + /* recursive definition, so set has yet to be completed */ + } else { + s.union(properties[c].s) + } + c++ + } + + if firstPass { + break + } + + intersections := 2 + compare: + for ai, a := range properties[0 : len(properties)-1] { + for _, b := range properties[ai+1:] { + if a.s.intersects(b.s) { + intersections++ + properties[ai].intersects = true + continue compare + } + } + } + if intersections >= len(properties) { + break + } + + c, unordered, ordered, max := + 0, &node{Type: TypeUnorderedAlternate}, &node{Type: TypeAlternate}, 0 + for _, element := range n.Slice() { + if properties[c].intersects { + ordered.PushBack(element.Copy()) + } else { + class := &node{Type: TypeUnorderedAlternate} + for d := 0; d < 256; d++ { + if properties[c].s.has(uint8(d)) { + class.PushBack(&node{Type: TypeCharacter, string: string(d)}) + } + } + + sequence, predicate, length := + &node{Type: TypeSequence}, &node{Type: TypePeekFor}, properties[c].s.len() + if length == 0 { + class.PushBack(&node{Type: TypeNil, string: ""}) + } + predicate.PushBack(class) + sequence.PushBack(predicate) + sequence.PushBack(element.Copy()) + + if element.GetType() == TypeNil { + unordered.PushBack(sequence) + } else if length > max { + unordered.PushBack(sequence) + max = length + } else { + unordered.PushFront(sequence) + } + } + c++ + } + n.Init() + if ordered.Front() == nil { + n.SetType(TypeUnorderedAlternate) + for _, element := range unordered.Slice() { + n.PushBack(element.Copy()) + } + } else { + for _, element := range ordered.Slice() { + n.PushBack(element.Copy()) + } + n.PushBack(unordered) + } + case TypeSequence: + classes, elements := + make([]struct { + s *set + }, n.Len()), n.Slice() + + for c, element := range elements { + consumes, classes[c].s = optimizeAlternates(element) + if consumes { + elements, classes = elements[c+1:], classes[:c+1] + break + } + } + + s = &set{} + for c := len(classes) - 1; c >= 0; c-- { + if classes[c].s != nil { + s.union(classes[c].s) + } + } + + for _, element := range elements { + optimizeAlternates(element) + } + case TypePeekNot, TypePeekFor: + optimizeAlternates(n.Front()) + s = &set{} + case TypeQuery, TypeStar: + _, s = optimizeAlternates(n.Front()) + case TypePlus, TypePush, TypeImplicitPush: + consumes, s = optimizeAlternates(n.Front()) + case TypeAction, TypeNil: + s = &set{} + } + return + } + for _, element := range t.Slice() { + if element.GetType() == TypeRule { + optimizeAlternates(element) + break + } + } + + for i, _ := range cache { + cache[i].reached = false + } + firstPass = false + for _, element := range t.Slice() { + if element.GetType() == TypeRule { + optimizeAlternates(element) + break + } + } + } + + out, error := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if error != nil { + fmt.Printf("%v: %v\n", file, error) + return + } + defer out.Close() + + var buffer bytes.Buffer + defer func() { + fileSet := token.NewFileSet() + code, error := parser.ParseFile(fileSet, file, &buffer, parser.ParseComments) + if error != nil { + buffer.WriteTo(out) + fmt.Printf("%v: %v\n", file, error) + return + } + formatter := printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8} + error = formatter.Fprint(out, fileSet, code) + if error != nil { + buffer.WriteTo(out) + fmt.Printf("%v: %v\n", file, error) + return + } + + }() + + print := func(format string, a ...interface{}) { fmt.Fprintf(&buffer, format, a...) } + printSave := func(n uint) { print("\n position%d, tokenIndex%d, depth%d := position, tokenIndex, depth", n, n, n) } + printRestore := func(n uint) { print(" position, tokenIndex, depth = position%d, tokenIndex%d, depth%d", n, n, n) } + printTemplate := func(s string) { + if error := template.Must(template.New("leg").Parse(s)).Execute(&buffer, t); error != nil { + panic(error) + } + } + + t.HasActions = counts[TypeAction] > 0 + t.HasCommit = counts[TypeCommit] > 0 + t.HasDot = counts[TypeDot] > 0 + t.HasCharacter = counts[TypeCharacter] > 0 + t.HasString = counts[TypeString] > 0 + t.HasRange = counts[TypeRange] > 0 + + var printRule func(n Node) + var compile func(expression Node, ko uint) + var label uint + labels := make(map[uint]bool) + printBegin := func() { print("\n {") } + printEnd := func() { print("\n }") } + printLabel := func(n uint) { + print("\n") + if labels[n] { + print(" l%d:\t", n) + } + } + printJump := func(n uint) { + print("\n goto l%d", n) + labels[n] = true + } + printRule = func(n Node) { + switch n.GetType() { + case TypeRule: + print("%v <- ", n) + printRule(n.Front()) + case TypeDot: + print(".") + case TypeName: + print("%v", n) + case TypeCharacter: + print("'%v'", escape(n.String())) + case TypeString: + s := escape(n.String()) + print("'%v'", s[1:len(s)-1]) + case TypeRange: + element := n.Front() + lower := element + element = element.Next() + upper := element + print("[%v-%v]", lower, upper) + case TypePredicate: + print("&{%v}", n) + case TypeAction: + print("{%v}", n) + case TypeCommit: + print("commit") + case TypeAlternate: + print("(") + elements := n.Slice() + printRule(elements[0]) + for _, element := range elements[1:] { + print(" / ") + printRule(element) + } + print(")") + case TypeUnorderedAlternate: + print("(") + elements := n.Slice() + printRule(elements[0]) + for _, element := range elements[1:] { + print(" | ") + printRule(element) + } + print(")") + case TypeSequence: + print("(") + elements := n.Slice() + printRule(elements[0]) + for _, element := range elements[1:] { + print(" ") + printRule(element) + } + print(")") + case TypePeekFor: + print("&") + printRule(n.Front()) + case TypePeekNot: + print("!") + printRule(n.Front()) + case TypeQuery: + printRule(n.Front()) + print("?") + case TypeStar: + printRule(n.Front()) + print("*") + case TypePlus: + printRule(n.Front()) + print("+") + case TypePush, TypeImplicitPush: + print("<") + printRule(n.Front()) + print(">") + case TypeNil: + default: + fmt.Fprintf(os.Stderr, "illegal node type: %v\n", n.GetType()) + } + } + compile = func(n Node, ko uint) { + switch n.GetType() { + case TypeRule: + fmt.Fprintf(os.Stderr, "internal error #1 (%v)\n", n) + case TypeDot: + print("\n if !matchDot() {") + /*print("\n if buffer[position] == END_SYMBOL {")*/ + printJump(ko) + /*print("}\nposition++")*/ + print("}") + case TypeName: + name := n.String() + rule := t.Rules[name] + if t.inline && t.rulesCount[name] == 1 { + compile(rule.Front(), ko) + return + } + print("\n if !rules[Rule%v]() {", name /*rule.GetId()*/) + printJump(ko) + print("}") + case TypeRange: + element := n.Front() + lower := element + element = element.Next() + upper := element + /*print("\n if !matchRange('%v', '%v') {", escape(lower.String()), escape(upper.String()))*/ + print("\n if c := buffer[position]; c < rune('%v') || c > rune('%v') {", escape(lower.String()), escape(upper.String())) + printJump(ko) + print("}\nposition++") + case TypeCharacter: + /*print("\n if !matchChar('%v') {", escape(n.String()))*/ + print("\n if buffer[position] != rune('%v') {", escape(n.String())) + printJump(ko) + print("}\nposition++") + case TypeString: + print("\n if !matchStringn(%v) {", strconv.Quote(n.String())) + printJump(ko) + print("}") + case TypePredicate: + print("\n if !(%v) {", n) + printJump(ko) + print("}") + case TypeAction: + case TypeCommit: + case TypePush: + fallthrough + case TypeImplicitPush: + ok, element := label, n.Front() + label++ + nodeType, rule := element.GetType(), element.Next() + printBegin() + if nodeType == TypeAction { + print("\nadd(Rule%v, position)", rule) + } else { + print("\nposition%d := position", ok) + print("\ndepth++") + compile(element, ko) + print("\ndepth--") + print("\nadd(Rule%v, position%d)", rule, ok) + } + printEnd() + case TypeAlternate: + ok := label + label++ + printBegin() + elements := n.Slice() + printSave(ok) + for _, element := range elements[:len(elements)-1] { + next := label + label++ + compile(element, next) + printJump(ok) + printLabel(next) + printRestore(ok) + } + compile(elements[len(elements)-1], ko) + printEnd() + printLabel(ok) + case TypeUnorderedAlternate: + done, ok := ko, label + label++ + printBegin() + print("\n switch buffer[position] {") + elements := n.Slice() + elements, last := elements[:len(elements)-1], elements[len(elements)-1].Front().Next() + for _, element := range elements { + sequence := element.Front() + class := sequence.Front() + sequence = sequence.Next() + print("\n case") + comma := false + for _, character := range class.Slice() { + if comma { + print(",") + } else { + comma = true + } + print(" '%s'", escape(character.String())) + } + print(":") + compile(sequence, done) + print("\nbreak") + } + print("\n default:") + compile(last, done) + print("\nbreak") + print("\n }") + printEnd() + printLabel(ok) + case TypeSequence: + for _, element := range n.Slice() { + compile(element, ko) + } + case TypePeekFor: + ok := label + label++ + printBegin() + printSave(ok) + compile(n.Front(), ko) + printRestore(ok) + printEnd() + case TypePeekNot: + ok := label + label++ + printBegin() + printSave(ok) + compile(n.Front(), ok) + printJump(ko) + printLabel(ok) + printRestore(ok) + printEnd() + case TypeQuery: + qko := label + label++ + qok := label + label++ + printBegin() + printSave(qko) + compile(n.Front(), qko) + printJump(qok) + printLabel(qko) + printRestore(qko) + printEnd() + printLabel(qok) + case TypeStar: + again := label + label++ + out := label + label++ + printLabel(again) + printBegin() + printSave(out) + compile(n.Front(), out) + printJump(again) + printLabel(out) + printRestore(out) + printEnd() + case TypePlus: + again := label + label++ + out := label + label++ + compile(n.Front(), ko) + printLabel(again) + printBegin() + printSave(out) + compile(n.Front(), out) + printJump(again) + printLabel(out) + printRestore(out) + printEnd() + case TypeNil: + default: + fmt.Fprintf(os.Stderr, "illegal node type: %v\n", n.GetType()) + } + } + + /* lets figure out which jump labels are going to be used with this dry compile */ + printTemp, print := print, func(format string, a ...interface{}) {} + for _, element := range t.Slice() { + if element.GetType() != TypeRule { + continue + } + expression := element.Front() + if expression.GetType() == TypeNil { + continue + } + ko := label + label++ + if count, ok := t.rulesCount[element.String()]; !ok { + continue + } else if t.inline && count == 1 && ko != 0 { + continue + } + compile(expression, ko) + } + print, label = printTemp, 0 + + /* now for the real compile pass */ + printTemplate(LEG_HEADER_TEMPLATE) + for _, element := range t.Slice() { + if element.GetType() != TypeRule { + continue + } + expression := element.Front() + if expression.GetType() == TypeNil { + fmt.Fprintf(os.Stderr, "rule '%v' used but not defined\n", element) + print("\n nil,") + continue + } + ko := label + label++ + print("\n /* %v ", element.GetId()) + printRule(element) + print(" */") + if count, ok := t.rulesCount[element.String()]; !ok { + fmt.Fprintf(os.Stderr, "rule '%v' defined but not used\n", element) + print("\n nil,") + continue + } else if t.inline && count == 1 && ko != 0 { + print("\n nil,") + continue + } + print("\n func() bool {") + if labels[ko] { + printSave(ko) + } + compile(expression, ko) + print("\n return true") + if labels[ko] { + printLabel(ko) + printRestore(ko) + print("\n return false") + } + print("\n },") + } + print("\n }\n p.rules = rules") + print("\n}\n") +} From 8467557664316846a3bd8a9e7e6b2f14453caa99 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Tue, 4 Mar 2014 11:42:15 +0800 Subject: [PATCH 02/13] Initial Trailer support --- leg.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/leg.go b/leg.go index ca3f9c1..a450abb 100644 --- a/leg.go +++ b/leg.go @@ -689,6 +689,7 @@ type Tree struct { EndSymbol rune StructName string StructVariables string + Trailer string RulesCount int Bits int HasActions bool @@ -742,6 +743,7 @@ func (t *Tree) AddNil() { t.PushFront(&node{Type: TypeNil, stri func (t *Tree) AddAction(text string) { t.PushFront(&node{Type: TypeAction, string: text}) } func (t *Tree) AddPackage(text string) { t.PushBack(&node{Type: TypePackage, string: text}) } func (t *Tree) AddDeclaration(text string) { t.Declarations = append(t.Declarations, text) } +func (t *Tree) AddTrailer(text string) { t.Trailer = text } func (t *Tree) AddState(text string) { leg := t.PopFront() leg.PushBack(&node{Type: TypeState, string: text}) @@ -1546,4 +1548,6 @@ func (t *Tree) Compile(file string) { } print("\n }\n p.rules = rules") print("\n}\n") + print(t.Trailer) + print("\n\n") } From 90cc41dcba542411e30d41d7c4765b1a23f4b019 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Tue, 4 Mar 2014 17:55:28 +0800 Subject: [PATCH 03/13] Initial LEG bootstrapping with Declaration and Trailer Generated bootstrap.leg.go is different from compiled leg.peg.go, but latter is identical when using itself to compile leg.peg --- bootstrap/leg/leg.peg | 116 ++++++++++++++++++++++++++++++++++++++++ bootstrap/leg/main.go | 120 +++++++++++++++++++++++++++++++----------- leg.go | 2 +- 3 files changed, 207 insertions(+), 31 deletions(-) create mode 100644 bootstrap/leg/leg.peg diff --git a/bootstrap/leg/leg.peg b/bootstrap/leg/leg.peg new file mode 100644 index 0000000..b2fe552 --- /dev/null +++ b/bootstrap/leg/leg.peg @@ -0,0 +1,116 @@ +# PE Grammar for PE Grammars +# +# Adapted from [1] by Ian Piumarta . +# +# 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 + +# parser declaration + +type Leg Peg { + *Tree +} + +# Hierarchical syntax +Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } + 'type' Spacing Identifier { p.AddLeg(buffer[begin:end]) } + 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } + (Declaration / Definition)+ Trailer? EndOfFile + +Declaration <- '%{' < ( !'%}' . )* > RPERCENT { p.AddDeclaration(buffer[begin:end]) } +Trailer <- '%%' < .* > { p.AddTrailer(buffer[begin:end]) } + +Definition <- Identifier { p.AddRule(buffer[begin:end]) } + LeftArrow Expression { p.AddExpression() } +Expression <- Sequence (Slash Sequence { p.AddAlternate() } + )* (Slash { p.AddNil(); p.AddAlternate() } + )? + / { p.AddNil() } +Sequence <- Prefix (Prefix { p.AddSequence() } + )* +Prefix <- And Action { p.AddPredicate(buffer[begin:end]) } + / 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(buffer[begin:end]) } + / Open Expression Close + / Literal + / Class + / Dot { p.AddDot() } + / Action { p.AddAction(buffer[begin:end]) } + / 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(buffer[begin:end]) } +DoubleChar <- Escape + / <[a-zA-Z]> { p.AddDoubleCharacter(buffer[begin:end]) } + / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } +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("-") } + / '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(buffer[begin:end]) } + / '\\' <[0-7][0-7]?> { p.AddOctalCharacter(buffer[begin:end]) } + / '\\\\' { p.AddCharacter("\\") } +Action <- '{' < Braces* > '}' Spacing +Braces <- '{' Braces* '}' / !'}' . +LeftArrow <- '<-' Spacing +Slash <- '/' Spacing +And <- '&' Spacing +Not <- '!' Spacing +Question <- '?' Spacing +Star <- '*' Spacing +Plus <- '+' Spacing +Open <- '(' Spacing +Close <- ')' Spacing +Dot <- '.' Spacing +RPERCENT <- '%}' Spacing +Spacing <- (Space / Comment)* +Comment <- '#' (!EndOfLine .)* EndOfLine +Space <- ' ' / '\t' / EndOfLine +EndOfLine <- '\r\n' / '\n' / '\r' +EndOfFile <- !. +Begin <- '<' Spacing +End <- '>' Spacing diff --git a/bootstrap/leg/main.go b/bootstrap/leg/main.go index c3958a2..ff8177c 100644 --- a/bootstrap/leg/main.go +++ b/bootstrap/leg/main.go @@ -13,7 +13,7 @@ func main() { t := New(true, true) /*package main - type Peg Peg { + type Leg Peg { *Tree }*/ t.AddPackage("main") @@ -21,12 +21,11 @@ func main() { t.AddState(` *Tree `) - t.AddDeclaration("\n//This is a declaration test\n") /* Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } - 'type' Spacing Identifier { p.AddPeg(buffer[begin:end]) } + 'type' Spacing Identifier { p.AddLeg(buffer[begin:end]) } 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } - Definition+ EndOfFile */ + ( Declaration | Definition)+ Trailer? EndOfFile */ t.AddRule("Grammar") t.AddName("Spacing") t.AddCharacter(`p`) @@ -61,7 +60,7 @@ func main() { t.AddSequence() t.AddName("Identifier") t.AddSequence() - t.AddAction(" p.AddPeg(buffer[begin:end]) ") + t.AddAction(" p.AddLeg(buffer[begin:end]) ") t.AddSequence() t.AddCharacter(`P`) t.AddCharacter(`e`) @@ -75,15 +74,55 @@ func main() { t.AddSequence() t.AddAction(" p.AddState(buffer[begin:end]) ") t.AddSequence() + t.AddName("Declaration") t.AddName("Definition") + t.AddAlternate() t.AddPlus() t.AddSequence() + t.AddName("Trailer") + t.AddQuery() + t.AddSequence() t.AddName("EndOfFile") t.AddSequence() t.AddExpression() + /* Declaration = '%{' < ( !'%}' . )* > { p.AddDeclaration(buffer[begin:end]) }* RPERCENT */ + t.AddRule("Declaration") + t.AddCharacter("%") + t.AddCharacter("{") + t.AddSequence() + t.AddPush() + t.AddCharacter("%") + t.AddCharacter("}") + t.AddSequence() + t.AddPush() + t.AddPeekNot() + t.AddDot() + t.AddSequence() + t.AddStar() + t.AddPush() + t.AddSequence() + t.AddName("RPERCENT") + t.AddSequence() + t.AddAction(" p.AddDeclaration(buffer[begin:end]) ") + t.AddSequence() + t.AddExpression() + + /* trailer = '%%' < .* > { p.AddTrailer(buffer[begin:end]) }*/ + t.AddRule("Trailer") + t.AddCharacter("%") + t.AddCharacter("%") + t.AddSequence() + t.AddDot() + t.AddStar() + t.AddPush() + t.AddAction(" p.AddTrailer(buffer[begin:end]) ") + t.AddSequence() + t.AddSequence() + t.AddExpression() + /* Definition <- Identifier { p.AddRule(buffer[begin:end]) } - LeftArrow Expression { p.AddExpression() } &(Identifier LeftArrow / !.)*/ + LeftArrow Expression { p.AddExpression() }*/ t.AddRule("Definition") t.AddName("Identifier") t.AddAction(" p.AddRule(buffer[begin:end]) ") @@ -94,14 +133,14 @@ func main() { t.AddSequence() t.AddAction(" p.AddExpression() ") t.AddSequence() - t.AddName("Identifier") - t.AddName("LeftArrow") - t.AddSequence() - t.AddDot() - t.AddPeekNot() - t.AddAlternate() - t.AddPeekFor() - t.AddSequence() + // t.AddName("Identifier") + // t.AddName("LeftArrow") + // t.AddSequence() + // t.AddDot() + // t.AddPeekNot() + // t.AddAlternate() + // t.AddPeekFor() + // t.AddSequence() t.AddExpression() /* Expression <- Sequence (Slash Sequence { p.AddAlternate() } @@ -581,6 +620,34 @@ func main() { t.AddAlternate() t.AddExpression() + /* Action <- '{' < Braces* > '}' Spacing */ + t.AddRule("Action") + t.AddCharacter(`{`) + t.AddName("Braces") + t.AddStar() + t.AddPush() + t.AddSequence() + t.AddCharacter(`}`) + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + + /* Braces <- '{' Braces* '}' / !'}' . */ + t.AddRule("Braces") + t.AddCharacter(`{`) + t.AddName("Braces") + t.AddStar() + t.AddSequence() + t.AddCharacter(`}`) + t.AddSequence() + t.AddCharacter(`}`) + t.AddPeekNot() + t.AddDot() + t.AddSequence() + t.AddAlternate() + t.AddExpression() + /* LeftArrow <- '<-' Spacing */ t.AddRule("LeftArrow") t.AddCharacter(`<`) @@ -653,6 +720,15 @@ func main() { t.AddSequence() t.AddExpression() + /* RPERCENT = '%}' Spacing */ + t.AddRule("RPERCENT") + t.AddCharacter("%") + t.AddCharacter("}") + t.AddSequence() + t.AddName("Spacing") + t.AddSequence() + t.AddExpression() + /* Spacing <- (Space / Comment)* */ t.AddRule("Spacing") t.AddName("Space") @@ -700,22 +776,6 @@ func main() { t.AddPeekNot() t.AddExpression() - /* Action <- '{' < [^}]* > '}' Spacing */ - t.AddRule("Action") - t.AddCharacter(`{`) - t.AddCharacter(`}`) - t.AddPeekNot() - t.AddDot() - t.AddSequence() - t.AddStar() - t.AddPush() - t.AddSequence() - t.AddCharacter(`}`) - t.AddSequence() - t.AddName("Spacing") - t.AddSequence() - t.AddExpression() - /* Begin <- '<' Spacing */ t.AddRule("Begin") t.AddCharacter(`<`) diff --git a/leg.go b/leg.go index a450abb..3140e74 100644 --- a/leg.go +++ b/leg.go @@ -1221,7 +1221,7 @@ func (t *Tree) Compile(file string) { var compile func(expression Node, ko uint) var label uint labels := make(map[uint]bool) - printBegin := func() { print("\n {") } + printBegin := func() { print("\n {\n") } printEnd := func() { print("\n }") } printLabel := func(n uint) { print("\n") From fa44e0e80d76b1144cc2c31b61c082af2eff6fa6 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Tue, 4 Mar 2014 20:48:34 +0800 Subject: [PATCH 04/13] '-' can be used as identifier --- bootstrap/leg/main.go | 94 ++++++++++++++++++++++--------------------- leg.go | 2 + 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/bootstrap/leg/main.go b/bootstrap/leg/main.go index ff8177c..be63c96 100644 --- a/bootstrap/leg/main.go +++ b/bootstrap/leg/main.go @@ -22,12 +22,12 @@ func main() { *Tree `) - /* Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } - 'type' Spacing Identifier { p.AddLeg(buffer[begin:end]) } - 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } + /* Grammar <- - 'package' - Identifier { p.AddPackage(buffer[begin:end]) } + 'type' - Identifier { p.AddLeg(buffer[begin:end]) } + 'Peg' - Action { p.AddState(buffer[begin:end]) } ( Declaration | Definition)+ Trailer? EndOfFile */ t.AddRule("Grammar") - t.AddName("Spacing") + t.AddName("-") t.AddCharacter(`p`) t.AddCharacter(`a`) t.AddSequence() @@ -42,7 +42,7 @@ func main() { t.AddCharacter(`e`) t.AddSequence() t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddName("Identifier") t.AddSequence() @@ -56,7 +56,7 @@ func main() { t.AddCharacter(`e`) t.AddSequence() t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddName("Identifier") t.AddSequence() @@ -68,7 +68,7 @@ func main() { t.AddCharacter(`g`) t.AddSequence() t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddName("Action") t.AddSequence() @@ -265,24 +265,26 @@ func main() { t.AddAlternate() t.AddExpression() - /* Identifier <- < IdentStart IdentCont* > Spacing */ + /* Identifier <- < IdentStart IdentCont* > - */ t.AddRule("Identifier") t.AddName("IdentStart") t.AddName("IdentCont") t.AddStar() t.AddSequence() t.AddPush() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* IdentStart <- [[a-z_]] */ + /* IdentStart <- [[a-z_-]] */ t.AddRule("IdentStart") t.AddCharacter(`a`) t.AddCharacter(`z`) t.AddDoubleRange() t.AddCharacter(`_`) t.AddAlternate() + t.AddCharacter(`-`) + t.AddAlternate() t.AddExpression() /* IdentCont <- IdentStart / [0-9] */ @@ -295,9 +297,9 @@ func main() { t.AddExpression() /* Literal <- ['] (!['] Char)? (!['] Char { p.AddSequence() } - )* ['] Spacing + )* ['] - / ["] (!["] DoubleChar)? (!["] DoubleChar { p.AddSequence() } - )* ["] Spacing */ + )* ["] - */ t.AddRule("Literal") t.AddCharacter(`'`) t.AddCharacter(`'`) @@ -316,7 +318,7 @@ func main() { t.AddSequence() t.AddCharacter(`'`) t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddCharacter(`"`) t.AddCharacter(`"`) @@ -335,7 +337,7 @@ func main() { t.AddSequence() t.AddCharacter(`"`) t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddAlternate() t.AddExpression() @@ -346,7 +348,7 @@ func main() { / '[' ( '^' Ranges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } / Ranges )? ']' ) - Spacing */ + - */ t.AddRule("Class") t.AddCharacter(`[`) t.AddCharacter(`[`) @@ -377,7 +379,7 @@ func main() { t.AddCharacter(`]`) t.AddSequence() t.AddAlternate() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() @@ -620,7 +622,7 @@ func main() { t.AddAlternate() t.AddExpression() - /* Action <- '{' < Braces* > '}' Spacing */ + /* Action <- '{' < Braces* > '}' - */ t.AddRule("Action") t.AddCharacter(`{`) t.AddName("Braces") @@ -629,7 +631,7 @@ func main() { t.AddSequence() t.AddCharacter(`}`) t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() @@ -648,89 +650,89 @@ func main() { t.AddAlternate() t.AddExpression() - /* LeftArrow <- '<-' Spacing */ + /* LeftArrow <- '<-' - */ t.AddRule("LeftArrow") t.AddCharacter(`<`) t.AddCharacter(`-`) t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Slash <- '/' Spacing */ + /* Slash <- '/' - */ t.AddRule("Slash") t.AddCharacter(`/`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* And <- '&' Spacing */ + /* And <- '&' - */ t.AddRule("And") t.AddCharacter(`&`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Not <- '!' Spacing */ + /* Not <- '!' - */ t.AddRule("Not") t.AddCharacter(`!`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Question <- '?' Spacing */ + /* Question <- '?' - */ t.AddRule("Question") t.AddCharacter(`?`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Star <- '*' Spacing */ + /* Star <- '*' - */ t.AddRule("Star") t.AddCharacter(`*`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Plus <- '+' Spacing */ + /* Plus <- '+' - */ t.AddRule("Plus") t.AddCharacter(`+`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Open <- '(' Spacing */ + /* Open <- '(' - */ t.AddRule("Open") t.AddCharacter(`(`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Close <- ')' Spacing */ + /* Close <- ')' - */ t.AddRule("Close") t.AddCharacter(`)`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Dot <- '.' Spacing */ + /* Dot <- '.' - */ t.AddRule("Dot") t.AddCharacter(`.`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* RPERCENT = '%}' Spacing */ + /* RPERCENT = '%}' - */ t.AddRule("RPERCENT") t.AddCharacter("%") t.AddCharacter("}") t.AddSequence() - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* Spacing <- (Space / Comment)* */ - t.AddRule("Spacing") + /* - <- (Space / Comment)* */ + t.AddRule("-") t.AddName("Space") t.AddName("Comment") t.AddAlternate() @@ -776,17 +778,17 @@ func main() { t.AddPeekNot() t.AddExpression() - /* Begin <- '<' Spacing */ + /* Begin <- '<' - */ t.AddRule("Begin") t.AddCharacter(`<`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() - /* End <- '>' Spacing */ + /* End <- '>' - */ t.AddRule("End") t.AddCharacter(`>`) - t.AddName("Spacing") + t.AddName("-") t.AddSequence() t.AddExpression() diff --git a/leg.go b/leg.go index 3140e74..481b865 100644 --- a/leg.go +++ b/leg.go @@ -710,6 +710,7 @@ func New(inline, _switch bool) *Tree { } func (t *Tree) AddRule(name string) { + name = strings.Replace(name, "-", "_", -1) t.PushFront(&node{Type: TypeRule, string: name, id: t.RulesCount}) t.RulesCount++ } @@ -722,6 +723,7 @@ func (t *Tree) AddExpression() { } func (t *Tree) AddName(text string) { + text = strings.Replace(text, "-", "_", -1) t.PushFront(&node{Type: TypeName, string: text}) } From 7bfabea4b582baa3c21420fbb07cacbe71e8e180 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Thu, 6 Mar 2014 02:16:07 +0800 Subject: [PATCH 05/13] Use '=' and '|' for LEG grammar --- bootstrap/leg/main.go | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/bootstrap/leg/main.go b/bootstrap/leg/main.go index be63c96..fb41c85 100644 --- a/bootstrap/leg/main.go +++ b/bootstrap/leg/main.go @@ -122,19 +122,19 @@ func main() { t.AddExpression() /* Definition <- Identifier { p.AddRule(buffer[begin:end]) } - LeftArrow Expression { p.AddExpression() }*/ + Equal Expression { p.AddExpression() }*/ t.AddRule("Definition") t.AddName("Identifier") t.AddAction(" p.AddRule(buffer[begin:end]) ") t.AddSequence() - t.AddName("LeftArrow") + t.AddName("Equal") t.AddSequence() t.AddName("Expression") t.AddSequence() t.AddAction(" p.AddExpression() ") t.AddSequence() // t.AddName("Identifier") - // t.AddName("LeftArrow") + // t.AddName("Equal") // t.AddSequence() // t.AddDot() // t.AddPeekNot() @@ -143,20 +143,20 @@ func main() { // t.AddSequence() t.AddExpression() - /* Expression <- Sequence (Slash Sequence { p.AddAlternate() } - )* (Slash { p.AddNil(); p.AddAlternate() } + /* Expression <- Sequence (Bar Sequence { p.AddAlternate() } + )* (Bar { p.AddNil(); p.AddAlternate() } )? / { p.AddNil() } */ t.AddRule("Expression") t.AddName("Sequence") - t.AddName("Slash") + t.AddName("Bar") t.AddName("Sequence") t.AddSequence() t.AddAction(" p.AddAlternate() ") t.AddSequence() t.AddStar() t.AddSequence() - t.AddName("Slash") + t.AddName("Bar") t.AddAction(" p.AddNil(); p.AddAlternate() ") t.AddSequence() t.AddQuery() @@ -223,7 +223,7 @@ func main() { t.AddSequence() t.AddExpression() - /* Primary <- Identifier !LeftArrow { p.AddName(buffer[begin:end]) } + /* Primary <- Identifier !Equal { p.AddName(buffer[begin:end]) } / Open Expression Close / Literal / Class @@ -232,7 +232,7 @@ func main() { / Begin Expression End { p.AddPush() }*/ t.AddRule("Primary") t.AddName("Identifier") - t.AddName("LeftArrow") + t.AddName("Equal") t.AddPeekNot() t.AddSequence() t.AddAction(" p.AddName(buffer[begin:end]) ") @@ -650,18 +650,16 @@ func main() { t.AddAlternate() t.AddExpression() - /* LeftArrow <- '<-' - */ - t.AddRule("LeftArrow") - t.AddCharacter(`<`) - t.AddCharacter(`-`) - t.AddSequence() + /* Equal <- '=' - */ + t.AddRule("Equal") + t.AddCharacter(`=`) t.AddName("-") t.AddSequence() t.AddExpression() - /* Slash <- '/' - */ - t.AddRule("Slash") - t.AddCharacter(`/`) + /* Bar <- '|' - */ + t.AddRule("Bar") + t.AddCharacter(`|`) t.AddName("-") t.AddSequence() t.AddExpression() From 700db5af13c1701be4b88fd60bb3c5945ff4b136 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Fri, 7 Mar 2014 06:24:34 +0800 Subject: [PATCH 06/13] Use LEG grammar identifier --- bootstrap/leg/main.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/bootstrap/leg/main.go b/bootstrap/leg/main.go index fb41c85..fd738d2 100644 --- a/bootstrap/leg/main.go +++ b/bootstrap/leg/main.go @@ -265,35 +265,32 @@ func main() { t.AddAlternate() t.AddExpression() - /* Identifier <- < IdentStart IdentCont* > - */ + /* Identifier = < [-a-zA-Z_][-a-zA-Z_0-9]* > - */ t.AddRule("Identifier") - t.AddName("IdentStart") - t.AddName("IdentCont") - t.AddStar() - t.AddSequence() - t.AddPush() - t.AddName("-") - t.AddSequence() - t.AddExpression() - /* IdentStart <- [[a-z_-]] */ - t.AddRule("IdentStart") + t.AddCharacter(`-`) t.AddCharacter(`a`) t.AddCharacter(`z`) t.AddDoubleRange() + t.AddAlternate() t.AddCharacter(`_`) t.AddAlternate() t.AddCharacter(`-`) + t.AddCharacter(`a`) + t.AddCharacter(`z`) + t.AddDoubleRange() t.AddAlternate() - t.AddExpression() - - /* IdentCont <- IdentStart / [0-9] */ - t.AddRule("IdentCont") - t.AddName("IdentStart") t.AddCharacter(`0`) t.AddCharacter(`9`) t.AddRange() t.AddAlternate() + t.AddCharacter(`_`) + t.AddAlternate() + t.AddStar() + t.AddSequence() + t.AddPush() + t.AddName("-") + t.AddSequence() t.AddExpression() /* Literal <- ['] (!['] Char)? (!['] Char { p.AddSequence() } From 9718cf5b91da4b85f483bdd29a98b202ce2768e3 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Sun, 9 Mar 2014 03:23:42 +0800 Subject: [PATCH 07/13] Statically semantic value complication won't work when rule has dynamic variables --- bootstrap/leg/main.go | 45 +++++++++++++- leg.go | 133 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/bootstrap/leg/main.go b/bootstrap/leg/main.go index fd738d2..d441ca5 100644 --- a/bootstrap/leg/main.go +++ b/bootstrap/leg/main.go @@ -21,8 +21,10 @@ func main() { t.AddState(` *Tree `) + t.AddYYSType("int") /* Grammar <- - 'package' - Identifier { p.AddPackage(buffer[begin:end]) } + 'type' - 'YYSTYPE' - Identifier { p.AddYYSType(buffer[begin:end]) } 'type' - Identifier { p.AddLeg(buffer[begin:end]) } 'Peg' - Action { p.AddState(buffer[begin:end]) } ( Declaration | Definition)+ Trailer? EndOfFile */ @@ -48,6 +50,26 @@ func main() { t.AddSequence() t.AddAction(" p.AddPackage(buffer[begin:end]) ") t.AddSequence() + t.AddCharacter(`Y`) + t.AddCharacter(`Y`) + t.AddSequence() + t.AddCharacter(`S`) + t.AddSequence() + t.AddCharacter(`T`) + t.AddSequence() + t.AddCharacter(`Y`) + t.AddSequence() + t.AddCharacter(`P`) + t.AddSequence() + t.AddCharacter(`E`) + t.AddSequence() + t.AddSequence() + t.AddName("-") + t.AddSequence() + t.AddName("Identifier") + t.AddSequence() + t.AddAction(" p.AddYYSType(buffer[begin:end]) ") + t.AddSequence() t.AddCharacter(`t`) t.AddCharacter(`y`) t.AddSequence() @@ -223,7 +245,8 @@ func main() { t.AddSequence() t.AddExpression() - /* Primary <- Identifier !Equal { p.AddName(buffer[begin:end]) } + /* Primary = Identifier { p.AddVariable(buffer[begin:end]) } Colon Identifier !EQUAL { p.AddName(buffer[begin:end]) } + / Identifier !Equal { p.AddName(buffer[begin:end]) } / Open Expression Close / Literal / Class @@ -232,11 +255,24 @@ func main() { / Begin Expression End { p.AddPush() }*/ t.AddRule("Primary") t.AddName("Identifier") + t.AddAction(" p.AddVariable(buffer[begin:end]) ") + t.AddSequence() + t.AddName("Colon") + t.AddSequence() + t.AddName("Identifier") + t.AddSequence() + t.AddName("Equal") + t.AddPeekNot() + t.AddSequence() + t.AddAction(" p.AddName(buffer[begin:end]) ") + t.AddSequence() + t.AddName("Identifier") t.AddName("Equal") t.AddPeekNot() t.AddSequence() t.AddAction(" p.AddName(buffer[begin:end]) ") t.AddSequence() + t.AddAlternate() t.AddName("Open") t.AddName("Expression") t.AddSequence() @@ -654,6 +690,13 @@ func main() { t.AddSequence() t.AddExpression() + /* Colon <- ':' - */ + t.AddRule("Colon") + t.AddCharacter(`:`) + t.AddName("-") + t.AddSequence() + t.AddExpression() + /* Bar <- '|' - */ t.AddRule("Bar") t.AddCharacter(`|`) diff --git a/leg.go b/leg.go index 481b865..067abf3 100644 --- a/leg.go +++ b/leg.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" "text/template" + "regexp" ) const LEG_HEADER_TEMPLATE = `package {{.PackageName}} @@ -31,6 +32,7 @@ const END_SYMBOL rune = {{.EndSymbol}} {{range .Declarations}}{{.}} {{end}} +type YYSTYPE {{.YYSType}} /* The rule types inferred from the grammar are below. */ type Rule uint8 @@ -385,6 +387,10 @@ func (p *{{.StructName}}) Highlighter() { {{if .HasActions}} func (p *{{.StructName}}) Execute() { buffer, begin, end := p.Buffer, 0, 0 + {{if .HasYY}} + var yy YYSTYPE + stack := make([]YYSTYPE, 0) + {{end}} for token := range p.TokenTree.Tokens() { switch (token.Rule) { case RulePegText: @@ -492,6 +498,7 @@ const ( TypePredicate TypeCommit TypeAction + TypeVariable TypePackage TypeState TypeAlternate @@ -520,6 +527,7 @@ var TypeMap = [...]string{ "TypePredicate", "TypeCommit", "TypeAction", + "TypeVariable", "TypePackage", "TypeState", "TypeAlternate", @@ -686,6 +694,7 @@ type Tree struct { Sizes [2]int PackageName string Declarations []string + YYSType string EndSymbol rune StructName string StructVariables string @@ -699,6 +708,7 @@ type Tree struct { HasCharacter bool HasString bool HasRange bool + HasYY bool } func New(inline, _switch bool) *Tree { @@ -724,7 +734,14 @@ func (t *Tree) AddExpression() { func (t *Tree) AddName(text string) { text = strings.Replace(text, "-", "_", -1) + var v *node + if t.Front().GetType() == TypeVariable { + v = t.PopFront() + } t.PushFront(&node{Type: TypeName, string: text}) + if v != nil { + t.Front().PushBack(v) + } } func (t *Tree) AddDot() { t.PushFront(&node{Type: TypeDot, string: "."}) } @@ -743,9 +760,11 @@ func (t *Tree) AddOctalCharacter(text string) { func (t *Tree) AddPredicate(text string) { t.PushFront(&node{Type: TypePredicate, string: text}) } func (t *Tree) AddNil() { t.PushFront(&node{Type: TypeNil, string: ""}) } func (t *Tree) AddAction(text string) { t.PushFront(&node{Type: TypeAction, string: text}) } +func (t *Tree) AddVariable(text string) { t.PushFront(&node{Type: TypeVariable, string: text}) } func (t *Tree) AddPackage(text string) { t.PushBack(&node{Type: TypePackage, string: text}) } func (t *Tree) AddDeclaration(text string) { t.Declarations = append(t.Declarations, text) } func (t *Tree) AddTrailer(text string) { t.Trailer = text } +func (t *Tree) AddYYSType(text string) { t.YYSType = text } func (t *Tree) AddState(text string) { leg := t.PopFront() leg.PushBack(&node{Type: TypeState, string: text}) @@ -827,7 +846,121 @@ func (t *Tree) Compile(file string) { counts := [TypeLast]uint{} { var rule *node + var traverse func(node Node) int var link func(node Node) + hasYY := false + + // Modify actions which use named semantic variables + // Use DFS traversal to find TypeVariable and TypeAction + var_stack := make([]string, 0) + traverse = func(n Node) int { + variableCount := 0 + next_level_count := 0 + leaf := n.Front() + if leaf == nil { + return 0 + } + for { + // fmt.Println(TypeMap[leaf.GetType()]) + switch leaf.GetType() { + case TypeName: + if leaf.Front()!=nil && leaf.Front().GetType()==TypeVariable { + variableCount++ + var_stack = append(var_stack, leaf.Front().String()) + } + case TypeAction: + // Use regular expression to extract every variable and replace them + re := regexp.MustCompile("[a-zA-Z_][a-zA-Z0-9_]*") + str := leaf.String() + if strings.Contains(str, "$$") { + hasYY = true + str = strings.Replace(str,"$$","yy",-1) + } + tempStr := make([]string, 0) + lastIndex := 0 + for _, element := range re.FindAllStringIndex(str, -1) { + varname := str[element[0]:element[1]] + tempStr = append(tempStr, str[lastIndex:element[0]]) + lastIndex = element[1] + hasReplaced := false + for i, var_element := range var_stack { + if var_element == varname { + tempStr = append(tempStr,fmt.Sprintf("stack[len(stack)-%d]", i+1)) + hasReplaced = true + break + } + } + if !hasReplaced { + tempStr = append(tempStr, str[element[0]:element[1]]) + } + } + tempStr = append(tempStr, str[lastIndex:]) + leaf.SetString(strings.Join(tempStr,"")) + rule = leaf + + // List types + case TypeSequence: + next_level_count = traverse(leaf) + if n.GetType()==TypeAlternate && next_level_count > 0{ + // fmt.Println(next_level_count,":",var_stack) + // tempStr := []string { rule.String(), ";stack = stack[0:(len(stack)-", + // strconv.Itoa(next_level_count), ")]"} + // rule.SetString(strings.Join(tempStr,"")) + var_stack = var_stack[0:(len(var_stack)-next_level_count)] + } + case TypeAlternate: + next_level_count = traverse(leaf) + + // Fix types + case TypePeekFor: + fallthrough + case TypePeekNot: + fallthrough + case TypeQuery: + fallthrough + case TypeStar: + fallthrough + case TypePlus: + fallthrough + case TypePush: + variableCount += traverse(leaf) + } + + if leaf.Next()==nil { + break + } + leaf = leaf.Next() + } + // fmt.Println("Return ", variableCount, ", Has ", len(var_stack)) + return variableCount + next_level_count + } + + traverse_node := t.Front() + for { + hasYY = false + var_stack = make([]string, 0) + stackCount := traverse(traverse_node) + if traverse_node.Front() != nil && rule != nil && hasYY { + t.HasYY = true + if traverse_node.Front().GetType() != TypeSequence { + expression := traverse_node.PopFront() + sequence := &node{Type: TypeSequence} + sequence.PushBack(expression) + traverse_node.PushBack(sequence) + } + tempStr := []string {"stack = stack[0:(len(stack)-", + strconv.Itoa(stackCount), ")]; stack = append(stack, yy)"} + traverse_node.Front().PushBack(&node{Type: TypeAction, string: strings.Join(tempStr,"")}) + // fmt.Println(TypeMap[traverse_node.Front().GetType()]) + // fmt.Println(tempStr) + } + rule = nil + if traverse_node.Next() == nil { + break + } + traverse_node = traverse_node.Next() + } + link = func(n Node) { nodeType := n.GetType() id := counts[nodeType] From 047d5e6502f6f98c5e59fa08797ce4041521e3bb Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Mon, 10 Mar 2014 04:04:08 +0800 Subject: [PATCH 08/13] Dynamic semantic variables manipulation - Add stack operations: RuleActionPush, RuleActionPop --- leg.go | 95 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 24 deletions(-) diff --git a/leg.go b/leg.go index 067abf3..8eb1041 100644 --- a/leg.go +++ b/leg.go @@ -41,6 +41,8 @@ const ( RuleUnknown Rule = iota {{range .RuleNames}}Rule{{.String}} {{end}} + RuleActionPush + RuleActionPop RulePre_ Rule_In_ Rule_Suf @@ -50,6 +52,8 @@ var Rul3s = [...]string { "Unknown", {{range .RuleNames}}"{{.String}}", {{end}} + "RuleActionPush", + "RuleActionPop", "Pre_", "_In_", "_Suf", @@ -387,7 +391,7 @@ func (p *{{.StructName}}) Highlighter() { {{if .HasActions}} func (p *{{.StructName}}) Execute() { buffer, begin, end := p.Buffer, 0, 0 - {{if .HasYY}} + {{if .HasVariable}} var yy YYSTYPE stack := make([]YYSTYPE, 0) {{end}} @@ -398,6 +402,12 @@ func (p *{{.StructName}}) Execute() { {{range .Actions}}case RuleAction{{.GetId}}: {{.String}} {{end}} + {{if .HasVariable}} + case RuleActionPush: + stack = append(stack, yy) + case RuleActionPop: + stack = stack[0:len(stack)-1] + {{end}} } } } @@ -561,6 +571,9 @@ type Node interface { GetId() int SetId(id int) + HasVariable() bool + HasYY() bool + Init() Front() *node Next() *node @@ -576,6 +589,8 @@ type node struct { Type string id int + hasVariable bool + hasYY bool front *node back *node @@ -617,6 +632,14 @@ func (n *node) SetId(id int) { n.id = id } +func (n *node) HasVariable() bool { + return n.hasVariable +} + +func (n *node) HasYY() bool { + return n.hasYY +} + func (n *node) Init() { n.front = nil n.back = nil @@ -708,7 +731,7 @@ type Tree struct { HasCharacter bool HasString bool HasRange bool - HasYY bool + HasVariable bool } func New(inline, _switch bool) *Tree { @@ -843,12 +866,14 @@ func (t *Tree) Compile(file string) { t.EndSymbol = '\u0004' t.RulesCount++ + hasVariable := false + hasYY := false counts := [TypeLast]uint{} { var rule *node var traverse func(node Node) int var link func(node Node) - hasYY := false + // Modify actions which use named semantic variables // Use DFS traversal to find TypeVariable and TypeAction @@ -861,10 +886,10 @@ func (t *Tree) Compile(file string) { return 0 } for { - // fmt.Println(TypeMap[leaf.GetType()]) switch leaf.GetType() { case TypeName: if leaf.Front()!=nil && leaf.Front().GetType()==TypeVariable { + hasVariable = true variableCount++ var_stack = append(var_stack, leaf.Front().String()) } @@ -885,7 +910,7 @@ func (t *Tree) Compile(file string) { hasReplaced := false for i, var_element := range var_stack { if var_element == varname { - tempStr = append(tempStr,fmt.Sprintf("stack[len(stack)-%d]", i+1)) + tempStr = append(tempStr,fmt.Sprintf("stack[len(stack)-%d]", len(var_stack)-i)) hasReplaced = true break } @@ -902,14 +927,10 @@ func (t *Tree) Compile(file string) { case TypeSequence: next_level_count = traverse(leaf) if n.GetType()==TypeAlternate && next_level_count > 0{ - // fmt.Println(next_level_count,":",var_stack) - // tempStr := []string { rule.String(), ";stack = stack[0:(len(stack)-", - // strconv.Itoa(next_level_count), ")]"} - // rule.SetString(strings.Join(tempStr,"")) var_stack = var_stack[0:(len(var_stack)-next_level_count)] } case TypeAlternate: - next_level_count = traverse(leaf) + traverse(leaf) // Fix types case TypePeekFor: @@ -937,22 +958,16 @@ func (t *Tree) Compile(file string) { traverse_node := t.Front() for { + hasVariable = false hasYY = false var_stack = make([]string, 0) - stackCount := traverse(traverse_node) - if traverse_node.Front() != nil && rule != nil && hasYY { - t.HasYY = true - if traverse_node.Front().GetType() != TypeSequence { - expression := traverse_node.PopFront() - sequence := &node{Type: TypeSequence} - sequence.PushBack(expression) - traverse_node.PushBack(sequence) - } - tempStr := []string {"stack = stack[0:(len(stack)-", - strconv.Itoa(stackCount), ")]; stack = append(stack, yy)"} - traverse_node.Front().PushBack(&node{Type: TypeAction, string: strings.Join(tempStr,"")}) - // fmt.Println(TypeMap[traverse_node.Front().GetType()]) - // fmt.Println(tempStr) + traverse(traverse_node) + if hasVariable { + traverse_node.hasVariable = true + t.HasVariable = true + } + if hasYY { + traverse_node.hasYY = true } rule = nil if traverse_node.Next() == nil { @@ -1445,6 +1460,11 @@ func (t *Tree) Compile(file string) { fmt.Fprintf(os.Stderr, "illegal node type: %v\n", n.GetType()) } } + printClearStack := func(n Node) { + print("\n for i:=0; i Date: Thu, 13 Mar 2014 01:22:43 +0800 Subject: [PATCH 09/13] Rewritten Makefile and restructure directory hierarchy --- Makefile | 30 +- bootstrap.peg.go | 2844 -------------- bootstrap/leg/leg.go | 1 - bootstrap/leg/leg.peg | 116 - grammars/c/Makefile | 12 - grammars/c/c.peg | 676 ---- grammars/c/main.go | 72 - grammars/calculator/Makefile | 12 - grammars/calculator/calculator.go | 102 - grammars/calculator/calculator.peg | 33 - grammars/fexl/Makefile | 12 - grammars/fexl/doc/NOTICE | 13 - grammars/fexl/doc/README | 80 - grammars/fexl/doc/try.fxl | 1024 ----- grammars/fexl/fexl.peg | 35 - grammars/fexl/main.go | 25 - grammars/java/Makefile | 12 - grammars/java/java_1_7.peg | 872 ----- grammars/java/main.go | 72 - .../{long_test => leg/calculator}/Makefile | 8 +- grammars/leg/calculator/calculator.leg | 40 + grammars/{ => leg}/calculator/main.go | 5 +- grammars/long_test/long.peg | 11 - grammars/long_test/main.go | 25 - peg.go | 1543 -------- peg.peg | 111 - src/bootstrap/leg/bootstrap.leg.go | 3362 +++++++++++++++++ src/bootstrap/leg/leg.go | 1 + {bootstrap => src/bootstrap}/leg/main.go | 0 {bootstrap => src/bootstrap}/leg/set.go | 0 src/leg/bootstrap.leg.go | 3362 +++++++++++++++++ leg.go => src/leg/leg.go | 0 src/leg/leg.leg | 117 + main.go => src/leg/main.go | 8 +- src/leg/set.go | 1 + set.go => src/set.go | 0 36 files changed, 6914 insertions(+), 7723 deletions(-) delete mode 100644 bootstrap.peg.go delete mode 120000 bootstrap/leg/leg.go delete mode 100644 bootstrap/leg/leg.peg delete mode 100644 grammars/c/Makefile delete mode 100644 grammars/c/c.peg delete mode 100644 grammars/c/main.go delete mode 100644 grammars/calculator/Makefile delete mode 100644 grammars/calculator/calculator.go delete mode 100644 grammars/calculator/calculator.peg delete mode 100644 grammars/fexl/Makefile delete mode 100644 grammars/fexl/doc/NOTICE delete mode 100644 grammars/fexl/doc/README delete mode 100755 grammars/fexl/doc/try.fxl delete mode 100644 grammars/fexl/fexl.peg delete mode 100644 grammars/fexl/main.go delete mode 100644 grammars/java/Makefile delete mode 100644 grammars/java/java_1_7.peg delete mode 100644 grammars/java/main.go rename grammars/{long_test => leg/calculator}/Makefile (55%) create mode 100644 grammars/leg/calculator/calculator.leg rename grammars/{ => leg}/calculator/main.go (82%) delete mode 100644 grammars/long_test/long.peg delete mode 100644 grammars/long_test/main.go delete mode 100644 peg.go delete mode 100644 peg.peg create mode 100644 src/bootstrap/leg/bootstrap.leg.go create mode 120000 src/bootstrap/leg/leg.go rename {bootstrap => src/bootstrap}/leg/main.go (100%) rename {bootstrap => src/bootstrap}/leg/set.go (100%) create mode 100644 src/leg/bootstrap.leg.go rename leg.go => src/leg/leg.go (100%) create mode 100644 src/leg/leg.leg rename main.go => src/leg/main.go (84%) create mode 120000 src/leg/set.go rename set.go => src/set.go (100%) diff --git a/Makefile b/Makefile index 7863c29..35d8ba2 100644 --- a/Makefile +++ b/Makefile @@ -2,16 +2,28 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -peg: bootstrap.peg.go peg.go main.go - go build +all: dirbin peg leg -bootstrap.peg.go: bootstrap/peg/main.go peg.go - cd bootstrap/peg; go build - bootstrap/peg/peg +dirbin: + mkdir -p bin -bootstrap.leg.go: bootstrap/leg/main.go leg.go - cd bootstrap/leg; go build - bootstrap/leg/leg +peg: src/peg/bootstrap.peg.go src/peg/peg.go src/peg/main.go + cd src/peg/; go build + mv src/peg/peg bin/ + +leg: src/leg/bootstrap.leg.go src/leg/leg.go src/leg/main.go + cd src/leg/; go build + mv src/leg/leg bin/ + +bootstrap.peg.go: src/bootstrap/peg/main.go src/peg/peg.go + cd src/bootstrap/peg; go build + src/bootstrap/peg/peg + mv src/bootstrap/peg/bootstrap.peg.go ./ + +bootstrap.leg.go: src/bootstrap/leg/main.go src/leg/leg.go + cd src/bootstrap/leg; go build + src/bootstrap/leg/leg + mv src/bootstrap/leg/bootstrap.leg.go ./ clean: - rm -f bootstrap/peg/peg bootstrap/leg/leg peg peg.peg.go + rm -f src/bootstrap/peg/peg src/bootstrap/leg/leg bin/peg bin/leg diff --git a/bootstrap.peg.go b/bootstrap.peg.go deleted file mode 100644 index 21d13bc..0000000 --- a/bootstrap.peg.go +++ /dev/null @@ -1,2844 +0,0 @@ -package main - -import ( - /*"bytes"*/ - "fmt" - "math" - "sort" - "strconv" -) - -const END_SYMBOL rune = 4 - -/* The rule types inferred from the grammar are below. */ -type Rule uint8 - -const ( - RuleUnknown Rule = iota - RuleGrammar - RuleDefinition - RuleExpression - RuleSequence - RulePrefix - RuleSuffix - RulePrimary - RuleIdentifier - RuleIdentStart - RuleIdentCont - RuleLiteral - RuleClass - RuleRanges - RuleDoubleRanges - RuleRange - RuleDoubleRange - RuleChar - RuleDoubleChar - RuleEscape - RuleLeftArrow - RuleSlash - RuleAnd - RuleNot - RuleQuestion - RuleStar - RulePlus - RuleOpen - RuleClose - RuleDot - RuleSpacing - RuleComment - RuleSpace - RuleEndOfLine - RuleEndOfFile - RuleAction - RuleBegin - RuleEnd - RuleAction0 - RuleAction1 - RuleAction2 - RuleAction3 - RuleAction4 - RuleAction5 - RuleAction6 - RuleAction7 - RuleAction8 - RuleAction9 - RuleAction10 - RuleAction11 - RuleAction12 - RuleAction13 - RuleAction14 - RuleAction15 - RuleAction16 - RuleAction17 - RuleAction18 - RulePegText - RuleAction19 - RuleAction20 - RuleAction21 - RuleAction22 - RuleAction23 - RuleAction24 - RuleAction25 - RuleAction26 - RuleAction27 - RuleAction28 - RuleAction29 - RuleAction30 - RuleAction31 - RuleAction32 - RuleAction33 - RuleAction34 - RuleAction35 - RuleAction36 - RuleAction37 - RuleAction38 - RuleAction39 - RuleAction40 - RuleAction41 - RuleAction42 - RuleAction43 - RuleAction44 - RuleAction45 - - RulePre_ - Rule_In_ - Rule_Suf -) - -var Rul3s = [...]string{ - "Unknown", - "Grammar", - "Definition", - "Expression", - "Sequence", - "Prefix", - "Suffix", - "Primary", - "Identifier", - "IdentStart", - "IdentCont", - "Literal", - "Class", - "Ranges", - "DoubleRanges", - "Range", - "DoubleRange", - "Char", - "DoubleChar", - "Escape", - "LeftArrow", - "Slash", - "And", - "Not", - "Question", - "Star", - "Plus", - "Open", - "Close", - "Dot", - "Spacing", - "Comment", - "Space", - "EndOfLine", - "EndOfFile", - "Action", - "Begin", - "End", - "Action0", - "Action1", - "Action2", - "Action3", - "Action4", - "Action5", - "Action6", - "Action7", - "Action8", - "Action9", - "Action10", - "Action11", - "Action12", - "Action13", - "Action14", - "Action15", - "Action16", - "Action17", - "Action18", - "PegText", - "Action19", - "Action20", - "Action21", - "Action22", - "Action23", - "Action24", - "Action25", - "Action26", - "Action27", - "Action28", - "Action29", - "Action30", - "Action31", - "Action32", - "Action33", - "Action34", - "Action35", - "Action36", - "Action37", - "Action38", - "Action39", - "Action40", - "Action41", - "Action42", - "Action43", - "Action44", - "Action45", - - "Pre_", - "_In_", - "_Suf", -} - -type TokenTree interface { - Print() - PrintSyntax() - PrintSyntaxTree(buffer string) - Add(rule Rule, begin, end, next, depth int) - Expand(index int) TokenTree - Tokens() <-chan token32 - Error() []token32 - trim(length int) -} - -/* ${@} bit structure for abstract syntax tree */ -type token16 struct { - Rule - begin, end, next int16 -} - -func (t *token16) isZero() bool { - return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 -} - -func (t *token16) isParentOf(u token16) bool { - return t.begin <= u.begin && t.end >= u.end && t.next > u.next -} - -func (t *token16) GetToken32() token32 { - return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} -} - -func (t *token16) String() string { - return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) -} - -type tokens16 struct { - tree []token16 - ordered [][]token16 -} - -func (t *tokens16) trim(length int) { - t.tree = t.tree[0:length] -} - -func (t *tokens16) Print() { - for _, token := range t.tree { - fmt.Println(token.String()) - } -} - -func (t *tokens16) Order() [][]token16 { - if t.ordered != nil { - return t.ordered - } - - depths := make([]int16, 1, math.MaxInt16) - for i, token := range t.tree { - if token.Rule == RuleUnknown { - t.tree = t.tree[:i] - break - } - depth := int(token.next) - if length := len(depths); depth >= length { - depths = depths[:depth+1] - } - depths[depth]++ - } - depths = append(depths, 0) - - ordered, pool := make([][]token16, len(depths)), make([]token16, len(t.tree)+len(depths)) - for i, depth := range depths { - depth++ - ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 - } - - for i, token := range t.tree { - depth := token.next - token.next = int16(i) - ordered[depth][depths[depth]] = token - depths[depth]++ - } - t.ordered = ordered - return ordered -} - -type State16 struct { - token16 - depths []int16 - leaf bool -} - -func (t *tokens16) PreOrder() (<-chan State16, [][]token16) { - s, ordered := make(chan State16, 6), t.Order() - go func() { - var states [8]State16 - for i, _ := range states { - states[i].depths = make([]int16, len(ordered)) - } - depths, state, depth := make([]int16, len(ordered)), 0, 1 - write := func(t token16, leaf bool) { - S := states[state] - state, S.Rule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.Rule, t.begin, t.end, int16(depth), leaf - copy(S.depths, depths) - s <- S - } - - states[state].token16 = ordered[0][0] - depths[0]++ - state++ - a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] - depthFirstSearch: - for { - for { - if i := depths[depth]; i > 0 { - if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && - (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { - if c.end != b.begin { - write(token16{Rule: Rule_In_, begin: c.end, end: b.begin}, true) - } - break - } - } - - if a.begin < b.begin { - write(token16{Rule: RulePre_, begin: a.begin, end: b.begin}, true) - } - break - } - - next := depth + 1 - if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { - write(b, false) - depths[depth]++ - depth, a, b = next, b, c - continue - } - - write(b, true) - depths[depth]++ - c, parent := ordered[depth][depths[depth]], true - for { - if c.Rule != RuleUnknown && a.isParentOf(c) { - b = c - continue depthFirstSearch - } else if parent && b.end != a.end { - write(token16{Rule: Rule_Suf, begin: b.end, end: a.end}, true) - } - - depth-- - if depth > 0 { - a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] - parent = a.isParentOf(b) - continue - } - - break depthFirstSearch - } - } - - close(s) - }() - return s, ordered -} - -func (t *tokens16) PrintSyntax() { - tokens, ordered := t.PreOrder() - max := -1 - for token := range tokens { - if !token.leaf { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) - } - fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) - } else if token.begin == token.end { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) - } - fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) - } else { - for c, end := token.begin, token.end; c < end; c++ { - if i := int(c); max+1 < i { - for j := max; j < i; j++ { - fmt.Printf("skip %v %v\n", j, token.String()) - } - max = i - } else if i := int(c); i <= max { - for j := i; j <= max; j++ { - fmt.Printf("dupe %v %v\n", j, token.String()) - } - } else { - max = int(c) - } - fmt.Printf("%v", c) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) - } - fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) - } - fmt.Printf("\n") - } - } -} - -func (t *tokens16) PrintSyntaxTree(buffer string) { - tokens, _ := t.PreOrder() - for token := range tokens { - for c := 0; c < int(token.next); c++ { - fmt.Printf(" ") - } - fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) - } -} - -func (t *tokens16) Add(rule Rule, begin, end, depth, index int) { - t.tree[index] = token16{Rule: rule, begin: int16(begin), end: int16(end), next: int16(depth)} -} - -func (t *tokens16) Tokens() <-chan token32 { - s := make(chan token32, 16) - go func() { - for _, v := range t.tree { - s <- v.GetToken32() - } - close(s) - }() - return s -} - -func (t *tokens16) Error() []token32 { - ordered := t.Order() - length := len(ordered) - tokens, length := make([]token32, length), length-1 - for i, _ := range tokens { - o := ordered[length-i] - if len(o) > 1 { - tokens[i] = o[len(o)-2].GetToken32() - } - } - return tokens -} - -/* ${@} bit structure for abstract syntax tree */ -type token32 struct { - Rule - begin, end, next int32 -} - -func (t *token32) isZero() bool { - return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 -} - -func (t *token32) isParentOf(u token32) bool { - return t.begin <= u.begin && t.end >= u.end && t.next > u.next -} - -func (t *token32) GetToken32() token32 { - return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} -} - -func (t *token32) String() string { - return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) -} - -type tokens32 struct { - tree []token32 - ordered [][]token32 -} - -func (t *tokens32) trim(length int) { - t.tree = t.tree[0:length] -} - -func (t *tokens32) Print() { - for _, token := range t.tree { - fmt.Println(token.String()) - } -} - -func (t *tokens32) Order() [][]token32 { - if t.ordered != nil { - return t.ordered - } - - depths := make([]int32, 1, math.MaxInt16) - for i, token := range t.tree { - if token.Rule == RuleUnknown { - t.tree = t.tree[:i] - break - } - depth := int(token.next) - if length := len(depths); depth >= length { - depths = depths[:depth+1] - } - depths[depth]++ - } - depths = append(depths, 0) - - ordered, pool := make([][]token32, len(depths)), make([]token32, len(t.tree)+len(depths)) - for i, depth := range depths { - depth++ - ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 - } - - for i, token := range t.tree { - depth := token.next - token.next = int32(i) - ordered[depth][depths[depth]] = token - depths[depth]++ - } - t.ordered = ordered - return ordered -} - -type State32 struct { - token32 - depths []int32 - leaf bool -} - -func (t *tokens32) PreOrder() (<-chan State32, [][]token32) { - s, ordered := make(chan State32, 6), t.Order() - go func() { - var states [8]State32 - for i, _ := range states { - states[i].depths = make([]int32, len(ordered)) - } - depths, state, depth := make([]int32, len(ordered)), 0, 1 - write := func(t token32, leaf bool) { - S := states[state] - state, S.Rule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.Rule, t.begin, t.end, int32(depth), leaf - copy(S.depths, depths) - s <- S - } - - states[state].token32 = ordered[0][0] - depths[0]++ - state++ - a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] - depthFirstSearch: - for { - for { - if i := depths[depth]; i > 0 { - if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && - (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { - if c.end != b.begin { - write(token32{Rule: Rule_In_, begin: c.end, end: b.begin}, true) - } - break - } - } - - if a.begin < b.begin { - write(token32{Rule: RulePre_, begin: a.begin, end: b.begin}, true) - } - break - } - - next := depth + 1 - if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { - write(b, false) - depths[depth]++ - depth, a, b = next, b, c - continue - } - - write(b, true) - depths[depth]++ - c, parent := ordered[depth][depths[depth]], true - for { - if c.Rule != RuleUnknown && a.isParentOf(c) { - b = c - continue depthFirstSearch - } else if parent && b.end != a.end { - write(token32{Rule: Rule_Suf, begin: b.end, end: a.end}, true) - } - - depth-- - if depth > 0 { - a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] - parent = a.isParentOf(b) - continue - } - - break depthFirstSearch - } - } - - close(s) - }() - return s, ordered -} - -func (t *tokens32) PrintSyntax() { - tokens, ordered := t.PreOrder() - max := -1 - for token := range tokens { - if !token.leaf { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) - } - fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) - } else if token.begin == token.end { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) - } - fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) - } else { - for c, end := token.begin, token.end; c < end; c++ { - if i := int(c); max+1 < i { - for j := max; j < i; j++ { - fmt.Printf("skip %v %v\n", j, token.String()) - } - max = i - } else if i := int(c); i <= max { - for j := i; j <= max; j++ { - fmt.Printf("dupe %v %v\n", j, token.String()) - } - } else { - max = int(c) - } - fmt.Printf("%v", c) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) - } - fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) - } - fmt.Printf("\n") - } - } -} - -func (t *tokens32) PrintSyntaxTree(buffer string) { - tokens, _ := t.PreOrder() - for token := range tokens { - for c := 0; c < int(token.next); c++ { - fmt.Printf(" ") - } - fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) - } -} - -func (t *tokens32) Add(rule Rule, begin, end, depth, index int) { - t.tree[index] = token32{Rule: rule, begin: int32(begin), end: int32(end), next: int32(depth)} -} - -func (t *tokens32) Tokens() <-chan token32 { - s := make(chan token32, 16) - go func() { - for _, v := range t.tree { - s <- v.GetToken32() - } - close(s) - }() - return s -} - -func (t *tokens32) Error() []token32 { - ordered := t.Order() - length := len(ordered) - tokens, length := make([]token32, length), length-1 - for i, _ := range tokens { - o := ordered[length-i] - if len(o) > 1 { - tokens[i] = o[len(o)-2].GetToken32() - } - } - return tokens -} - -func (t *tokens16) Expand(index int) TokenTree { - tree := t.tree - if index >= len(tree) { - expanded := make([]token32, 2*len(tree)) - for i, v := range tree { - expanded[i] = v.GetToken32() - } - return &tokens32{tree: expanded} - } - return nil -} - -func (t *tokens32) Expand(index int) TokenTree { - tree := t.tree - if index >= len(tree) { - expanded := make([]token32, 2*len(tree)) - copy(expanded, tree) - t.tree = expanded - } - return nil -} - -type Peg struct { - *Tree - - Buffer string - buffer []rune - rules [85]func() bool - Parse func(rule ...int) error - Reset func() - TokenTree -} - -type textPosition struct { - line, symbol int -} - -type textPositionMap map[int]textPosition - -func translatePositions(buffer string, positions []int) textPositionMap { - length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 - sort.Ints(positions) - -search: - for i, c := range buffer[0:] { - if c == '\n' { - line, symbol = line+1, 0 - } else { - symbol++ - } - if i == positions[j] { - translations[positions[j]] = textPosition{line, symbol} - for j++; j < length; j++ { - if i != positions[j] { - continue search - } - } - break search - } - } - - return translations -} - -type parseError struct { - p *Peg -} - -func (e *parseError) Error() string { - tokens, error := e.p.TokenTree.Error(), "\n" - positions, p := make([]int, 2*len(tokens)), 0 - for _, token := range tokens { - positions[p], p = int(token.begin), p+1 - positions[p], p = int(token.end), p+1 - } - translations := translatePositions(e.p.Buffer, positions) - for _, token := range tokens { - begin, end := int(token.begin), int(token.end) - error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", - Rul3s[token.Rule], - translations[begin].line, translations[begin].symbol, - translations[end].line, translations[end].symbol, - /*strconv.Quote(*/ e.p.Buffer[begin:end] /*)*/) - } - - return error -} - -func (p *Peg) PrintSyntaxTree() { - p.TokenTree.PrintSyntaxTree(p.Buffer) -} - -func (p *Peg) Highlighter() { - p.TokenTree.PrintSyntax() -} - -func (p *Peg) Execute() { - buffer, begin, end := p.Buffer, 0, 0 - for token := range p.TokenTree.Tokens() { - switch token.Rule { - case RulePegText: - begin, end = int(token.begin), int(token.end) - case RuleAction0: - p.AddPackage(buffer[begin:end]) - case RuleAction1: - p.AddPeg(buffer[begin:end]) - case RuleAction2: - p.AddState(buffer[begin:end]) - case RuleAction3: - p.AddRule(buffer[begin:end]) - case RuleAction4: - p.AddExpression() - case RuleAction5: - p.AddAlternate() - case RuleAction6: - p.AddNil() - p.AddAlternate() - case RuleAction7: - p.AddNil() - case RuleAction8: - p.AddSequence() - case RuleAction9: - p.AddPredicate(buffer[begin:end]) - case RuleAction10: - p.AddPeekFor() - case RuleAction11: - p.AddPeekNot() - case RuleAction12: - p.AddQuery() - case RuleAction13: - p.AddStar() - case RuleAction14: - p.AddPlus() - case RuleAction15: - p.AddName(buffer[begin:end]) - case RuleAction16: - p.AddDot() - case RuleAction17: - p.AddAction(buffer[begin:end]) - case RuleAction18: - p.AddPush() - case RuleAction19: - p.AddSequence() - case RuleAction20: - p.AddSequence() - case RuleAction21: - p.AddPeekNot() - p.AddDot() - p.AddSequence() - case RuleAction22: - p.AddPeekNot() - p.AddDot() - p.AddSequence() - case RuleAction23: - p.AddAlternate() - case RuleAction24: - p.AddAlternate() - case RuleAction25: - p.AddRange() - case RuleAction26: - p.AddDoubleRange() - case RuleAction27: - p.AddCharacter(buffer[begin:end]) - case RuleAction28: - p.AddDoubleCharacter(buffer[begin:end]) - case RuleAction29: - p.AddCharacter(buffer[begin:end]) - case RuleAction30: - p.AddCharacter("\a") - case RuleAction31: - p.AddCharacter("\b") - case RuleAction32: - p.AddCharacter("\x1B") - case RuleAction33: - p.AddCharacter("\f") - case RuleAction34: - p.AddCharacter("\n") - case RuleAction35: - p.AddCharacter("\r") - case RuleAction36: - p.AddCharacter("\t") - case RuleAction37: - p.AddCharacter("\v") - case RuleAction38: - p.AddCharacter("'") - case RuleAction39: - p.AddCharacter("\"") - case RuleAction40: - p.AddCharacter("[") - case RuleAction41: - p.AddCharacter("]") - case RuleAction42: - p.AddCharacter("-") - case RuleAction43: - p.AddOctalCharacter(buffer[begin:end]) - case RuleAction44: - p.AddOctalCharacter(buffer[begin:end]) - case RuleAction45: - p.AddCharacter("\\") - - } - } -} - -func (p *Peg) Init() { - p.buffer = []rune(p.Buffer) - if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != END_SYMBOL { - p.buffer = append(p.buffer, END_SYMBOL) - } - - var tree TokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} - position, depth, tokenIndex, buffer, rules := 0, 0, 0, p.buffer, p.rules - - p.Parse = func(rule ...int) error { - r := 1 - if len(rule) > 0 { - r = rule[0] - } - matches := p.rules[r]() - p.TokenTree = tree - if matches { - p.TokenTree.trim(tokenIndex) - return nil - } - return &parseError{p} - } - - p.Reset = func() { - position, tokenIndex, depth = 0, 0, 0 - } - - add := func(rule Rule, begin int) { - if t := tree.Expand(tokenIndex); t != nil { - tree = t - } - tree.Add(rule, begin, position, depth, tokenIndex) - tokenIndex++ - } - - matchDot := func() bool { - if buffer[position] != END_SYMBOL { - position++ - return true - } - return false - } - - /*matchChar := func(c byte) bool { - if buffer[position] == c { - position++ - return true - } - return false - }*/ - - /*matchRange := func(lower byte, upper byte) bool { - if c := buffer[position]; c >= lower && c <= upper { - position++ - return true - } - return false - }*/ - - rules = [...]func() bool{ - nil, - /* 0 Grammar <- <(Spacing ('p' 'a' 'c' 'k' 'a' 'g' 'e') Spacing Identifier Action0 ('t' 'y' 'p' 'e') Spacing Identifier Action1 ('P' 'e' 'g') Spacing Action Action2 Definition+ EndOfFile)> */ - func() bool { - position0, tokenIndex0, depth0 := position, tokenIndex, depth - { - position1 := position - depth++ - if !rules[RuleSpacing]() { - goto l0 - } - if buffer[position] != rune('p') { - goto l0 - } - position++ - if buffer[position] != rune('a') { - goto l0 - } - position++ - if buffer[position] != rune('c') { - goto l0 - } - position++ - if buffer[position] != rune('k') { - goto l0 - } - position++ - if buffer[position] != rune('a') { - goto l0 - } - position++ - if buffer[position] != rune('g') { - goto l0 - } - position++ - if buffer[position] != rune('e') { - goto l0 - } - position++ - if !rules[RuleSpacing]() { - goto l0 - } - if !rules[RuleIdentifier]() { - goto l0 - } - { - add(RuleAction0, position) - } - if buffer[position] != rune('t') { - goto l0 - } - position++ - if buffer[position] != rune('y') { - goto l0 - } - position++ - if buffer[position] != rune('p') { - goto l0 - } - position++ - if buffer[position] != rune('e') { - goto l0 - } - position++ - if !rules[RuleSpacing]() { - goto l0 - } - if !rules[RuleIdentifier]() { - goto l0 - } - { - add(RuleAction1, position) - } - if buffer[position] != rune('P') { - goto l0 - } - position++ - if buffer[position] != rune('e') { - goto l0 - } - position++ - if buffer[position] != rune('g') { - goto l0 - } - position++ - if !rules[RuleSpacing]() { - goto l0 - } - if !rules[RuleAction]() { - goto l0 - } - { - add(RuleAction2, position) - } - { - position7 := position - depth++ - if !rules[RuleIdentifier]() { - goto l0 - } - { - add(RuleAction3, position) - } - if !rules[RuleLeftArrow]() { - goto l0 - } - if !rules[RuleExpression]() { - goto l0 - } - { - add(RuleAction4, position) - } - { - position10, tokenIndex10, depth10 := position, tokenIndex, depth - { - position11, tokenIndex11, depth11 := position, tokenIndex, depth - if !rules[RuleIdentifier]() { - goto l12 - } - if !rules[RuleLeftArrow]() { - goto l12 - } - goto l11 - l12: - position, tokenIndex, depth = position11, tokenIndex11, depth11 - { - position13, tokenIndex13, depth13 := position, tokenIndex, depth - if !matchDot() { - goto l13 - } - goto l0 - l13: - position, tokenIndex, depth = position13, tokenIndex13, depth13 - } - } - l11: - position, tokenIndex, depth = position10, tokenIndex10, depth10 - } - depth-- - add(RuleDefinition, position7) - } - l5: - { - position6, tokenIndex6, depth6 := position, tokenIndex, depth - { - position14 := position - depth++ - if !rules[RuleIdentifier]() { - goto l6 - } - { - add(RuleAction3, position) - } - if !rules[RuleLeftArrow]() { - goto l6 - } - if !rules[RuleExpression]() { - goto l6 - } - { - add(RuleAction4, position) - } - { - position17, tokenIndex17, depth17 := position, tokenIndex, depth - { - position18, tokenIndex18, depth18 := position, tokenIndex, depth - if !rules[RuleIdentifier]() { - goto l19 - } - if !rules[RuleLeftArrow]() { - goto l19 - } - goto l18 - l19: - position, tokenIndex, depth = position18, tokenIndex18, depth18 - { - position20, tokenIndex20, depth20 := position, tokenIndex, depth - if !matchDot() { - goto l20 - } - goto l6 - l20: - position, tokenIndex, depth = position20, tokenIndex20, depth20 - } - } - l18: - position, tokenIndex, depth = position17, tokenIndex17, depth17 - } - depth-- - add(RuleDefinition, position14) - } - goto l5 - l6: - position, tokenIndex, depth = position6, tokenIndex6, depth6 - } - { - position21 := position - depth++ - { - position22, tokenIndex22, depth22 := position, tokenIndex, depth - if !matchDot() { - goto l22 - } - goto l0 - l22: - position, tokenIndex, depth = position22, tokenIndex22, depth22 - } - depth-- - add(RuleEndOfFile, position21) - } - depth-- - add(RuleGrammar, position1) - } - return true - l0: - position, tokenIndex, depth = position0, tokenIndex0, depth0 - return false - }, - /* 1 Definition <- <(Identifier Action3 LeftArrow Expression Action4 &((Identifier LeftArrow) / !.))> */ - nil, - /* 2 Expression <- <((Sequence (Slash Sequence Action5)* (Slash Action6)?) / Action7)> */ - func() bool { - { - position25 := position - depth++ - { - position26, tokenIndex26, depth26 := position, tokenIndex, depth - if !rules[RuleSequence]() { - goto l27 - } - l28: - { - position29, tokenIndex29, depth29 := position, tokenIndex, depth - if !rules[RuleSlash]() { - goto l29 - } - if !rules[RuleSequence]() { - goto l29 - } - { - add(RuleAction5, position) - } - goto l28 - l29: - position, tokenIndex, depth = position29, tokenIndex29, depth29 - } - { - position31, tokenIndex31, depth31 := position, tokenIndex, depth - if !rules[RuleSlash]() { - goto l31 - } - { - add(RuleAction6, position) - } - goto l32 - l31: - position, tokenIndex, depth = position31, tokenIndex31, depth31 - } - l32: - goto l26 - l27: - position, tokenIndex, depth = position26, tokenIndex26, depth26 - { - add(RuleAction7, position) - } - } - l26: - depth-- - add(RuleExpression, position25) - } - return true - }, - /* 3 Sequence <- <(Prefix (Prefix Action8)*)> */ - func() bool { - position35, tokenIndex35, depth35 := position, tokenIndex, depth - { - position36 := position - depth++ - if !rules[RulePrefix]() { - goto l35 - } - l37: - { - position38, tokenIndex38, depth38 := position, tokenIndex, depth - if !rules[RulePrefix]() { - goto l38 - } - { - add(RuleAction8, position) - } - goto l37 - l38: - position, tokenIndex, depth = position38, tokenIndex38, depth38 - } - depth-- - add(RuleSequence, position36) - } - return true - l35: - position, tokenIndex, depth = position35, tokenIndex35, depth35 - return false - }, - /* 4 Prefix <- <((And Action Action9) / ((&('!') (Not Suffix Action11)) | (&('&') (And Suffix Action10)) | (&('"' | '\'' | '(' | '.' | '<' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[' | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{') Suffix)))> */ - func() bool { - position40, tokenIndex40, depth40 := position, tokenIndex, depth - { - position41 := position - depth++ - { - position42, tokenIndex42, depth42 := position, tokenIndex, depth - if !rules[RuleAnd]() { - goto l43 - } - if !rules[RuleAction]() { - goto l43 - } - { - add(RuleAction9, position) - } - goto l42 - l43: - position, tokenIndex, depth = position42, tokenIndex42, depth42 - { - switch buffer[position] { - case '!': - { - position46 := position - depth++ - if buffer[position] != rune('!') { - goto l40 - } - position++ - if !rules[RuleSpacing]() { - goto l40 - } - depth-- - add(RuleNot, position46) - } - if !rules[RuleSuffix]() { - goto l40 - } - { - add(RuleAction11, position) - } - break - case '&': - if !rules[RuleAnd]() { - goto l40 - } - if !rules[RuleSuffix]() { - goto l40 - } - { - add(RuleAction10, position) - } - break - default: - if !rules[RuleSuffix]() { - goto l40 - } - break - } - } - - } - l42: - depth-- - add(RulePrefix, position41) - } - return true - l40: - position, tokenIndex, depth = position40, tokenIndex40, depth40 - return false - }, - /* 5 Suffix <- <(Primary ((&('+') (Plus Action14)) | (&('*') (Star Action13)) | (&('?') (Question Action12)))?)> */ - func() bool { - position49, tokenIndex49, depth49 := position, tokenIndex, depth - { - position50 := position - depth++ - { - position51 := position - depth++ - { - switch buffer[position] { - case '<': - { - position53 := position - depth++ - if buffer[position] != rune('<') { - goto l49 - } - position++ - if !rules[RuleSpacing]() { - goto l49 - } - depth-- - add(RuleBegin, position53) - } - if !rules[RuleExpression]() { - goto l49 - } - { - position54 := position - depth++ - if buffer[position] != rune('>') { - goto l49 - } - position++ - if !rules[RuleSpacing]() { - goto l49 - } - depth-- - add(RuleEnd, position54) - } - { - add(RuleAction18, position) - } - break - case '{': - if !rules[RuleAction]() { - goto l49 - } - { - add(RuleAction17, position) - } - break - case '.': - { - position57 := position - depth++ - if buffer[position] != rune('.') { - goto l49 - } - position++ - if !rules[RuleSpacing]() { - goto l49 - } - depth-- - add(RuleDot, position57) - } - { - add(RuleAction16, position) - } - break - case '[': - { - position59 := position - depth++ - { - position60, tokenIndex60, depth60 := position, tokenIndex, depth - if buffer[position] != rune('[') { - goto l61 - } - position++ - if buffer[position] != rune('[') { - goto l61 - } - position++ - { - position62, tokenIndex62, depth62 := position, tokenIndex, depth - { - position64, tokenIndex64, depth64 := position, tokenIndex, depth - if buffer[position] != rune('^') { - goto l65 - } - position++ - if !rules[RuleDoubleRanges]() { - goto l65 - } - { - add(RuleAction21, position) - } - goto l64 - l65: - position, tokenIndex, depth = position64, tokenIndex64, depth64 - if !rules[RuleDoubleRanges]() { - goto l62 - } - } - l64: - goto l63 - l62: - position, tokenIndex, depth = position62, tokenIndex62, depth62 - } - l63: - if buffer[position] != rune(']') { - goto l61 - } - position++ - if buffer[position] != rune(']') { - goto l61 - } - position++ - goto l60 - l61: - position, tokenIndex, depth = position60, tokenIndex60, depth60 - if buffer[position] != rune('[') { - goto l49 - } - position++ - { - position67, tokenIndex67, depth67 := position, tokenIndex, depth - { - position69, tokenIndex69, depth69 := position, tokenIndex, depth - if buffer[position] != rune('^') { - goto l70 - } - position++ - if !rules[RuleRanges]() { - goto l70 - } - { - add(RuleAction22, position) - } - goto l69 - l70: - position, tokenIndex, depth = position69, tokenIndex69, depth69 - if !rules[RuleRanges]() { - goto l67 - } - } - l69: - goto l68 - l67: - position, tokenIndex, depth = position67, tokenIndex67, depth67 - } - l68: - if buffer[position] != rune(']') { - goto l49 - } - position++ - } - l60: - if !rules[RuleSpacing]() { - goto l49 - } - depth-- - add(RuleClass, position59) - } - break - case '"', '\'': - { - position72 := position - depth++ - { - position73, tokenIndex73, depth73 := position, tokenIndex, depth - if buffer[position] != rune('\'') { - goto l74 - } - position++ - { - position75, tokenIndex75, depth75 := position, tokenIndex, depth - { - position77, tokenIndex77, depth77 := position, tokenIndex, depth - if buffer[position] != rune('\'') { - goto l77 - } - position++ - goto l75 - l77: - position, tokenIndex, depth = position77, tokenIndex77, depth77 - } - if !rules[RuleChar]() { - goto l75 - } - goto l76 - l75: - position, tokenIndex, depth = position75, tokenIndex75, depth75 - } - l76: - l78: - { - position79, tokenIndex79, depth79 := position, tokenIndex, depth - { - position80, tokenIndex80, depth80 := position, tokenIndex, depth - if buffer[position] != rune('\'') { - goto l80 - } - position++ - goto l79 - l80: - position, tokenIndex, depth = position80, tokenIndex80, depth80 - } - if !rules[RuleChar]() { - goto l79 - } - { - add(RuleAction19, position) - } - goto l78 - l79: - position, tokenIndex, depth = position79, tokenIndex79, depth79 - } - if buffer[position] != rune('\'') { - goto l74 - } - position++ - if !rules[RuleSpacing]() { - goto l74 - } - goto l73 - l74: - position, tokenIndex, depth = position73, tokenIndex73, depth73 - if buffer[position] != rune('"') { - goto l49 - } - position++ - { - position82, tokenIndex82, depth82 := position, tokenIndex, depth - { - position84, tokenIndex84, depth84 := position, tokenIndex, depth - if buffer[position] != rune('"') { - goto l84 - } - position++ - goto l82 - l84: - position, tokenIndex, depth = position84, tokenIndex84, depth84 - } - if !rules[RuleDoubleChar]() { - goto l82 - } - goto l83 - l82: - position, tokenIndex, depth = position82, tokenIndex82, depth82 - } - l83: - l85: - { - position86, tokenIndex86, depth86 := position, tokenIndex, depth - { - position87, tokenIndex87, depth87 := position, tokenIndex, depth - if buffer[position] != rune('"') { - goto l87 - } - position++ - goto l86 - l87: - position, tokenIndex, depth = position87, tokenIndex87, depth87 - } - if !rules[RuleDoubleChar]() { - goto l86 - } - { - add(RuleAction20, position) - } - goto l85 - l86: - position, tokenIndex, depth = position86, tokenIndex86, depth86 - } - if buffer[position] != rune('"') { - goto l49 - } - position++ - if !rules[RuleSpacing]() { - goto l49 - } - } - l73: - depth-- - add(RuleLiteral, position72) - } - break - case '(': - { - position89 := position - depth++ - if buffer[position] != rune('(') { - goto l49 - } - position++ - if !rules[RuleSpacing]() { - goto l49 - } - depth-- - add(RuleOpen, position89) - } - if !rules[RuleExpression]() { - goto l49 - } - { - position90 := position - depth++ - if buffer[position] != rune(')') { - goto l49 - } - position++ - if !rules[RuleSpacing]() { - goto l49 - } - depth-- - add(RuleClose, position90) - } - break - default: - if !rules[RuleIdentifier]() { - goto l49 - } - { - position91, tokenIndex91, depth91 := position, tokenIndex, depth - if !rules[RuleLeftArrow]() { - goto l91 - } - goto l49 - l91: - position, tokenIndex, depth = position91, tokenIndex91, depth91 - } - { - add(RuleAction15, position) - } - break - } - } - - depth-- - add(RulePrimary, position51) - } - { - position93, tokenIndex93, depth93 := position, tokenIndex, depth - { - switch buffer[position] { - case '+': - { - position96 := position - depth++ - if buffer[position] != rune('+') { - goto l93 - } - position++ - if !rules[RuleSpacing]() { - goto l93 - } - depth-- - add(RulePlus, position96) - } - { - add(RuleAction14, position) - } - break - case '*': - { - position98 := position - depth++ - if buffer[position] != rune('*') { - goto l93 - } - position++ - if !rules[RuleSpacing]() { - goto l93 - } - depth-- - add(RuleStar, position98) - } - { - add(RuleAction13, position) - } - break - default: - { - position100 := position - depth++ - if buffer[position] != rune('?') { - goto l93 - } - position++ - if !rules[RuleSpacing]() { - goto l93 - } - depth-- - add(RuleQuestion, position100) - } - { - add(RuleAction12, position) - } - break - } - } - - goto l94 - l93: - position, tokenIndex, depth = position93, tokenIndex93, depth93 - } - l94: - depth-- - add(RuleSuffix, position50) - } - return true - l49: - position, tokenIndex, depth = position49, tokenIndex49, depth49 - return false - }, - /* 6 Primary <- <((&('<') (Begin Expression End Action18)) | (&('{') (Action Action17)) | (&('.') (Dot Action16)) | (&('[') Class) | (&('"' | '\'') Literal) | (&('(') (Open Expression Close)) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') (Identifier !LeftArrow Action15)))> */ - nil, - /* 7 Identifier <- <(<(IdentStart IdentCont*)> Spacing)> */ - func() bool { - position103, tokenIndex103, depth103 := position, tokenIndex, depth - { - position104 := position - depth++ - { - position105 := position - depth++ - if !rules[RuleIdentStart]() { - goto l103 - } - l106: - { - position107, tokenIndex107, depth107 := position, tokenIndex, depth - { - position108 := position - depth++ - { - position109, tokenIndex109, depth109 := position, tokenIndex, depth - if !rules[RuleIdentStart]() { - goto l110 - } - goto l109 - l110: - position, tokenIndex, depth = position109, tokenIndex109, depth109 - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l107 - } - position++ - } - l109: - depth-- - add(RuleIdentCont, position108) - } - goto l106 - l107: - position, tokenIndex, depth = position107, tokenIndex107, depth107 - } - depth-- - add(RulePegText, position105) - } - if !rules[RuleSpacing]() { - goto l103 - } - depth-- - add(RuleIdentifier, position104) - } - return true - l103: - position, tokenIndex, depth = position103, tokenIndex103, depth103 - return false - }, - /* 8 IdentStart <- <((&('_') '_') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]) | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]))> */ - func() bool { - position111, tokenIndex111, depth111 := position, tokenIndex, depth - { - position112 := position - depth++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l111 - } - position++ - break - case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l111 - } - position++ - break - default: - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l111 - } - position++ - break - } - } - - depth-- - add(RuleIdentStart, position112) - } - return true - l111: - position, tokenIndex, depth = position111, tokenIndex111, depth111 - return false - }, - /* 9 IdentCont <- <(IdentStart / [0-9])> */ - nil, - /* 10 Literal <- <(('\'' (!'\'' Char)? (!'\'' Char Action19)* '\'' Spacing) / ('"' (!'"' DoubleChar)? (!'"' DoubleChar Action20)* '"' Spacing))> */ - nil, - /* 11 Class <- <((('[' '[' (('^' DoubleRanges Action21) / DoubleRanges)? (']' ']')) / ('[' (('^' Ranges Action22) / Ranges)? ']')) Spacing)> */ - nil, - /* 12 Ranges <- <(!']' Range (!']' Range Action23)*)> */ - func() bool { - position117, tokenIndex117, depth117 := position, tokenIndex, depth - { - position118 := position - depth++ - { - position119, tokenIndex119, depth119 := position, tokenIndex, depth - if buffer[position] != rune(']') { - goto l119 - } - position++ - goto l117 - l119: - position, tokenIndex, depth = position119, tokenIndex119, depth119 - } - if !rules[RuleRange]() { - goto l117 - } - l120: - { - position121, tokenIndex121, depth121 := position, tokenIndex, depth - { - position122, tokenIndex122, depth122 := position, tokenIndex, depth - if buffer[position] != rune(']') { - goto l122 - } - position++ - goto l121 - l122: - position, tokenIndex, depth = position122, tokenIndex122, depth122 - } - if !rules[RuleRange]() { - goto l121 - } - { - add(RuleAction23, position) - } - goto l120 - l121: - position, tokenIndex, depth = position121, tokenIndex121, depth121 - } - depth-- - add(RuleRanges, position118) - } - return true - l117: - position, tokenIndex, depth = position117, tokenIndex117, depth117 - return false - }, - /* 13 DoubleRanges <- <(!(']' ']') DoubleRange (!(']' ']') DoubleRange Action24)*)> */ - func() bool { - position124, tokenIndex124, depth124 := position, tokenIndex, depth - { - position125 := position - depth++ - { - position126, tokenIndex126, depth126 := position, tokenIndex, depth - if buffer[position] != rune(']') { - goto l126 - } - position++ - if buffer[position] != rune(']') { - goto l126 - } - position++ - goto l124 - l126: - position, tokenIndex, depth = position126, tokenIndex126, depth126 - } - if !rules[RuleDoubleRange]() { - goto l124 - } - l127: - { - position128, tokenIndex128, depth128 := position, tokenIndex, depth - { - position129, tokenIndex129, depth129 := position, tokenIndex, depth - if buffer[position] != rune(']') { - goto l129 - } - position++ - if buffer[position] != rune(']') { - goto l129 - } - position++ - goto l128 - l129: - position, tokenIndex, depth = position129, tokenIndex129, depth129 - } - if !rules[RuleDoubleRange]() { - goto l128 - } - { - add(RuleAction24, position) - } - goto l127 - l128: - position, tokenIndex, depth = position128, tokenIndex128, depth128 - } - depth-- - add(RuleDoubleRanges, position125) - } - return true - l124: - position, tokenIndex, depth = position124, tokenIndex124, depth124 - return false - }, - /* 14 Range <- <((Char '-' Char Action25) / Char)> */ - func() bool { - position131, tokenIndex131, depth131 := position, tokenIndex, depth - { - position132 := position - depth++ - { - position133, tokenIndex133, depth133 := position, tokenIndex, depth - if !rules[RuleChar]() { - goto l134 - } - if buffer[position] != rune('-') { - goto l134 - } - position++ - if !rules[RuleChar]() { - goto l134 - } - { - add(RuleAction25, position) - } - goto l133 - l134: - position, tokenIndex, depth = position133, tokenIndex133, depth133 - if !rules[RuleChar]() { - goto l131 - } - } - l133: - depth-- - add(RuleRange, position132) - } - return true - l131: - position, tokenIndex, depth = position131, tokenIndex131, depth131 - return false - }, - /* 15 DoubleRange <- <((Char '-' Char Action26) / DoubleChar)> */ - func() bool { - position136, tokenIndex136, depth136 := position, tokenIndex, depth - { - position137 := position - depth++ - { - position138, tokenIndex138, depth138 := position, tokenIndex, depth - if !rules[RuleChar]() { - goto l139 - } - if buffer[position] != rune('-') { - goto l139 - } - position++ - if !rules[RuleChar]() { - goto l139 - } - { - add(RuleAction26, position) - } - goto l138 - l139: - position, tokenIndex, depth = position138, tokenIndex138, depth138 - if !rules[RuleDoubleChar]() { - goto l136 - } - } - l138: - depth-- - add(RuleDoubleRange, position137) - } - return true - l136: - position, tokenIndex, depth = position136, tokenIndex136, depth136 - return false - }, - /* 16 Char <- <(Escape / (!'\\' <.> Action27))> */ - func() bool { - position141, tokenIndex141, depth141 := position, tokenIndex, depth - { - position142 := position - depth++ - { - position143, tokenIndex143, depth143 := position, tokenIndex, depth - if !rules[RuleEscape]() { - goto l144 - } - goto l143 - l144: - position, tokenIndex, depth = position143, tokenIndex143, depth143 - { - position145, tokenIndex145, depth145 := position, tokenIndex, depth - if buffer[position] != rune('\\') { - goto l145 - } - position++ - goto l141 - l145: - position, tokenIndex, depth = position145, tokenIndex145, depth145 - } - { - position146 := position - depth++ - if !matchDot() { - goto l141 - } - depth-- - add(RulePegText, position146) - } - { - add(RuleAction27, position) - } - } - l143: - depth-- - add(RuleChar, position142) - } - return true - l141: - position, tokenIndex, depth = position141, tokenIndex141, depth141 - return false - }, - /* 17 DoubleChar <- <(Escape / (<([a-z] / [A-Z])> Action28) / (!'\\' <.> Action29))> */ - func() bool { - position148, tokenIndex148, depth148 := position, tokenIndex, depth - { - position149 := position - depth++ - { - position150, tokenIndex150, depth150 := position, tokenIndex, depth - if !rules[RuleEscape]() { - goto l151 - } - goto l150 - l151: - position, tokenIndex, depth = position150, tokenIndex150, depth150 - { - position153 := position - depth++ - { - position154, tokenIndex154, depth154 := position, tokenIndex, depth - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l155 - } - position++ - goto l154 - l155: - position, tokenIndex, depth = position154, tokenIndex154, depth154 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l152 - } - position++ - } - l154: - depth-- - add(RulePegText, position153) - } - { - add(RuleAction28, position) - } - goto l150 - l152: - position, tokenIndex, depth = position150, tokenIndex150, depth150 - { - position157, tokenIndex157, depth157 := position, tokenIndex, depth - if buffer[position] != rune('\\') { - goto l157 - } - position++ - goto l148 - l157: - position, tokenIndex, depth = position157, tokenIndex157, depth157 - } - { - position158 := position - depth++ - if !matchDot() { - goto l148 - } - depth-- - add(RulePegText, position158) - } - { - add(RuleAction29, position) - } - } - l150: - depth-- - add(RuleDoubleChar, position149) - } - return true - l148: - position, tokenIndex, depth = position148, tokenIndex148, depth148 - return false - }, - /* 18 Escape <- <(('\\' ('a' / 'A') Action30) / ('\\' ('b' / 'B') Action31) / ('\\' ('e' / 'E') Action32) / ('\\' ('f' / 'F') Action33) / ('\\' ('n' / 'N') Action34) / ('\\' ('r' / 'R') Action35) / ('\\' ('t' / 'T') Action36) / ('\\' ('v' / 'V') Action37) / ('\\' '\'' Action38) / ('\\' '"' Action39) / ('\\' '[' Action40) / ('\\' ']' Action41) / ('\\' '-' Action42) / ('\\' <([0-3] [0-7] [0-7])> Action43) / ('\\' <([0-7] [0-7]?)> Action44) / ('\\' '\\' Action45))> */ - func() bool { - position160, tokenIndex160, depth160 := position, tokenIndex, depth - { - position161 := position - depth++ - { - position162, tokenIndex162, depth162 := position, tokenIndex, depth - if buffer[position] != rune('\\') { - goto l163 - } - position++ - { - position164, tokenIndex164, depth164 := position, tokenIndex, depth - if buffer[position] != rune('a') { - goto l165 - } - position++ - goto l164 - l165: - position, tokenIndex, depth = position164, tokenIndex164, depth164 - if buffer[position] != rune('A') { - goto l163 - } - position++ - } - l164: - { - add(RuleAction30, position) - } - goto l162 - l163: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l167 - } - position++ - { - position168, tokenIndex168, depth168 := position, tokenIndex, depth - if buffer[position] != rune('b') { - goto l169 - } - position++ - goto l168 - l169: - position, tokenIndex, depth = position168, tokenIndex168, depth168 - if buffer[position] != rune('B') { - goto l167 - } - position++ - } - l168: - { - add(RuleAction31, position) - } - goto l162 - l167: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l171 - } - position++ - { - position172, tokenIndex172, depth172 := position, tokenIndex, depth - if buffer[position] != rune('e') { - goto l173 - } - position++ - goto l172 - l173: - position, tokenIndex, depth = position172, tokenIndex172, depth172 - if buffer[position] != rune('E') { - goto l171 - } - position++ - } - l172: - { - add(RuleAction32, position) - } - goto l162 - l171: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l175 - } - position++ - { - position176, tokenIndex176, depth176 := position, tokenIndex, depth - if buffer[position] != rune('f') { - goto l177 - } - position++ - goto l176 - l177: - position, tokenIndex, depth = position176, tokenIndex176, depth176 - if buffer[position] != rune('F') { - goto l175 - } - position++ - } - l176: - { - add(RuleAction33, position) - } - goto l162 - l175: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l179 - } - position++ - { - position180, tokenIndex180, depth180 := position, tokenIndex, depth - if buffer[position] != rune('n') { - goto l181 - } - position++ - goto l180 - l181: - position, tokenIndex, depth = position180, tokenIndex180, depth180 - if buffer[position] != rune('N') { - goto l179 - } - position++ - } - l180: - { - add(RuleAction34, position) - } - goto l162 - l179: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l183 - } - position++ - { - position184, tokenIndex184, depth184 := position, tokenIndex, depth - if buffer[position] != rune('r') { - goto l185 - } - position++ - goto l184 - l185: - position, tokenIndex, depth = position184, tokenIndex184, depth184 - if buffer[position] != rune('R') { - goto l183 - } - position++ - } - l184: - { - add(RuleAction35, position) - } - goto l162 - l183: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l187 - } - position++ - { - position188, tokenIndex188, depth188 := position, tokenIndex, depth - if buffer[position] != rune('t') { - goto l189 - } - position++ - goto l188 - l189: - position, tokenIndex, depth = position188, tokenIndex188, depth188 - if buffer[position] != rune('T') { - goto l187 - } - position++ - } - l188: - { - add(RuleAction36, position) - } - goto l162 - l187: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l191 - } - position++ - { - position192, tokenIndex192, depth192 := position, tokenIndex, depth - if buffer[position] != rune('v') { - goto l193 - } - position++ - goto l192 - l193: - position, tokenIndex, depth = position192, tokenIndex192, depth192 - if buffer[position] != rune('V') { - goto l191 - } - position++ - } - l192: - { - add(RuleAction37, position) - } - goto l162 - l191: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l195 - } - position++ - if buffer[position] != rune('\'') { - goto l195 - } - position++ - { - add(RuleAction38, position) - } - goto l162 - l195: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l197 - } - position++ - if buffer[position] != rune('"') { - goto l197 - } - position++ - { - add(RuleAction39, position) - } - goto l162 - l197: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l199 - } - position++ - if buffer[position] != rune('[') { - goto l199 - } - position++ - { - add(RuleAction40, position) - } - goto l162 - l199: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l201 - } - position++ - if buffer[position] != rune(']') { - goto l201 - } - position++ - { - add(RuleAction41, position) - } - goto l162 - l201: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l203 - } - position++ - if buffer[position] != rune('-') { - goto l203 - } - position++ - { - add(RuleAction42, position) - } - goto l162 - l203: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l205 - } - position++ - { - position206 := position - depth++ - if c := buffer[position]; c < rune('0') || c > rune('3') { - goto l205 - } - position++ - if c := buffer[position]; c < rune('0') || c > rune('7') { - goto l205 - } - position++ - if c := buffer[position]; c < rune('0') || c > rune('7') { - goto l205 - } - position++ - depth-- - add(RulePegText, position206) - } - { - add(RuleAction43, position) - } - goto l162 - l205: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l208 - } - position++ - { - position209 := position - depth++ - if c := buffer[position]; c < rune('0') || c > rune('7') { - goto l208 - } - position++ - { - position210, tokenIndex210, depth210 := position, tokenIndex, depth - if c := buffer[position]; c < rune('0') || c > rune('7') { - goto l210 - } - position++ - goto l211 - l210: - position, tokenIndex, depth = position210, tokenIndex210, depth210 - } - l211: - depth-- - add(RulePegText, position209) - } - { - add(RuleAction44, position) - } - goto l162 - l208: - position, tokenIndex, depth = position162, tokenIndex162, depth162 - if buffer[position] != rune('\\') { - goto l160 - } - position++ - if buffer[position] != rune('\\') { - goto l160 - } - position++ - { - add(RuleAction45, position) - } - } - l162: - depth-- - add(RuleEscape, position161) - } - return true - l160: - position, tokenIndex, depth = position160, tokenIndex160, depth160 - return false - }, - /* 19 LeftArrow <- <('<' '-' Spacing)> */ - func() bool { - position214, tokenIndex214, depth214 := position, tokenIndex, depth - { - position215 := position - depth++ - if buffer[position] != rune('<') { - goto l214 - } - position++ - if buffer[position] != rune('-') { - goto l214 - } - position++ - if !rules[RuleSpacing]() { - goto l214 - } - depth-- - add(RuleLeftArrow, position215) - } - return true - l214: - position, tokenIndex, depth = position214, tokenIndex214, depth214 - return false - }, - /* 20 Slash <- <('/' Spacing)> */ - func() bool { - position216, tokenIndex216, depth216 := position, tokenIndex, depth - { - position217 := position - depth++ - if buffer[position] != rune('/') { - goto l216 - } - position++ - if !rules[RuleSpacing]() { - goto l216 - } - depth-- - add(RuleSlash, position217) - } - return true - l216: - position, tokenIndex, depth = position216, tokenIndex216, depth216 - return false - }, - /* 21 And <- <('&' Spacing)> */ - func() bool { - position218, tokenIndex218, depth218 := position, tokenIndex, depth - { - position219 := position - depth++ - if buffer[position] != rune('&') { - goto l218 - } - position++ - if !rules[RuleSpacing]() { - goto l218 - } - depth-- - add(RuleAnd, position219) - } - return true - l218: - position, tokenIndex, depth = position218, tokenIndex218, depth218 - return false - }, - /* 22 Not <- <('!' Spacing)> */ - nil, - /* 23 Question <- <('?' Spacing)> */ - nil, - /* 24 Star <- <('*' Spacing)> */ - nil, - /* 25 Plus <- <('+' Spacing)> */ - nil, - /* 26 Open <- <('(' Spacing)> */ - nil, - /* 27 Close <- <(')' Spacing)> */ - nil, - /* 28 Dot <- <('.' Spacing)> */ - nil, - /* 29 Spacing <- <(Space / Comment)*> */ - func() bool { - { - position228 := position - depth++ - l229: - { - position230, tokenIndex230, depth230 := position, tokenIndex, depth - { - position231, tokenIndex231, depth231 := position, tokenIndex, depth - { - position233 := position - depth++ - { - switch buffer[position] { - case '\t': - if buffer[position] != rune('\t') { - goto l232 - } - position++ - break - case ' ': - if buffer[position] != rune(' ') { - goto l232 - } - position++ - break - default: - if !rules[RuleEndOfLine]() { - goto l232 - } - break - } - } - - depth-- - add(RuleSpace, position233) - } - goto l231 - l232: - position, tokenIndex, depth = position231, tokenIndex231, depth231 - { - position235 := position - depth++ - if buffer[position] != rune('#') { - goto l230 - } - position++ - l236: - { - position237, tokenIndex237, depth237 := position, tokenIndex, depth - { - position238, tokenIndex238, depth238 := position, tokenIndex, depth - if !rules[RuleEndOfLine]() { - goto l238 - } - goto l237 - l238: - position, tokenIndex, depth = position238, tokenIndex238, depth238 - } - if !matchDot() { - goto l237 - } - goto l236 - l237: - position, tokenIndex, depth = position237, tokenIndex237, depth237 - } - if !rules[RuleEndOfLine]() { - goto l230 - } - depth-- - add(RuleComment, position235) - } - } - l231: - goto l229 - l230: - position, tokenIndex, depth = position230, tokenIndex230, depth230 - } - depth-- - add(RuleSpacing, position228) - } - return true - }, - /* 30 Comment <- <('#' (!EndOfLine .)* EndOfLine)> */ - nil, - /* 31 Space <- <((&('\t') '\t') | (&(' ') ' ') | (&('\n' | '\r') EndOfLine))> */ - nil, - /* 32 EndOfLine <- <(('\r' '\n') / '\n' / '\r')> */ - func() bool { - position241, tokenIndex241, depth241 := position, tokenIndex, depth - { - position242 := position - depth++ - { - position243, tokenIndex243, depth243 := position, tokenIndex, depth - if buffer[position] != rune('\r') { - goto l244 - } - position++ - if buffer[position] != rune('\n') { - goto l244 - } - position++ - goto l243 - l244: - position, tokenIndex, depth = position243, tokenIndex243, depth243 - if buffer[position] != rune('\n') { - goto l245 - } - position++ - goto l243 - l245: - position, tokenIndex, depth = position243, tokenIndex243, depth243 - if buffer[position] != rune('\r') { - goto l241 - } - position++ - } - l243: - depth-- - add(RuleEndOfLine, position242) - } - return true - l241: - position, tokenIndex, depth = position241, tokenIndex241, depth241 - return false - }, - /* 33 EndOfFile <- */ - nil, - /* 34 Action <- <('{' <(!'}' .)*> '}' Spacing)> */ - func() bool { - position247, tokenIndex247, depth247 := position, tokenIndex, depth - { - position248 := position - depth++ - if buffer[position] != rune('{') { - goto l247 - } - position++ - { - position249 := position - depth++ - l250: - { - position251, tokenIndex251, depth251 := position, tokenIndex, depth - { - position252, tokenIndex252, depth252 := position, tokenIndex, depth - if buffer[position] != rune('}') { - goto l252 - } - position++ - goto l251 - l252: - position, tokenIndex, depth = position252, tokenIndex252, depth252 - } - if !matchDot() { - goto l251 - } - goto l250 - l251: - position, tokenIndex, depth = position251, tokenIndex251, depth251 - } - depth-- - add(RulePegText, position249) - } - if buffer[position] != rune('}') { - goto l247 - } - position++ - if !rules[RuleSpacing]() { - goto l247 - } - depth-- - add(RuleAction, position248) - } - return true - l247: - position, tokenIndex, depth = position247, tokenIndex247, depth247 - return false - }, - /* 35 Begin <- <('<' Spacing)> */ - nil, - /* 36 End <- <('>' Spacing)> */ - nil, - /* 38 Action0 <- <{ p.AddPackage(buffer[begin:end]) }> */ - nil, - /* 39 Action1 <- <{ p.AddPeg(buffer[begin:end]) }> */ - nil, - /* 40 Action2 <- <{ p.AddState(buffer[begin:end]) }> */ - nil, - /* 41 Action3 <- <{ p.AddRule(buffer[begin:end]) }> */ - nil, - /* 42 Action4 <- <{ p.AddExpression() }> */ - nil, - /* 43 Action5 <- <{ p.AddAlternate() }> */ - nil, - /* 44 Action6 <- <{ p.AddNil(); p.AddAlternate() }> */ - nil, - /* 45 Action7 <- <{ p.AddNil() }> */ - nil, - /* 46 Action8 <- <{ p.AddSequence() }> */ - nil, - /* 47 Action9 <- <{ p.AddPredicate(buffer[begin:end]) }> */ - nil, - /* 48 Action10 <- <{ p.AddPeekFor() }> */ - nil, - /* 49 Action11 <- <{ p.AddPeekNot() }> */ - nil, - /* 50 Action12 <- <{ p.AddQuery() }> */ - nil, - /* 51 Action13 <- <{ p.AddStar() }> */ - nil, - /* 52 Action14 <- <{ p.AddPlus() }> */ - nil, - /* 53 Action15 <- <{ p.AddName(buffer[begin:end]) }> */ - nil, - /* 54 Action16 <- <{ p.AddDot() }> */ - nil, - /* 55 Action17 <- <{ p.AddAction(buffer[begin:end]) }> */ - nil, - /* 56 Action18 <- <{ p.AddPush() }> */ - nil, - nil, - /* 58 Action19 <- <{ p.AddSequence() }> */ - nil, - /* 59 Action20 <- <{ p.AddSequence() }> */ - nil, - /* 60 Action21 <- <{ p.AddPeekNot(); p.AddDot(); p.AddSequence() }> */ - nil, - /* 61 Action22 <- <{ p.AddPeekNot(); p.AddDot(); p.AddSequence() }> */ - nil, - /* 62 Action23 <- <{ p.AddAlternate() }> */ - nil, - /* 63 Action24 <- <{ p.AddAlternate() }> */ - nil, - /* 64 Action25 <- <{ p.AddRange() }> */ - nil, - /* 65 Action26 <- <{ p.AddDoubleRange() }> */ - nil, - /* 66 Action27 <- <{ p.AddCharacter(buffer[begin:end]) }> */ - nil, - /* 67 Action28 <- <{ p.AddDoubleCharacter(buffer[begin:end]) }> */ - nil, - /* 68 Action29 <- <{ p.AddCharacter(buffer[begin:end]) }> */ - nil, - /* 69 Action30 <- <{ p.AddCharacter("\a") }> */ - nil, - /* 70 Action31 <- <{ p.AddCharacter("\b") }> */ - nil, - /* 71 Action32 <- <{ p.AddCharacter("\x1B") }> */ - nil, - /* 72 Action33 <- <{ p.AddCharacter("\f") }> */ - nil, - /* 73 Action34 <- <{ p.AddCharacter("\n") }> */ - nil, - /* 74 Action35 <- <{ p.AddCharacter("\r") }> */ - nil, - /* 75 Action36 <- <{ p.AddCharacter("\t") }> */ - nil, - /* 76 Action37 <- <{ p.AddCharacter("\v") }> */ - nil, - /* 77 Action38 <- <{ p.AddCharacter("'") }> */ - nil, - /* 78 Action39 <- <{ p.AddCharacter("\"") }> */ - nil, - /* 79 Action40 <- <{ p.AddCharacter("[") }> */ - nil, - /* 80 Action41 <- <{ p.AddCharacter("]") }> */ - nil, - /* 81 Action42 <- <{ p.AddCharacter("-") }> */ - nil, - /* 82 Action43 <- <{ p.AddOctalCharacter(buffer[begin:end]) }> */ - nil, - /* 83 Action44 <- <{ p.AddOctalCharacter(buffer[begin:end]) }> */ - nil, - /* 84 Action45 <- <{ p.AddCharacter("\\") }> */ - nil, - } - p.rules = rules -} diff --git a/bootstrap/leg/leg.go b/bootstrap/leg/leg.go deleted file mode 120000 index 46c40ef..0000000 --- a/bootstrap/leg/leg.go +++ /dev/null @@ -1 +0,0 @@ -../../leg.go \ No newline at end of file diff --git a/bootstrap/leg/leg.peg b/bootstrap/leg/leg.peg deleted file mode 100644 index b2fe552..0000000 --- a/bootstrap/leg/leg.peg +++ /dev/null @@ -1,116 +0,0 @@ -# PE Grammar for PE Grammars -# -# Adapted from [1] by Ian Piumarta . -# -# 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 - -# parser declaration - -type Leg Peg { - *Tree -} - -# Hierarchical syntax -Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } - 'type' Spacing Identifier { p.AddLeg(buffer[begin:end]) } - 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } - (Declaration / Definition)+ Trailer? EndOfFile - -Declaration <- '%{' < ( !'%}' . )* > RPERCENT { p.AddDeclaration(buffer[begin:end]) } -Trailer <- '%%' < .* > { p.AddTrailer(buffer[begin:end]) } - -Definition <- Identifier { p.AddRule(buffer[begin:end]) } - LeftArrow Expression { p.AddExpression() } -Expression <- Sequence (Slash Sequence { p.AddAlternate() } - )* (Slash { p.AddNil(); p.AddAlternate() } - )? - / { p.AddNil() } -Sequence <- Prefix (Prefix { p.AddSequence() } - )* -Prefix <- And Action { p.AddPredicate(buffer[begin:end]) } - / 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(buffer[begin:end]) } - / Open Expression Close - / Literal - / Class - / Dot { p.AddDot() } - / Action { p.AddAction(buffer[begin:end]) } - / 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(buffer[begin:end]) } -DoubleChar <- Escape - / <[a-zA-Z]> { p.AddDoubleCharacter(buffer[begin:end]) } - / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } -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("-") } - / '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(buffer[begin:end]) } - / '\\' <[0-7][0-7]?> { p.AddOctalCharacter(buffer[begin:end]) } - / '\\\\' { p.AddCharacter("\\") } -Action <- '{' < Braces* > '}' Spacing -Braces <- '{' Braces* '}' / !'}' . -LeftArrow <- '<-' Spacing -Slash <- '/' Spacing -And <- '&' Spacing -Not <- '!' Spacing -Question <- '?' Spacing -Star <- '*' Spacing -Plus <- '+' Spacing -Open <- '(' Spacing -Close <- ')' Spacing -Dot <- '.' Spacing -RPERCENT <- '%}' Spacing -Spacing <- (Space / Comment)* -Comment <- '#' (!EndOfLine .)* EndOfLine -Space <- ' ' / '\t' / EndOfLine -EndOfLine <- '\r\n' / '\n' / '\r' -EndOfFile <- !. -Begin <- '<' Spacing -End <- '>' Spacing diff --git a/grammars/c/Makefile b/grammars/c/Makefile deleted file mode 100644 index d82a4e2..0000000 --- a/grammars/c/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -c: c.peg.go main.go - go build - -c.peg.go: c.peg - ../../peg -switch -inline c.peg - -clean: - rm -f c c.peg.go diff --git a/grammars/c/c.peg b/grammars/c/c.peg deleted file mode 100644 index d45d1a4..0000000 --- a/grammars/c/c.peg +++ /dev/null @@ -1,676 +0,0 @@ -#=========================================================================== -# -# Parsing Expression Grammar of C for Mouse 1.1 - 1.5. -# Based on standard ISO/IEC 9899.1999:TC2, without preprocessor. -# Requires semantics class to process Typedefs. -# -#--------------------------------------------------------------------------- -# -# Copyright (C) 2007, 2009, 2010 by Roman R Redziejowski (www.romanredz.se). -# -# The author gives unlimited permission to copy and distribute -# this file, with or without modifications, as long as this notice -# is preserved, and any changes are properly documented. -# -# This file is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -#--------------------------------------------------------------------------- -# -# Latest update 2010-11-19 -# -#--------------------------------------------------------------------------- -# -# Modifications to the standard grammar: -# -# Defined # as start of line comment. -# Added FunctionSpecifier "_stdcall". -# Added TypeQualifier "__declspec()". -# Added TypeSpecifier "__attribute__()". -# The scope of TypedefNames is not implemented. -# -#--------------------------------------------------------------------------- -# -# Implementation of typedefs. -# -# A TypedefName is an Identifier that has been declared as such -# by a previous typedef declaration. It can be used as TypeSpecifier -# in DeclarationSpecifiers and SpecifierQualifierList. -# Recognizing it as such is essential for correct parsing. -# In other contexts, TypedefName is treated as an ordinary Identifier. -# -# According to 6.7.2, comment 2, of the Standard, TypedefName can appear -# in DeclarationSpecifiers or SpecifierQualifierList at most once, -# and then as the only TypeSpecifier. To make sure that an Identifer -# is recognized as TypedefName only in these contexts, definitions -# of these items are changed as follows: -# -# - TypedefName is removed as an alternative of TypeSpecifier. -# -# - DeclarationSpecifiers and SpecifierQualifierList are redefined -# to allow either single TypedefName or one or more TypeSpecifiers. -# -# The semantics class, via semantic actions, maintains a table of TypedefNames. -# -# The rule defining TypedefName as Identifier has a semantic action -# that returns true iff the Identifier is in the table. -# That means TypedefName is accepted iff it is in the table. -# -# According to 6.7.7, comment 3, of the Standard, -# in a Declaration whose StorageClassSpecifier is TYPEDEF, -# each Declarator defines an Identifier to be a TypedefName. -# These Identifiers are entered into the table as follows. -# -# - Each Identifier has itself as semantic value. -# -# - Each DirectDeclarator starts with either Identifier -# or Declarator in parentheses. -# Its semantic value is either that Identifier, -# or the Identifier obtained as semantic value of that Declarator. -# -# - Each Declarator has as semantic value the Identifier -# appearing in its DirectDeclarator, -# -# - Each InitDeclarator has as semantic value the Identifier -# appearing in its Declarator. -# -# - InitDeclaratorList has as semantic value -# the list of Identifiers appearing in its InitDeclarators. -# -# - DeclarationSpecifiers has semantic value "typedef" -# if any of the specifiers is "typedef" or null otherwise. -# -# - Declaration has a semantic action that enters Identifiers -# delivered by InitDeclaratorList into typedef table -# if DeclarationSpecifiers indicate "typedef". -# -# -#--------------------------------------------------------------------------- -# -# Change log -# 2009-07-13 Posted on Internet. -# 2010-11-19 Removed superfluous '?' after 'Spacing'. -# -# -#--------------------------------------------------------------------------- -# -# 2013-02-21 Modified to work with github.com/pointlander/peg -# -#=========================================================================== - - -#------------------------------------------------------------------------- -# A.2.4 External definitions -#------------------------------------------------------------------------- - -package main - -type C Peg { - -} - -TranslationUnit <- Spacing ExternalDeclaration+ EOT - -ExternalDeclaration <- FunctionDefinition / Declaration - -FunctionDefinition <- DeclarationSpecifiers Declarator DeclarationList? CompoundStatement - -DeclarationList <- Declaration+ - - -#------------------------------------------------------------------------- -# A.2.2 Declarations -#------------------------------------------------------------------------- - -Declaration <- DeclarationSpecifiers InitDeclaratorList? SEMI #{} - -DeclarationSpecifiers - <- (( StorageClassSpecifier - / TypeQualifier - / FunctionSpecifier - )* - TypedefName - ( StorageClassSpecifier - / TypeQualifier - / FunctionSpecifier - )* - ) #{DeclarationSpecifiers} - / ( StorageClassSpecifier - / TypeSpecifier - / TypeQualifier - / FunctionSpecifier - )+ #{DeclarationSpecifiers} - -InitDeclaratorList <- InitDeclarator (COMMA InitDeclarator)* #{} - -InitDeclarator <- Declarator (EQU Initializer)? #{} - -StorageClassSpecifier - <- TYPEDEF - / EXTERN - / STATIC - / AUTO - / REGISTER - / ATTRIBUTE LPAR LPAR (!RPAR .)* RPAR RPAR - -TypeSpecifier - <- VOID - / CHAR - / SHORT - / INT - / LONG - / FLOAT - / DOUBLE - / SIGNED - / UNSIGNED - / BOOL - / COMPLEX - / StructOrUnionSpecifier - / EnumSpecifier - -StructOrUnionSpecifier - <- StructOrUnion - ( Identifier? LWING StructDeclaration+ RWING - / Identifier - ) - -StructOrUnion <- STRUCT / UNION - -StructDeclaration <- SpecifierQualifierList StructDeclaratorList SEMI - -SpecifierQualifierList - <- ( TypeQualifier* - TypedefName - TypeQualifier* - ) - / ( TypeSpecifier - / TypeQualifier - )+ - -StructDeclaratorList <- StructDeclarator (COMMA StructDeclarator)* - -StructDeclarator - <- Declarator? COLON ConstantExpression - / Declarator - -EnumSpecifier - <- ENUM - ( Identifier? LWING EnumeratorList COMMA? RWING - / Identifier - ) - -EnumeratorList <- Enumerator (COMMA Enumerator)* - -Enumerator <- EnumerationConstant (EQU ConstantExpression)? - -TypeQualifier - <- CONST - / RESTRICT - / VOLATILE - / DECLSPEC LPAR Identifier RPAR - -FunctionSpecifier <- INLINE / STDCALL - -Declarator <- Pointer? DirectDeclarator #{} - -DirectDeclarator - <- ( Identifier - / LPAR Declarator RPAR - ) - ( LBRK TypeQualifier* AssignmentExpression? RBRK - / LBRK STATIC TypeQualifier* AssignmentExpression RBRK - / LBRK TypeQualifier+ STATIC AssignmentExpression RBRK - / LBRK TypeQualifier* STAR RBRK - / LPAR ParameterTypeList RPAR - / LPAR IdentifierList? RPAR - )* #{} - -Pointer <- ( STAR TypeQualifier* )+ - -ParameterTypeList <- ParameterList (COMMA ELLIPSIS)? - -ParameterList <- ParameterDeclaration (COMMA ParameterDeclaration)* - -ParameterDeclaration - <- DeclarationSpecifiers - ( Declarator - / AbstractDeclarator - )? - -IdentifierList <- Identifier (COMMA Identifier)* - -TypeName <- SpecifierQualifierList AbstractDeclarator? - -AbstractDeclarator - <- Pointer? DirectAbstractDeclarator - / Pointer - -DirectAbstractDeclarator - <- ( LPAR AbstractDeclarator RPAR - / LBRK (AssignmentExpression / STAR)? RBRK - / LPAR ParameterTypeList? RPAR - ) - ( LBRK (AssignmentExpression / STAR)? RBRK - / LPAR ParameterTypeList? RPAR - )* - -TypedefName <-Identifier #{&TypedefName} - -Initializer - <- AssignmentExpression - / LWING InitializerList COMMA? RWING - -InitializerList <- Designation? Initializer (COMMA Designation? Initializer)* - -Designation <- Designator+ EQU - -Designator - <- LBRK ConstantExpression RBRK - / DOT Identifier - - -#------------------------------------------------------------------------- -# A.2.3 Statements -#------------------------------------------------------------------------- - -Statement - <- LabeledStatement - / CompoundStatement - / ExpressionStatement - / SelectionStatement - / IterationStatement - / JumpStatement - -LabeledStatement - <- Identifier COLON Statement - / CASE ConstantExpression COLON Statement - / DEFAULT COLON Statement - -CompoundStatement <- LWING ( Declaration / Statement )* RWING - -ExpressionStatement <- Expression? SEMI - -SelectionStatement - <- IF LPAR Expression RPAR Statement (ELSE Statement)? - / SWITCH LPAR Expression RPAR Statement - -IterationStatement - <- WHILE LPAR Expression RPAR Statement - / DO Statement WHILE LPAR Expression RPAR SEMI - / FOR LPAR Expression? SEMI Expression? SEMI Expression? RPAR Statement - / FOR LPAR Declaration Expression? SEMI Expression? RPAR Statement - -JumpStatement - <- GOTO Identifier SEMI - / CONTINUE SEMI - / BREAK SEMI - / RETURN Expression? SEMI - - -#------------------------------------------------------------------------- -# A.2.1 Expressions -#------------------------------------------------------------------------- - -PrimaryExpression - <- Identifier - / Constant - / StringLiteral - / LPAR Expression RPAR - -PostfixExpression - <- ( PrimaryExpression - / LPAR TypeName RPAR LWING InitializerList COMMA? RWING - ) - ( LBRK Expression RBRK - / LPAR ArgumentExpressionList? RPAR - / DOT Identifier - / PTR Identifier - / INC - / DEC - )* - -ArgumentExpressionList <- AssignmentExpression (COMMA AssignmentExpression)* - -UnaryExpression - <- PostfixExpression - / INC UnaryExpression - / DEC UnaryExpression - / UnaryOperator CastExpression - / SIZEOF (UnaryExpression / LPAR TypeName RPAR ) - -UnaryOperator - <- AND - / STAR - / PLUS - / MINUS - / TILDA - / BANG - -CastExpression <- (LPAR TypeName RPAR)* UnaryExpression - -MultiplicativeExpression <- CastExpression ((STAR / DIV / MOD) CastExpression)* - -AdditiveExpression <- MultiplicativeExpression ((PLUS / MINUS) MultiplicativeExpression)* - -ShiftExpression <- AdditiveExpression ((LEFT / RIGHT) AdditiveExpression)* - -RelationalExpression <- ShiftExpression ((LE / GE / LT / GT) ShiftExpression)* - -EqualityExpression <- RelationalExpression ((EQUEQU / BANGEQU) RelationalExpression)* - -ANDExpression <- EqualityExpression (AND EqualityExpression)* - -ExclusiveORExpression <- ANDExpression (HAT ANDExpression)* - -InclusiveORExpression <- ExclusiveORExpression (OR ExclusiveORExpression)* - -LogicalANDExpression <- InclusiveORExpression (ANDAND InclusiveORExpression)* - -LogicalORExpression <- LogicalANDExpression (OROR LogicalANDExpression)* - -ConditionalExpression <- LogicalORExpression (QUERY Expression COLON LogicalORExpression)* - -AssignmentExpression - <- UnaryExpression AssignmentOperator AssignmentExpression - / ConditionalExpression - -AssignmentOperator - <- EQU - / STAREQU - / DIVEQU - / MODEQU - / PLUSEQU - / MINUSEQU - / LEFTEQU - / RIGHTEQU - / ANDEQU - / HATEQU - / OREQU - -Expression <- AssignmentExpression (COMMA AssignmentExpression)* - -ConstantExpression <- ConditionalExpression - - -#------------------------------------------------------------------------- -# A.1.1 Lexical elements -# Tokens are: Keyword, Identifier, Constant, StringLiteral, Punctuator. -# Tokens are separated by Spacing. -#------------------------------------------------------------------------- - -Spacing - <- ( WhiteSpace - / LongComment - / LineComment - / Pragma - )* - -WhiteSpace <- [ \n\r\t] # 7.4.1.10 [\u000B\u000C] - -LongComment <- '/*' (!'*/'.)* '*/' # 6.4.9 - -LineComment <- '//' (!'\n' .)* # 6.4.9 - -Pragma <- '#' (!'\n' .)* # Treat pragma as comment - - -#------------------------------------------------------------------------- -# A.1.2 Keywords -#------------------------------------------------------------------------- - -AUTO <- 'auto' !IdChar Spacing -BREAK <- 'break' !IdChar Spacing -CASE <- 'case' !IdChar Spacing -CHAR <- 'char' !IdChar Spacing -CONST <- 'const' !IdChar Spacing -CONTINUE <- 'continue' !IdChar Spacing -DEFAULT <- 'default' !IdChar Spacing -DOUBLE <- 'double' !IdChar Spacing -DO <- 'do' !IdChar Spacing -ELSE <- 'else' !IdChar Spacing -ENUM <- 'enum' !IdChar Spacing -EXTERN <- 'extern' !IdChar Spacing -FLOAT <- 'float' !IdChar Spacing -FOR <- 'for' !IdChar Spacing -GOTO <- 'goto' !IdChar Spacing -IF <- 'if' !IdChar Spacing -INT <- 'int' !IdChar Spacing -INLINE <- 'inline' !IdChar Spacing -LONG <- 'long' !IdChar Spacing -REGISTER <- 'register' !IdChar Spacing -RESTRICT <- 'restrict' !IdChar Spacing -RETURN <- 'return' !IdChar Spacing -SHORT <- 'short' !IdChar Spacing -SIGNED <- 'signed' !IdChar Spacing -SIZEOF <- 'sizeof' !IdChar Spacing -STATIC <- 'static' !IdChar Spacing -STRUCT <- 'struct' !IdChar Spacing -SWITCH <- 'switch' !IdChar Spacing -TYPEDEF <- 'typedef' !IdChar Spacing -UNION <- 'union' !IdChar Spacing -UNSIGNED <- 'unsigned' !IdChar Spacing -VOID <- 'void' !IdChar Spacing -VOLATILE <- 'volatile' !IdChar Spacing -WHILE <- 'while' !IdChar Spacing -BOOL <- '_Bool' !IdChar Spacing -COMPLEX <- '_Complex' !IdChar Spacing -STDCALL <- '_stdcall' !IdChar Spacing -DECLSPEC <- '__declspec' !IdChar Spacing -ATTRIBUTE <- '__attribute__' !IdChar Spacing - -Keyword - <- ( 'auto' - / 'break' - / 'case' - / 'char' - / 'const' - / 'continue' - / 'default' - / 'double' - / 'do' - / 'else' - / 'enum' - / 'extern' - / 'float' - / 'for' - / 'goto' - / 'if' - / 'int' - / 'inline' - / 'long' - / 'register' - / 'restrict' - / 'return' - / 'short' - / 'signed' - / 'sizeof' - / 'static' - / 'struct' - / 'switch' - / 'typedef' - / 'union' - / 'unsigned' - / 'void' - / 'volatile' - / 'while' - / '_Bool' - / '_Complex' - / '_Imaginary' - / '_stdcall' - / '__declspec' - / '__attribute__' - ) - !IdChar - - -#------------------------------------------------------------------------- -# A.1.3 Identifiers -# The standard does not explicitly state that identifiers must be -# distinct from keywords, but it seems so. -#------------------------------------------------------------------------- - -Identifier <- !Keyword IdNondigit IdChar* Spacing #{} - -IdNondigit - <- [a-z] / [A-Z] / [_] - / UniversalCharacter - -IdChar - <- [a-z] / [A-Z] / [0-9] / [_] - / UniversalCharacter - - -#------------------------------------------------------------------------- -# A.1.4 Universal character names -#------------------------------------------------------------------------- - -UniversalCharacter - <- '\\u' HexQuad - / '\\U' HexQuad HexQuad - -HexQuad <- HexDigit HexDigit HexDigit HexDigit - - -#------------------------------------------------------------------------- -# A.1.5 Constants -#------------------------------------------------------------------------- - -Constant - <- FloatConstant - / IntegerConstant # Note: can be a prefix of Float Constant! - / EnumerationConstant - / CharacterConstant - -IntegerConstant - <- ( DecimalConstant - / HexConstant - / OctalConstant - ) - IntegerSuffix? Spacing - -DecimalConstant <- [1-9][0-9]* - -OctalConstant <- '0' [0-7]* - -HexConstant <- HexPrefix HexDigit+ - -HexPrefix <- '0x' / '0X' - -HexDigit <- [a-f] / [A-F] / [0-9] - -IntegerSuffix - <- [uU] Lsuffix? - / Lsuffix [uU]? - -Lsuffix - <- 'll' - / 'LL' - / [lL] - -FloatConstant - <- ( DecimalFloatConstant - / HexFloatConstant - ) - FloatSuffix? Spacing - -DecimalFloatConstant - <- Fraction Exponent? - / [0-9]+ Exponent - -HexFloatConstant - <- HexPrefix HexFraction BinaryExponent? - / HexPrefix HexDigit+ BinaryExponent - -Fraction - <- [0-9]* '.' [0-9]+ - / [0-9]+ '.' - -HexFraction - <- HexDigit* '.' HexDigit+ - / HexDigit+ '.' - -Exponent <- [eE][+\-]? [0-9]+ - -BinaryExponent <- [pP][+\-]? [0-9]+ - -FloatSuffix <- [flFL] - -EnumerationConstant <- Identifier - -CharacterConstant <- 'L'? ['] Char* ['] Spacing - -Char <- Escape / !['\n\\] . - -Escape - <- SimpleEscape - / OctalEscape - / HexEscape - / UniversalCharacter - -SimpleEscape <- '\\' ['\"?\\abfnrtv] -OctalEscape <- '\\' [0-7][0-7]?[0-7]? -HexEscape <- '\\x' HexDigit+ - - -#------------------------------------------------------------------------- -# A.1.6 String Literals -#------------------------------------------------------------------------- - -StringLiteral <- 'L'? (["] StringChar* ["] Spacing)+ - -StringChar <- Escape / ![\"\n\\] . - - -#------------------------------------------------------------------------- -# A.1.7 Punctuators -#------------------------------------------------------------------------- - -LBRK <- '[' Spacing -RBRK <- ']' Spacing -LPAR <- '(' Spacing -RPAR <- ')' Spacing -LWING <- '{' Spacing -RWING <- '}' Spacing -DOT <- '.' Spacing -PTR <- '->' Spacing -INC <- '++' Spacing -DEC <- '--' Spacing -AND <- '&' ![&] Spacing -STAR <- '*' ![=] Spacing -PLUS <- '+' ![+=] Spacing -MINUS <- '-' ![\-=>] Spacing -TILDA <- '~' Spacing -BANG <- '!' ![=] Spacing -DIV <- '/' ![=] Spacing -MOD <- '%' ![=>] Spacing -LEFT <- '<<' ![=] Spacing -RIGHT <- '>>' ![=] Spacing -LT <- '<' ![=] Spacing -GT <- '>' ![=] Spacing -LE <- '<=' Spacing -GE <- '>=' Spacing -EQUEQU <- '==' Spacing -BANGEQU <- '!=' Spacing -HAT <- '^' ![=] Spacing -OR <- '|' ![=] Spacing -ANDAND <- '&&' Spacing -OROR <- '||' Spacing -QUERY <- '?' Spacing -COLON <- ':' ![>] Spacing -SEMI <- ';' Spacing -ELLIPSIS <- '...' Spacing -EQU <- '=' !"=" Spacing -STAREQU <- '*=' Spacing -DIVEQU <- '/=' Spacing -MODEQU <- '%=' Spacing -PLUSEQU <- '+=' Spacing -MINUSEQU <- '-=' Spacing -LEFTEQU <- '<<=' Spacing -RIGHTEQU <- '>>=' Spacing -ANDEQU <- '&=' Spacing -HATEQU <- '^=' Spacing -OREQU <- '|=' Spacing -COMMA <- ',' Spacing - -EOT <- !. diff --git a/grammars/c/main.go b/grammars/c/main.go deleted file mode 100644 index c7e1378..0000000 --- a/grammars/c/main.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "strings" -) - -func main() { - if len(os.Args) < 2 { - fmt.Printf("%v FILE\n", os.Args[0]) - os.Exit(1) - } - - var walk func(name string) - walk = func(name string) { - fileInfo, err := os.Stat(name) - if err != nil { - log.Fatal(err) - } - - if fileInfo.Mode() & (os.ModeNamedPipe | os.ModeSocket | os.ModeDevice) != 0 { - /* will lock up if opened */ - } else if fileInfo.IsDir() { - fmt.Printf("directory %v\n", name) - - file, err := os.Open(name) - if err != nil { - log.Fatal(err) - } - - files, err := file.Readdir(-1) - if err != nil { - log.Fatal(err) - } - file.Close() - - for _, f := range files { - if !strings.HasSuffix(name, "/") { - name += "/" - } - walk(name + f.Name()) - } - } else if strings.HasSuffix(name, ".c") { - fmt.Printf("parse %v\n", name) - - file, err := os.Open(name) - if err != nil { - log.Fatal(err) - } - - buffer, err := ioutil.ReadAll(file) - if err != nil { - log.Fatal(err) - } - file.Close() - - clang := &C{Buffer: string(buffer)} - clang.Init() - if err := clang.Parse(); err != nil { - log.Fatal(err) - } - } - } - walk(os.Args[1]) -} diff --git a/grammars/calculator/Makefile b/grammars/calculator/Makefile deleted file mode 100644 index e8dbb66..0000000 --- a/grammars/calculator/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -calculator: calculator.peg.go calculator.go main.go - go build - -calculator.peg.go: calculator.peg - ../../peg -switch -inline calculator.peg - -clean: - rm -f calculator calculator.peg.go diff --git a/grammars/calculator/calculator.go b/grammars/calculator/calculator.go deleted file mode 100644 index 8969470..0000000 --- a/grammars/calculator/calculator.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "math/big" -) - -type Type uint8 - -const ( - TypeNumber Type = iota - TypeNegation - TypeAdd - TypeSubtract - TypeMultiply - TypeDivide - TypeModulus - TypeExponentiation -) - -type ByteCode struct { - T Type - Value *big.Int -} - -func (code *ByteCode) String() string { - switch code.T { - case TypeNumber: - return code.Value.String() - case TypeAdd: - return "+" - case TypeNegation, TypeSubtract: - return "-" - case TypeMultiply: - return "*" - case TypeDivide: - return "/" - case TypeModulus: - return "%" - case TypeExponentiation: - return "^" - } - return "" -} - -type Expression struct { - Code []ByteCode - Top int -} - -func (e *Expression) Init(expression string) { - e.Code = make([]ByteCode, len(expression)) -} - -func (e *Expression) AddOperator(operator Type) { - code, top := e.Code, e.Top - e.Top++ - code[top].T = operator -} - -func (e *Expression) AddValue(value string) { - code, top := e.Code, e.Top - e.Top++ - code[top].Value = new(big.Int) - code[top].Value.SetString(value, 10) -} - -func (e *Expression) Evaluate() *big.Int { - stack, top := make([]big.Int, len(e.Code)), 0 - for _, code := range e.Code[0:e.Top] { - switch code.T { - case TypeNumber: - stack[top].Set(code.Value) - top++ - continue - case TypeNegation: - a := &stack[top-1] - a.Neg(a) - continue - } - a, b := &stack[top-2], &stack[top-1] - top-- - switch code.T { - case TypeAdd: - a.Add(a, b) - case TypeSubtract: - a.Sub(a, b) - case TypeMultiply: - a.Mul(a, b) - case TypeDivide: - a.Div(a, b) - case TypeModulus: - a.Mod(a, b) - case TypeExponentiation: - a.Exp(a, b, nil) - } - } - return &stack[0] -} diff --git a/grammars/calculator/calculator.peg b/grammars/calculator/calculator.peg deleted file mode 100644 index 929d714..0000000 --- a/grammars/calculator/calculator.peg +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -package main - -type Calculator Peg { - Expression -} - -e <- s e1 !. -e1 <- e2 ( add e2 { p.AddOperator(TypeAdd) } - / minus e2 { p.AddOperator(TypeSubtract) } - )* -e2 <- e3 ( multiply e3 { p.AddOperator(TypeMultiply) } - / divide e3 { p.AddOperator(TypeDivide) } - / modulus e3 { p.AddOperator(TypeModulus) } - )* -e3 <- e4 ( exponentiation e4 { p.AddOperator(TypeExponentiation) } - )* -e4 <- minus value { p.AddOperator(TypeNegation) } - / value -value <- < [0-9]+ > s { p.AddValue(buffer[begin:end]) } - / open e1 close -add <- '+' s -minus <- '-' s -multiply <- '*' s -divide <- '/' s -modulus <- '%' s -exponentiation <- '^' s -open <- '(' s -close <- ')' s -s <- ( ' ' / '\t' )* diff --git a/grammars/fexl/Makefile b/grammars/fexl/Makefile deleted file mode 100644 index 168cffb..0000000 --- a/grammars/fexl/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -fexl: fexl.peg.go main.go - go build - -fexl.peg.go: fexl.peg - ../../peg -switch -inline fexl.peg - -clean: - rm -f fexl fexl.peg.go diff --git a/grammars/fexl/doc/NOTICE b/grammars/fexl/doc/NOTICE deleted file mode 100644 index b7e6466..0000000 --- a/grammars/fexl/doc/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2011 Patrick Chkoreff - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions -and limitations under the License. diff --git a/grammars/fexl/doc/README b/grammars/fexl/doc/README deleted file mode 100644 index 533436b..0000000 --- a/grammars/fexl/doc/README +++ /dev/null @@ -1,80 +0,0 @@ -Fexl (Function EXpression Language) http://fexl.com - -AUTHOR - -Patrick Chkoreff wrote this software. Please see the NOTICE file for terms of -use. - - -CREDITS - -I thank Moses Schönfinkel, who in 1924 wrote a paper titled "On the building -blocks of mathematical logic". I found this paper in "From Frege to Gödel, A -Source Book in Mathematical Logic, 1879-1931". - -Mr. Schönfinkel observes that all computable functions can be defined in terms -of just two primitive functions C and S applied together in various -combinations. This is a profound and magnificent insight for which I am very -grateful. - -The C function is governed by the rule ((C x) y) = x. This is known as the -"constancy function", or "Konstanzfunktion" in the original German. - -The S function is governed by the rule (((S x) y) z) = ((x z) (y z)). This is -known as the "fusion function", or "Verschmelzungfunktion" in the original -German. - -I also thank Jørgen Steensgaard-Madsen, who in 1989 wrote a paper titled -"Typed Representation of Objects by Functions". I found this paper in the -"ACM Transactions on Programming Languages and Systems, January 1989, Volume -11 Number 1". - -Mr. Steensgaard-Madsen observes that all of what we ordinarily understand as -"data" can be represented as pure functions. Even a piece of data as humble -as a single bit is in essence just a function. - - -HOW TO INSTALL - -Go into the source code directory and run this command: - - ./build install - -You may be prompted for your sudo (superuser) password. - -That builds the program locally in ../bin, then copies it to the /usr/bin -directory. If you need to install it in a different place, change the -install_location variable inside the build script. - - -HOW TO BUILD LOCALLY - -If you wish to enhance or test the program, you might prefer to build it -locally in the ../bin directory and run it from there, without installing into -/usr/bin. You do that with this command: - - ./build - - -HOW TO RUN - -To run a fexl program which is read from standard input: - - fexl - -To run a fexl program which is read from a file named "script": - - fexl script - -You may also use the "shebang" method to create an executable fexl file. For -example, create a file named "script" and put this on the first line: - - #!/usr/bin/fexl - -Then make your script executable with: - - chmod +x script - -Now you can run your script directly this way: - - ./script diff --git a/grammars/fexl/doc/try.fxl b/grammars/fexl/doc/try.fxl deleted file mode 100755 index f36b64c..0000000 --- a/grammars/fexl/doc/try.fxl +++ /dev/null @@ -1,1024 +0,0 @@ -#!../bin/fexl -# ^^^ use that line for the locally built version - -#!/usr/bin/fexl -# ^^^ use that line for the installed version - - -# NOTE: If you run ./try.fxl, it will go through a bunch of tests, including -# one at the end where it asks you to type lines of text and terminate with -# Ctrl-D. If you'd like to run the test without having to type anything, and -# compare it with the reference output, do this: -# -# cat try.fxl | ../bin/fexl | cmp - out -# -# That should run quietly with exit code 0. - - -##### - -# This function halts by simply consuming all arguments given to it. -\halt == (\_ halt) - -# Useful: -\string_from = (\x - string_type x x; - long_type x (long_string x); - double_type x (double_string x); - x) - -\print = (\item string_put (string_from item)) -\nl = (print " -") - -\T = (\T\F T) -\F = (\T\F F) - -\string_eq=(\x\y string_compare x y F T F) - -\long_le = (\x\y long_compare x y T T F) -\long_lt = (\x\y long_compare x y T F F) -\long_ge = (\x\y long_compare x y F T T) -\long_gt = (\x\y long_compare x y F F T) -\long_ne = (\x\y long_compare x y T F T) -\long_min = (\x\y long_compare x y x x y) - -### List functions - -# "end" is the empty list. -\end = (\end\item end) - -# The "item" (cons) list constructor is built-in, but could be defined thus: -# \item = (\head\tail \end\item item head tail) - -# Return the first N items of the list. -\list_prefix == (\list\N - long_le N 0 end; - list end \head\tail - \N = (long_sub N 1) - item head; list_prefix tail N - ) - -# Return the item at position N in the list, or default if no such item. -\list_at == (\list\N\default - list default \head\tail - long_compare N 0 default head - \N = (long_sub N 1) - list_at tail N default - ) - -\list_map == (\next\fun\list - list next \head\tail fun head; list_map next fun tail) - -\list_do = (list_map I) - -\list_print = (\fun list_do \x string_put; fun x) - -# We don't use char_put because of buffering problems. -\chars_print = (list_print long_char) - -\bits_print = (list_print \x x "1" "0") - -# Reverse a list. -\reverse=(\list - \reverse==(\list\result list result \h\t reverse t (item h result)) - reverse list end - ) - -######## - -\test_hello_world== -( -print "hello world" nl; -) - -######## - -\test_cat== -( -print "=== Enter lines of text and I'll echo them. Press Ctrl-D to stop";nl; - -\long_lt = (\x\y long_compare x y T F F) - -# The cat program echoes the input to the output. -\cat == (char_get \ch long_lt ch 0 I; char_put ch; cat) -cat -) - -######## - -\test_string_slice== -( -print (string_slice "abcde" 0 1); nl; -print (string_slice "abcde" 0 2); nl; -print (string_slice "abcde" 0 3); nl; -print (string_slice "abcde" 0 4); nl; -print (string_slice "abcde" 0 5); nl; -print (string_slice "abcde" 0 6); nl; -print (string_slice "abcde" 0 700); nl; -print (string_slice "a" 0 0); nl; -print (string_slice "a" 0 1); nl; -print (string_slice "a" 0 2); nl; -print (string_slice "a" -1 0); nl; -print "=====";nl; -print (string_slice "a" 0 1); nl; -print (string_slice "a" -1 2); nl; -print (string_slice "a" -2 3); nl; -print (string_slice "a" -2 4); nl; -print (string_slice "a" -2 0); nl; -print (string_slice "abcde" 0 5); nl; -print (string_slice "abcde" -1 5); nl; -print (string_slice "abcde" -2 5); nl; -print (string_slice "abcde" -3 5); nl; -print (string_slice "abcde" -4 5); nl; -print (string_slice "abcde" -5 5); nl; -print (string_slice "abcde" -5 6); nl; -print (string_slice "abcde" -5 7); nl; -print (string_slice "abcde" -5 8); nl; -print (string_slice "abcde" -5 9); nl; -print (string_slice "abcde" -5 10); nl; -print (string_slice "abcde" -5 11); nl; -print "=====";nl; -print (string_slice "" 0 0); nl; -print (string_slice "" 0 800); nl; -print (string_slice "" -30 800); nl; -#string_put (string_from (string_slice "a" 0 1));nl; -#string_put (string_from (string_slice "a" 0 1));nl; -#string_put (string_from (string_slice "a" 0 1));nl; -#string_put (string_from (string_slice "a" 0 1));nl; - -#string_put (string_slice "a" 0 0) -) - -######## - -\test_write_binary == -( -# Writing binary - -\string_3014 = - ( - string_append (long_char 03); - string_append (long_char 00); - string_append (long_char 01); - string_append (long_char 04); - "" - ) - -string_put string_3014; -) - -######## - -\test_string_len== -( -print (string_len ""); nl; -print (string_len "a"); nl; -print (string_len "ab"); nl; -print (string_len "12345678901234567890123456789012"); nl; -) - -######## - -\test_string_at== -( -print (string_at "abc" -1); nl; -print (string_at "abc" 0); nl; -print (string_at "abc" 1); nl; -print (string_at "abc" 2); nl; -print (string_at "abc" 3); nl; -) - -######## - -\test_string_compare== -( -\string_014 = - ( - string_append (long_char 00); - string_append (long_char 01); - string_append (long_char 04); - "" - ) - -\string_041 = - ( - string_append (long_char 00); - string_append (long_char 04); - string_append (long_char 01); - "" - ) - -\string_0142 = (string_append string_014; long_char 02); - -\do_compare=(\x\y\expect - \result = (string_compare x y "LT" "EQ" "GT") - print "string_compare "; print x; print " "; print y; print " "; - print result; print " "; - print (string_eq result expect "GOOD" "BAD"); - nl; - ) - -do_compare string_0142 string_014 "GT"; -do_compare string_014 string_0142 "LT"; -do_compare string_014 string_014 "EQ"; -do_compare string_014 string_041 "LT"; -do_compare string_041 string_014 "GT"; -do_compare string_041 string_0142 "GT"; -) - -######## -\test_string_common == -( -\string_eq=(\x\y string_compare x y F T F) -\long_eq=(\x\y long_compare x y F T F) - -\check = (\value\expect - \halt == (\_ halt) - \ok = (long_eq value expect) - print " "; print (ok "GOOD" "BAD");nl; - ok I halt - ) - -\test_string_common = (\x\y\expect - \len = (string_common x y) - print "string_common ";print x; print " "; print y; print " = "; print len; - check len expect; - ) - -test_string_common "" "" 0; -test_string_common "" "a" 0; -test_string_common "a" "a" 1; -test_string_common "a" "ab" 1; -test_string_common "ab" "a" 1; -test_string_common "ab" "ab" 2; -test_string_common "abc" "abd" 2; -test_string_common "aac" "abd" 1; -test_string_common "abd" "abd" 3; -test_string_common "cbd" "abd" 0; -test_string_common "x" "" 0; -) - -######## - -\test_long_add== -( -\x=(long_add 37 23) -print "The value of x is "; print x; print "."; nl; -) - -######## -\test_procedural== -( -# Make some abbreviations. -\add=double_add -\sub=double_sub -\mul=double_mul -\div=double_div - - -print ~@ -=== -Here we demonstrate an ordinary "procedural" style of programming. This works -because definitions are NOT recursive by default. If you want a recursive -definition, you must use "==" instead of just "=". - -@; - -\show=(\name\value print name; print " = "; print value; nl;) - -\x=3.0 -\y=4.0 -\x=(add x x) -\y=(mul y x) -show "x" x; show "y" y; -\x=(div x; mul y 4.0) -show "x" x; show "y" y; - -\z=(mul x; mul y; add 1.0 y) -show "x" x; show "y" y; show "z" z; -\z=(div z 5.0) -show "z" z; -) - -\test_eager== -( -\long_le = (\x\y long_compare x y T T F) - -\sum == (\total\count - long_le count 0 total; - - # This form evaluates eagerly: - \total = (long_add total count) - - # Or if you prefer, you can use "?" to force eager evaluation like this: - #? (long_add total count) \total - - sum total (long_sub count 1)) - -\sum = (sum 0) - -\count = 100000 -print "The sum of 1 .. ";print count; print " is "; print (sum count);nl; -) - -\test_double_compare == -( -\do_compare=(\x\y\expect - \result = (double_compare x y "LT" "EQ" "GT") - print "double_compare "; print x; print " "; print y; print " "; - print result; print " "; - print (string_eq result expect "GOOD" "BAD"); - nl; - ) -do_compare 23.0 23.0 "EQ" -do_compare 23.0 24.0 "LT" -do_compare 23.1 23.2 "LT" -do_compare 24.0 23.0 "GT" -do_compare 24.0 240.0 "LT" -do_compare -1.0 4.0 "LT" -do_compare 4.0 -1.0 "GT" -do_compare -1.0 -1.0 "EQ" -) - -####### Some tests with arbitrary precision arithmetic. - -\module_test_arithmetic == -( - -# These put a binary digit 0 or 1 on the front of a list. -\d0 = (item F) -\d1 = (item T) - -# the natural numbers 0 and 1 -\nat_0 = end -\nat_1 = (d1 nat_0) - -# (nat_2x x) is twice x. -\nat_2x=(\x x nat_0 \_\_ d0 x) - -# (nat_2x1 x) is twice x plus 1. -\nat_2x1=d1 - -# (nat_eq0 x) is true iff x = 0 -\nat_eq0=(\x x T \_\_ F) - -# (nat_inc x) is x+1. (x incremented by 1). Both x and the result are of -# type nat. -\nat_inc==(\x x nat_1 \b\n b (d0; nat_inc n) (d1 n)) - -# (nat_dec x) is x-1 if x > 0, or 0 if x = 0. (x decremented by 1) Both x -# and the result are of type nat. -\nat_dec==(\x x nat_0 \b\n b (nat_eq0 n nat_0 (d0 n)) (d1; nat_dec n)) - -# (nat_add x y) is x+y. (the sum of x and y) The x, y, and result are of -# type nat. -\nat_add == (\x\y x y \bx\nx y x \by\ny - \sum=(nat_add nx ny) - bx - (by (d0; nat_inc sum) (d1 sum)) - (item by sum) - ) - -# (nat_mul x y) is x*y. (the product of x and y) The x, y, and result are -# of type nat. -\nat_mul == (\x\y x nat_0 \bx\nx y nat_0 \by\ny - bx - (by (d1; nat_add nx (nat_mul ny x)) (d0; nat_mul ny x)) - (by (d0; nat_mul nx y) (d0; d0; nat_mul nx ny)) - ) - -# (int_ge0 x) is true if int x >= 0. -\int_ge0=(\x x T \s\_ s) - -# (int_abs x) is the absolute value of int x. The result is a nat. -\int_abs=(\x x nat_0 \_\n n) - -\int_0 = end -\int_1 = (d1; d1; int_0) - -# (nat_int x) is nat x converted to the int +x. -\nat_int=(\x nat_eq0 x int_0; d1 x) -# (nat_neg x) is nat x converted to the int -x. -\nat_neg=(\x nat_eq0 x int_0; d0 x) - -# (int_2x x) is twice x. -\int_2x=(\x x int_0 \b\n item b; d0; n) - -# (int_inc x) is int x+1. -\int_inc=(\x x int_1 \b\n b (d1; nat_inc n) (nat_neg (nat_dec n))) - -# (int_dec x) is int x-1. -\int_dec=(\x x (d0; nat_1) \b\n b (nat_int (nat_dec n)) (d0; nat_inc n)) - -# (nat_sub x y) is x-y. (x minus y) The x, y are of type nat, but the -# result is of type int because the result might be negative. -\nat_sub==(\x\y x (nat_neg y) \bx\nx y (nat_int x) \by\ny - \z = (int_2x (nat_sub nx ny)) - bx (by I int_inc) (by int_dec I) z - ) - -# (nat_div x y) divides x by y. It yields a pair , where q is the -# quotient and r is the remainder. -# -# The result satisfies the equation x = q*y + r, 0 <= r < y. -# -# NOTE: If you divide by zero, the function yields the pair <0,0>. - -\nat_div==(\x\y\return - x (return nat_0 nat_0) \bx\nx - y (return nat_0 nat_0) \by\ny - by - ( - # divide by odd - nat_div nx y \q\r - \r=(bx nat_2x1 nat_2x r) - \d=(nat_sub r y) - int_ge0 d - (return (nat_2x1 q) (int_abs d)) - (return (nat_2x q) r) - ) - ( - # divide by even - nat_div nx ny \q\r - return q (bx nat_2x1 nat_2x r) - ) - ) - -\nat_compare == (\x\y \lt\eq\gt - x (y eq \_\_ lt) \bx\nx - y gt \by\ny - nat_compare nx ny - lt - (bx (by eq gt) (by lt eq)) - gt - ) - -\nat_le = (\x\y nat_compare x y T T F) -\nat_ge = (\x\y nat_compare x y F T T) - -\nat_2 = (d0 nat_1) -\nat_5 = (d1 nat_2) -\nat_10 = (d0 nat_5) - -\nat_div10 = (\x nat_div x nat_10) - -# Convert a nat into a machine long value, ignoring any overflow. -\nat_long = - ( - \nat_long == (\sum\pow\bits - bits sum \bit\bits - \sum = (bit (long_add pow) I sum) - \pow = (long_mul 2 pow) - nat_long sum pow bits - ) - - nat_long 0 1 - ) - -# (nat_base_10_lo n) is the list of ASCII decimal digits for n starting -# with the least significant digit. -\nat_base_10_lo == (\x - nat_div10 x \q\r - \ch = (long_add 48; nat_long r); - item ch; - nat_eq0 q end; - nat_base_10_lo q - ) - -# (nat_base_10 n) is the list of ASCII decimal digits for n starting -# with the most significant digit. -\nat_base_10=(\n reverse; nat_base_10_lo n) - -\nat_print = (\x chars_print (nat_base_10 x)) -\nat_print_lo = (\x chars_print (nat_base_10_lo x)) - -# for testing: -# show in reverse decimal -#\nat_print = nat_print_lo -# show in binary -#\nat_print = bits_print - -\int_base_10 = (\x - int_ge0 x - (nat_base_10; int_abs x) - (item 45; nat_base_10; int_abs x) - ) - -\int_print = (\x chars_print (int_base_10 x)) - -# LATER maybe char constants? e.g. '0' == 48 '-' == 45 -# This would be handled in the standard resolution context. It would not be -# part of the grammar. The symbol "'0'" would simply be resolved to the long -# value 48. - -###### - -\nat_2 = (d0 nat_1) -\nat_3 = (d1 nat_1) -\nat_4 = (d0 nat_2) -\nat_5 = (d1 nat_2) -\nat_6 = (d0 nat_3) -\nat_7 = (d1 nat_3) -\nat_8 = (d0 nat_4) -\nat_9 = (d1 nat_4) -\nat_10 = (d0 nat_5) -\nat_11 = (d1 nat_5) -\nat_12 = (d0 nat_6) -\nat_13 = (d1 nat_6) -\nat_14 = (d0 nat_7) -\nat_15 = (d1 nat_7) -\nat_16 = (d0 nat_8) -\nat_17 = (d1 nat_8) -\nat_18 = (d0 nat_9) -\nat_19 = (d1 nat_9) -\nat_32 = (d0 nat_16) -\nat_20 = (d0 nat_10) -\nat_24 = (d0 nat_12) -\nat_31 = (d1 nat_15) -\nat_48 = (d0 nat_24) -\nat_49 = (d1 nat_24) - -#### - -\test_fibonacci == -( - -# This lets you use either built-in arithmetic or arbitrary-precision -# arithmetic. - -\test_case == -( -\if_show_all -\number_type -\num_rounds - -if_show_all -( -print "Print the first ";print num_rounds; print " Fibonacci numbers "; -print "using number type ";print number_type;nl; -) -( -print "Print the Fibonacci number at position ";print num_rounds; -print " using number type ";print number_type;nl; -) - -\choose = -( -\return -\case = (string_eq number_type) -case "double" (return print double_add 1.0); -case "nat" (return nat_print nat_add nat_1); -halt -) - -choose \num_print \num_add \num_1 - -\nums_print = (list_do \x num_print x; nl) - -# Produces the infinite list of all Fibonacci numbers. -\fibonacci = - ( - \1 - \add - - \fibonacci == (\x\y - item x; - \z = (add x y) - fibonacci y z - ) - - fibonacci 1 1 - ) - -\fibonacci = (fibonacci num_1 num_add) - -if_show_all -(nums_print; list_prefix fibonacci num_rounds) -(num_print; list_at fibonacci (long_sub num_rounds 1) num_1) -nl; -) - -#test_case T "nat" 200; -#test_case T "nat" 2000; -#test_case T "nat" 1; -#test_case T "nat" 2; -#test_case T "nat" 3; -#test_case F "nat" 4; -#test_case F "double" 4; -#test_case F "nat" 1000; -#test_case F "nat" 100; -#test_case T "nat" 100; -#test_case F "double" 1000; -#test_case F "nat" 10000; -#test_case T "nat" 100; -#test_case T "nat" 10; -#test_case F "nat" 500; - -#test_case T "double" 200; -#test_case T "nat" 200; -#test_case F "nat" 200; -#test_case F "nat" 2000; - -test_case T "nat" 300; -test_case F "nat" 1600; # 10.208s -) - -#### -\test_binary_counter == -( - -\loop == -( -\count -\num -long_le count 0 I; -print (nat_long num); print " "; -bits_print num; -nl; -\count = (long_sub count 1) -\num = (nat_inc num) -loop count num -) - -loop 50 nat_0 -) - -\test_divide== -( -# LATER automatically check the constraints -\test_div = (\x\y - nat_div x y \q\r - print "test_div";nl; - \show=(\key\val print key;print " = "; nat_print val; nl;) - show "x" x; - show "y" y; - show "q" q; - show "r" r; - nl; - ) - -test_div nat_0 nat_0; -test_div nat_0 nat_1; -test_div nat_1 nat_0; -test_div nat_1 nat_1; -test_div nat_2 nat_1; - -test_div nat_0 nat_2; -test_div nat_1 nat_2; -test_div nat_2 nat_2; -test_div nat_3 nat_2; -test_div nat_4 nat_2; - -test_div nat_0 nat_3; -test_div nat_1 nat_3; -test_div nat_2 nat_3; -test_div nat_3 nat_3; -test_div nat_4 nat_3; -test_div nat_5 nat_3; -test_div nat_6 nat_3; -test_div nat_7 nat_3; -test_div nat_8 nat_3; -test_div nat_9 nat_3; -test_div nat_10 nat_3; -test_div nat_11 nat_3; -test_div nat_12 nat_3; - -test_div nat_0 nat_4; -test_div nat_1 nat_4; -test_div nat_2 nat_4; -test_div nat_3 nat_4; -test_div nat_4 nat_4; -test_div nat_5 nat_4; -test_div nat_6 nat_4; -test_div nat_7 nat_4; -test_div nat_8 nat_4; -test_div nat_9 nat_4; -test_div nat_10 nat_4; -test_div nat_11 nat_4; -test_div nat_12 nat_4; -test_div nat_12 nat_4; - -test_div nat_0 nat_5; -test_div nat_1 nat_5; -test_div nat_2 nat_5; -test_div nat_3 nat_5; -test_div nat_4 nat_5; -test_div nat_5 nat_5; -test_div nat_6 nat_5; -test_div nat_7 nat_5; -test_div nat_8 nat_5; -test_div nat_9 nat_5; -test_div nat_10 nat_5; -test_div nat_11 nat_5; -test_div nat_12 nat_5; -test_div nat_13 nat_5; -test_div nat_14 nat_5; -test_div nat_15 nat_5; -test_div nat_16 nat_5; -test_div nat_17 nat_5; -test_div nat_18 nat_5; -test_div nat_19 nat_5; - -\big_test = -( -\next -\x = (nat_mul nat_31 nat_19) -\churn = (\x nat_add nat_17; nat_mul x x) -\x = (churn x) -\x = (churn x) -\x = (churn x) -\x = (churn x) -\x = (churn x) -\x = (churn x) -\y =nat_10 -\y=(nat_mul y y) - -test_div x y; -test_div (churn x) (churn; churn; churn; churn; churn; churn y); -next -) - -big_test -#big_test; -#big_test; -#big_test; -#big_test; -) - -\test_sub == -( -\test_sub = (\x\y - \z = (nat_sub x y) - print "== test_sub: "; - nat_print x; - print " - "; - nat_print y; - print " = "; - int_print z;nl; - ) - -test_sub nat_0 nat_0 -test_sub nat_1 nat_0 -test_sub nat_2 nat_0 -test_sub nat_3 nat_0 -test_sub nat_4 nat_0 - -test_sub nat_1 nat_1 -test_sub nat_0 nat_1 - -test_sub nat_0 nat_2 -test_sub nat_1 nat_2 -test_sub nat_2 nat_2 -test_sub nat_3 nat_2 -test_sub nat_4 nat_2 - -test_sub nat_0 nat_3 -test_sub nat_1 nat_3 -test_sub nat_2 nat_3 -test_sub nat_3 nat_3 -test_sub nat_4 nat_3 -test_sub nat_5 nat_3 -test_sub nat_6 nat_3 - -test_sub nat_0 nat_4 -test_sub nat_1 nat_4 -test_sub nat_2 nat_4 -test_sub nat_3 nat_4 -test_sub nat_4 nat_4 -test_sub nat_5 nat_4 -test_sub nat_6 nat_4 -test_sub nat_7 nat_4 - -test_sub nat_0 nat_5 -test_sub nat_1 nat_5 -test_sub nat_2 nat_5 -test_sub nat_3 nat_5 -test_sub nat_4 nat_5 -test_sub nat_5 nat_5 -test_sub nat_6 nat_5 -test_sub nat_7 nat_5 -test_sub nat_8 nat_5 -test_sub nat_9 nat_5 - -test_sub nat_3 nat_19 -test_sub nat_19 nat_19 -test_sub nat_49 nat_19 -test_sub nat_48 nat_19 -) - -\return return test_fibonacci test_binary_counter test_divide - test_sub -) - -module_test_arithmetic -\test_fibonacci \test_binary_counter \test_divide \test_sub - -######## - -# Choose your test(s) to run down here. Comment the ones don't want to run. - -\test_string_type== -( -\test_case=(\x\expect - \result = (string_type x "yes" "no") - print "string_type "; print result; - print " ["; - print (string_eq result expect "GOOD" "BAD"); - print "]"; - nl; - ) - -test_case 4 "no" -test_case 2.3 "no" -test_case (\x\y y x) "no" -test_case C "no" -test_case (string_append "hello " "world") "yes" -test_case ((\x\y y x) "hi" I) "yes" -test_case "hey!" "yes" -) - -\test_double_type== -( -\test_case=(\x\expect - \result = (double_type x "yes" "no") - print "double_type "; print result; - print " ["; - print (string_eq result expect "GOOD" "BAD"); - print "]"; - nl; - ) - -test_case 4 "no" -test_case 2.3 "yes" -test_case (\x\y y x) "no" -test_case C "no" -test_case (string_append "hello " "world") "no" -test_case ((\x\y y x) (double_add 4.2 2.6) I) "yes" -test_case "hey!" "no" -) - -\test_long_type== -( -\test_case=(\x\expect - \result = (long_type x "yes" "no") - print "long_type "; print result; - print " ["; - print (string_eq result expect "GOOD" "BAD"); - print "]"; - nl; - ) - -test_case 4 "yes" -test_case 2.3 "no" -test_case (\x\y y x) "no" -test_case C "no" -test_case (string_append "hello " "world") "no" -test_case ((\x\y y x) (long_add 4 2) I) "yes" -test_case "hey!" "no" -) - -\test_string_long == -( -\test_case=(\x\expect - \quote = ~@ "@ - \result = (string_long x "no" \n string_append "yes " (long_string n)) - print "string_long "; - string_put quote; string_put x; string_put quote - print " : "; print result; - print " ["; - print (string_eq result expect "GOOD" "BAD"); - print "]"; - nl; - ) - -test_case "0" "yes 0" -test_case "1" "yes 1" -test_case "-1" "yes -1" -test_case "123" "yes 123" -test_case "-123" "yes -123" -test_case "x123" "no" -test_case "1x23" "no" -test_case "" "no" -test_case " 456 " "no" -test_case "456 " "no" -test_case "1.6" "no" -test_case "0." "no" -) - -\test_string_double == -( -\test_case=(\x\expect - \quote = ~@ "@ - \result = (string_double x "no" \n string_append "yes " (double_string n)) - print "string_double "; - string_put quote; string_put x; string_put quote - print " : "; print result; - print " ["; - print (string_eq result expect "GOOD" "BAD"); - print "]"; - nl; - ) - -test_case "0" "yes 0" -test_case "1" "yes 1" -test_case "-1" "yes -1" -test_case "123" "yes 123" -test_case "-123" "yes -123" -test_case "x123" "no" -test_case "1x23" "no" -test_case "" "no" -test_case " 456 " "no" -test_case " 456.78 " "no" -test_case "456.78" "yes 456.78" -test_case "456 " "no" -test_case "1.6" "yes 1.6" -test_case "0." "yes 0" -test_case "-0" "yes -0" -test_case "-0.0" "yes -0" -test_case "-0.0123" "yes -0.0123" -) - -\test_long_double == -( -\test_case = ( -\x -\y = (long_double x) - -\x_str = (long_string x) -\y_str = (double_string y) - -print "long x = "; string_put x_str; -print " double y = "; string_put y_str;nl; -) - -test_case 4 -test_case 0 -test_case -1 -test_case -37 -test_case 126478 -) - -\test_double_long == -( -\test_case = ( -\x -\y = (double_long x) - -\x_str = (double_string x) -\y_str = (long_string y) - -print "double x = "; string_put x_str; -print " long y = "; string_put y_str;nl; -) - -test_case 4.0 -test_case 0.0 -test_case -1.0 -test_case -37.0 -test_case 126478.0 -test_case 4.3 -test_case 0.3 -test_case -1.3 -test_case -37.3 -test_case 126478.3 -test_case 4.9 -test_case 0.9 -test_case -1.9 -test_case -37.9 -test_case 126478.9 -test_case -126478.9 -) - -#### - -test_string_type -test_double_type -test_long_type - -test_long_double -test_double_long - -test_string_long -test_string_double - -test_hello_world -test_string_slice -test_write_binary -test_string_len -test_string_at -test_string_compare -test_string_common -test_long_add -test_double_compare -test_procedural -test_eager - -test_binary_counter; -test_divide; -test_sub; -test_fibonacci -test_cat - -\\Extra stuff down here becomes input -to the test_cat function. diff --git a/grammars/fexl/fexl.peg b/grammars/fexl/fexl.peg deleted file mode 100644 index 82167cf..0000000 --- a/grammars/fexl/fexl.peg +++ /dev/null @@ -1,35 +0,0 @@ -package main - -type Fexl Peg { - -} - -Fexl <- ws Expression+ Input? !. - -Input <- '\\\\' .* - -Expression <- Comment / ';' ws Expression* / Definition / Argument / Term - -Comment <- '#' (![\n\r] .)* ws - -Definition <- '\\' Symbol '=' ws Term / Recursive - -Recursive <- '\\' Symbol '==' ws Term - -Argument <- '\\' Symbol - -Term <- open Expression+ close / Symbol - -Symbol <- (String / (![ \t\n\r\\()"~;=] .)+) ws - -String <- '"' (!'"' .)* '"' / Complex - -Complex <- tilde '@' (!'@' .)* '@' - -tilde <- '~' - -open <- '(' ws - -close <- ')' ws - -ws <- [ \t\n\r]* diff --git a/grammars/fexl/main.go b/grammars/fexl/main.go deleted file mode 100644 index d1d522e..0000000 --- a/grammars/fexl/main.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "log" - "io/ioutil" -) - -func main() { - buffer, err := ioutil.ReadFile("doc/try.fxl") - if err != nil { - log.Fatal(err) - } - - fexl := &Fexl{Buffer: string(buffer)} - fexl.Init() - - if err := fexl.Parse(); err != nil { - log.Fatal(err) - } - fexl.Highlighter() -} diff --git a/grammars/java/Makefile b/grammars/java/Makefile deleted file mode 100644 index 23a6353..0000000 --- a/grammars/java/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -java: java_1_7.peg.go main.go - go build - -java_1_7.peg.go: java_1_7.peg - ../../peg -switch -inline java_1_7.peg - -clean: - rm -f java java_1_7.peg.go diff --git a/grammars/java/java_1_7.peg b/grammars/java/java_1_7.peg deleted file mode 100644 index 32abdc1..0000000 --- a/grammars/java/java_1_7.peg +++ /dev/null @@ -1,872 +0,0 @@ -#=========================================================================== -# -# Parsing Expression Grammar for Java 1.7 for Mouse 1.1 - 1.5. -# Based on Chapters 3 and 18 of Java Language Specification, Third Edition, -# at http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html, -# and description of Java SE 7 enhancements in -# http://download.java.net/jdk7/docs/technotes/guides/language/enhancements.html. -# -#--------------------------------------------------------------------------- -# -# Copyright (C) 2006, 2009, 2010, 2011 -# by Roman R Redziejowski(www.romanredz.se). -# -# The author gives unlimited permission to copy and distribute -# this file, with or without modifications, as long as this notice -# is preserved, and any changes are properly documented. -# -# This file is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -#--------------------------------------------------------------------------- -# -# Latest update 2011-07-21 -# -#--------------------------------------------------------------------------- -# -# Change log -# 2006-12-06 Posted on Internet. -# 2009-04-04 Modified to conform to Mouse syntax: -# Underscore removed from names -# \f in Space replaced by Unicode for FormFeed. -# 2009-07-10 Unused rule THREADSAFE removed. -# 2009-07-10 Copying and distribution conditions relaxed by the author. -# 2010-07-01 Updated Mouse version in the comment. -# 2010-09-15 Updated comment on Java release. -# 2010-09-18 Updated list of reserved words ("keywords") according to -# JLS 3.9: added "const" and "goto", removed "threadsafe". -# 2010-09-18 Removed superfluous "?" everywhere after "Spacing". -# 2010-10-05 Removed erroneous "TypeArguments?" from "EnumConstant". -# See JLS 8.9, JLS 18.1. -# NB. "Annotations" are optional, but not shown as such in JLS. -# 2010-10-20 Corrected "FormalParameterList" according to JLS 8.4.1. -# NB. "VariableModifiers" in "FormalParameter" and "LastFormalParameter" -# are optional, but not shown as such in JLS. -# 2010-10-20 Corrected "Annotation" according to JLS 9.7. -# Is incorrect in JLS 18.1 (does not allow list of value pairs). -# 2010-10-20 Corrected "LocalVariableDeclarationStatement". -# Is incorrect in JLS 18.1: only FINAL allowed as "VariableModifier". -# Is incorrect in JLS 14.4: "VariableModifiers" not shown as optional. -# 2010-10-20 Corrected "AnnotationTypeElementRest": added SEMI as last alternative. -# See JLS 9.6. NB. Missing in JLS 18.1. -# 2010-10-20 Moved "Identifier" from "AnnotationTypeElementRest" to -# "AnnotationMethodRest". Was incorrect in JLS 18.1. -# 2010-10-21 Inverted order of alternatives in "HexSignificand". -# 2010-10-24 Corrected previous correction: moved SEMI from -# "AnnotationTypeElementRest" to "AnnotationTypeElementDeclaration". -# 2010-10-25 Repeated "u" allowed in UnicodeEscape (JLS 3.3). -# Line terminators not allowed in StringLiteral (JLS 3.10.5). -# (Found thanks to Java PEG for Parboiled, which in turn credits -# Reinier Zwitserloot for finding it.) -# 2011-07-19 Added SEMI after "VariableDeclarators" in "MemberDecl" (JLS 8.3). -# 2011-07-21 Corrected "ArrayInitializer" to allow for "{,}" (JLS 10.6). -# -#--------------------------------------------------------------------------- -# -# Changes for Java 1.7 -# 2011-07-18 Implemented Binary Literals: added "BinaryNumeral". -# 2011-07-19 Implemented Underscores in Numerical Literals: -# Added "Digits" and "HexDigits". Removed "Digit". -# Modified "DecimalNumeral", "HexNumeral", "BinaryNumeral", -# "OctalNumeral", "DecimalFloat", "Exponent", -# "HexSignificand", and "BinaryExponent". -# 2011-07-20 Implemented Type Inference for Generic Instance Creation: -# Added "Diamond". -# Modified "ClassCreatorRest" by adding "Diamond?". -# 2011-07-20 Implemented try-with-resources Statement: -# Added try-with-resources as an alternative of "Statement". -# Added "Resource". (Based on comments to JavacParser). -# 2011-07-20 Implemented catching of multiple exceptions: -# Modified "Catch" to allow multiple exception types. -# Based on a pure guess. -# -#--------------------------------------------------------------------------- -# -# 2013-02-16 Modified to work with github.com/pointlander/peg -# -#=========================================================================== - -#------------------------------------------------------------------------- -# Compilation Unit -#------------------------------------------------------------------------- - -package main - -type Java Peg { - -} - -CompilationUnit <- Spacing PackageDeclaration? ImportDeclaration* TypeDeclaration* EOT -PackageDeclaration <- Annotation* PACKAGE QualifiedIdentifier SEMI -ImportDeclaration <- IMPORT STATIC? QualifiedIdentifier (DOT STAR)? SEMI - -TypeDeclaration <- Modifier* (ClassDeclaration - / EnumDeclaration - / InterfaceDeclaration - / AnnotationTypeDeclaration) - / SEMI - -#------------------------------------------------------------------------- -# Class Declaration -#------------------------------------------------------------------------- - -ClassDeclaration <- CLASS Identifier TypeParameters? (EXTENDS ClassType)? (IMPLEMENTS ClassTypeList)? ClassBody - -ClassBody <- LWING ClassBodyDeclaration* RWING - -ClassBodyDeclaration - <- SEMI - / STATIC? Block # Static or Instance Initializer - / Modifier* MemberDecl # ClassMemberDeclaration - -MemberDecl - <- TypeParameters GenericMethodOrConstructorRest # Generic Method or Constructor - / Type Identifier MethodDeclaratorRest # Method - / Type VariableDeclarators SEMI # Field - / VOID Identifier VoidMethodDeclaratorRest # Void method - / Identifier ConstructorDeclaratorRest # Constructor - / InterfaceDeclaration # Interface - / ClassDeclaration # Class - / EnumDeclaration # Enum - / AnnotationTypeDeclaration # Annotation - -GenericMethodOrConstructorRest - <- (Type / VOID) Identifier MethodDeclaratorRest - / Identifier ConstructorDeclaratorRest - -MethodDeclaratorRest - <- FormalParameters Dim* (THROWS ClassTypeList)? (MethodBody / SEMI) - -VoidMethodDeclaratorRest - <- FormalParameters (THROWS ClassTypeList)? (MethodBody / SEMI) - -ConstructorDeclaratorRest - <- FormalParameters (THROWS ClassTypeList)? MethodBody - -MethodBody - <- Block - -#------------------------------------------------------------------------- -# Interface Declaration -#------------------------------------------------------------------------- - -InterfaceDeclaration - <- INTERFACE Identifier TypeParameters? (EXTENDS ClassTypeList)? InterfaceBody - -InterfaceBody - <- LWING InterfaceBodyDeclaration* RWING - -InterfaceBodyDeclaration - <- Modifier* InterfaceMemberDecl - / SEMI - -InterfaceMemberDecl - <- InterfaceMethodOrFieldDecl - / InterfaceGenericMethodDecl - / VOID Identifier VoidInterfaceMethodDeclaratorRest - / InterfaceDeclaration - / AnnotationTypeDeclaration - / ClassDeclaration - / EnumDeclaration - -InterfaceMethodOrFieldDecl - <- Type Identifier InterfaceMethodOrFieldRest - -InterfaceMethodOrFieldRest - <- ConstantDeclaratorsRest SEMI - / InterfaceMethodDeclaratorRest - -InterfaceMethodDeclaratorRest - <- FormalParameters Dim* (THROWS ClassTypeList)? SEM - -InterfaceGenericMethodDecl - <- TypeParameters (Type / VOID) Identifier InterfaceMethodDeclaratorRest - -VoidInterfaceMethodDeclaratorRest - <- FormalParameters (THROWS ClassTypeList)? SEMI - -ConstantDeclaratorsRest - <- ConstantDeclaratorRest (COMMA ConstantDeclarator)* - -ConstantDeclarator - <- Identifier ConstantDeclaratorRest - -ConstantDeclaratorRest - <- Dim* EQU VariableInitializer - -#------------------------------------------------------------------------- -# Enum Declaration -#------------------------------------------------------------------------- - -EnumDeclaration - <- ENUM Identifier (IMPLEMENTS ClassTypeList)? EnumBody - -EnumBody - <- LWING EnumConstants? COMMA? EnumBodyDeclarations? RWING - -EnumConstants - <- EnumConstant (COMMA EnumConstant)* - -EnumConstant - <- Annotation* Identifier Arguments? ClassBody? - -EnumBodyDeclarations - <- SEMI ClassBodyDeclaration* - -#------------------------------------------------------------------------- -# Variable Declarations -#------------------------------------------------------------------------- - -LocalVariableDeclarationStatement - <- (FINAL / Annotation)* Type VariableDeclarators SEMI - -VariableDeclarators - <- VariableDeclarator (COMMA VariableDeclarator)* - -VariableDeclarator - <- Identifier Dim* (EQU VariableInitializer)? - -#------------------------------------------------------------------------- -# Formal Parameters -#------------------------------------------------------------------------- - -FormalParameters - <- LPAR FormalParameterList? RPAR - -FormalParameter - <- (FINAL / Annotation)* Type VariableDeclaratorId - -LastFormalParameter - <- (FINAL / Annotation)* Type ELLIPSIS VariableDeclaratorId - -FormalParameterList - <- FormalParameter (COMMA FormalParameter)* (COMMA LastFormalParameter)? - / LastFormalParameter - -VariableDeclaratorId - <- Identifier Dim* - -#------------------------------------------------------------------------- -# Statements -#------------------------------------------------------------------------- - -Block - <- LWING BlockStatements RWING - -BlockStatements - <- BlockStatement* - -BlockStatement - <- LocalVariableDeclarationStatement - / Modifier* - ( ClassDeclaration - / EnumDeclaration - ) - / Statement - -Statement - <- Block - / ASSERT Expression (COLON Expression)? SEMI - / IF ParExpression Statement (ELSE Statement)? - / FOR LPAR ForInit? SEMI Expression? SEMI ForUpdate? RPAR Statement - / FOR LPAR FormalParameter COLON Expression RPAR Statement - / WHILE ParExpression Statement - / DO Statement WHILE ParExpression SEMI - / TRY LPAR Resource (SEMI Resource)* SEMI? RPAR Block Catch* Finally? - / TRY Block (Catch+ Finally? / Finally) - / SWITCH ParExpression LWING SwitchBlockStatementGroups RWING - / SYNCHRONIZED ParExpression Block - / RETURN Expression? SEMI - / THROW Expression SEMI - / BREAK Identifier? SEMI - / CONTINUE Identifier? SEMI - / SEMI - / StatementExpression SEMI - / Identifier COLON Statement - -Resource - <- Modifier* Type VariableDeclaratorId EQU Expression - -Catch - <- CATCH LPAR (FINAL / Annotation)* Type (OR Type)* VariableDeclaratorId RPAR Block - -Finally - <- FINALLY Block - -SwitchBlockStatementGroups - <- SwitchBlockStatementGroup* - -SwitchBlockStatementGroup - <- SwitchLabel BlockStatements - -SwitchLabel - <- CASE ConstantExpression COLON - / CASE EnumConstantName COLON - / DEFAULT COLON - -ForInit - <- (FINAL / Annotation)* Type VariableDeclarators - / StatementExpression (COMMA StatementExpression)* - -ForUpdate - <- StatementExpression (COMMA StatementExpression)* - -EnumConstantName - <- Identifier - -#------------------------------------------------------------------------- -# Expressions -#------------------------------------------------------------------------- - -StatementExpression - <- Expression - - # This is more generous than definition in section 14.8, which allows only - # specific forms of Expression. - - -ConstantExpression - <- Expression - -Expression - <- ConditionalExpression (AssignmentOperator ConditionalExpression)* - - # This definition is part of the modification in JLS Chapter 18 - # to minimize look ahead. In JLS Chapter 15.27, Expression is defined - # as AssignmentExpression, which is effectively defined as - # (LeftHandSide AssignmentOperator)* ConditionalExpression. - # The above is obtained by allowing ANY ConditionalExpression - # as LeftHandSide, which results in accepting statements like 5 = a. - - -AssignmentOperator - <- EQU - / PLUSEQU - / MINUSEQU - / STAREQU - / DIVEQU - / ANDEQU - / OREQU - / HATEQU - / MODEQU - / SLEQU - / SREQU - / BSREQU - -ConditionalExpression - <- ConditionalOrExpression (QUERY Expression COLON ConditionalOrExpression)* - -ConditionalOrExpression - <- ConditionalAndExpression (OROR ConditionalAndExpression)* - -ConditionalAndExpression - <- InclusiveOrExpression (ANDAND InclusiveOrExpression)* - -InclusiveOrExpression - <- ExclusiveOrExpression (OR ExclusiveOrExpression)* - -ExclusiveOrExpression - <- AndExpression (HAT AndExpression)* - -AndExpression - <- EqualityExpression (AND EqualityExpression)* - -EqualityExpression - <- RelationalExpression ((EQUAL / NOTEQUAL) RelationalExpression)* - -RelationalExpression - <- ShiftExpression ((LE / GE / LT / GT) ShiftExpression / INSTANCEOF ReferenceType)* - -ShiftExpression - <- AdditiveExpression ((SL / SR / BSR) AdditiveExpression)* - -AdditiveExpression - <- MultiplicativeExpression ((PLUS / MINUS) MultiplicativeExpression)* - -MultiplicativeExpression - <- UnaryExpression ((STAR / DIV / MOD) UnaryExpression)* - -UnaryExpression - <- PrefixOp UnaryExpression - / LPAR Type RPAR UnaryExpression - / Primary (Selector)* (PostfixOp)* - -Primary - <- ParExpression - / NonWildcardTypeArguments (ExplicitGenericInvocationSuffix / THIS Arguments) - / THIS Arguments? - / SUPER SuperSuffix - / Literal - / NEW Creator - / QualifiedIdentifier IdentifierSuffix? - / BasicType Dim* DOT CLASS - / VOID DOT CLASS - -IdentifierSuffix - <- LBRK ( RBRK Dim* DOT CLASS / Expression RBRK) - / Arguments - / DOT - ( CLASS - / ExplicitGenericInvocation - / THIS - / SUPER Arguments - / NEW NonWildcardTypeArguments? InnerCreator - ) - -ExplicitGenericInvocation - <- NonWildcardTypeArguments ExplicitGenericInvocationSuffix - -NonWildcardTypeArguments - <- LPOINT ReferenceType (COMMA ReferenceType)* RPOINT - -ExplicitGenericInvocationSuffix - <- SUPER SuperSuffix - / Identifier Arguments - -PrefixOp - <- INC - / DEC - / BANG - / TILDA - / PLUS - / MINUS - -PostfixOp - <- INC - / DEC - -Selector - <- DOT Identifier Arguments? - / DOT ExplicitGenericInvocation - / DOT THIS - / DOT SUPER SuperSuffix - / DOT NEW NonWildcardTypeArguments? InnerCreator - / DimExpr - -SuperSuffix - <- Arguments - / DOT Identifier Arguments? - -BasicType - <- ( 'byte' - / 'short' - / 'char' - / 'int' - / 'long' - / 'float' - / 'double' - / 'boolean' - ) !LetterOrDigit Spacing - -Arguments - <- LPAR (Expression (COMMA Expression)*)? RPAR - -Creator - <- NonWildcardTypeArguments? CreatedName ClassCreatorRest - / NonWildcardTypeArguments? (ClassType / BasicType) ArrayCreatorRest - -CreatedName - <- Identifier NonWildcardTypeArguments? (DOT Identifier NonWildcardTypeArguments?)* - -InnerCreator - <- Identifier ClassCreatorRest - -ArrayCreatorRest - <- LBRK ( RBRK Dim* ArrayInitializer / Expression RBRK DimExpr* Dim* ) - - # This is more generous than JLS 15.10. According to that definition, - # BasicType must be followed by at least one DimExpr or by ArrayInitializer. - - -ClassCreatorRest - <- Diamond? Arguments ClassBody? - -Diamond - <- LPOINT RPOINT - -ArrayInitializer - <- LWING (VariableInitializer (COMMA VariableInitializer)*)? COMMA? RWING - -VariableInitializer - <- ArrayInitializer - / Expression - -ParExpression - <- LPAR Expression RPAR - -QualifiedIdentifier - <- Identifier (DOT Identifier)* - -Dim - <- LBRK RBRK - -DimExpr - <- LBRK Expression RBRK - -#------------------------------------------------------------------------- -# Types and Modifiers -#------------------------------------------------------------------------- - -Type - <- (BasicType / ClassType) Dim* - -ReferenceType - <- BasicType Dim+ - / ClassType Dim* - -ClassType - <- Identifier TypeArguments? (DOT Identifier TypeArguments?)* - -ClassTypeList - <- ClassType (COMMA ClassType)* - -TypeArguments - <- LPOINT TypeArgument (COMMA TypeArgument)* RPOINT - -TypeArgument - <- ReferenceType - / QUERY ((EXTENDS / SUPER) ReferenceType)? - -TypeParameters - <- LPOINT TypeParameter (COMMA TypeParameter)* RPOINT - -TypeParameter - <- Identifier (EXTENDS Bound)? - -Bound - <- ClassType (AND ClassType)* - -Modifier - <- Annotation - / ( 'public' - / 'protected' - / 'private' - / 'static' - / 'abstract' - / 'final' - / 'native' - / 'synchronized' - / 'transient' - / 'volatile' - / 'strictfp' - ) !LetterOrDigit Spacing - - # This common definition of Modifier is part of the modification - # in JLS Chapter 18 to minimize look ahead. The main body of JLS has - # different lists of modifiers for different language elements. - -#------------------------------------------------------------------------- -# Annotations -#------------------------------------------------------------------------- - -AnnotationTypeDeclaration - <- AT INTERFACE Identifier AnnotationTypeBody - -AnnotationTypeBody - <- LWING AnnotationTypeElementDeclaration* RWING - -AnnotationTypeElementDeclaration - <- Modifier* AnnotationTypeElementRest - / SEMI - -AnnotationTypeElementRest - <- Type AnnotationMethodOrConstantRest SEMI - / ClassDeclaration - / EnumDeclaration - / InterfaceDeclaration - / AnnotationTypeDeclaration - -AnnotationMethodOrConstantRest - <- AnnotationMethodRest - / AnnotationConstantRest - -AnnotationMethodRest - <- Identifier LPAR RPAR DefaultValue? - -AnnotationConstantRest - <- VariableDeclarators - -DefaultValue - <- DEFAULT ElementValue - -Annotation - <- NormalAnnotation - / SingleElementAnnotation - / MarkerAnnotation - -NormalAnnotation - <- AT QualifiedIdentifier LPAR ElementValuePairs? RPAR - -SingleElementAnnotation - <- AT QualifiedIdentifier LPAR ElementValue RPAR - -MarkerAnnotation - <- AT QualifiedIdentifier - -ElementValuePairs - <- ElementValuePair (COMMA ElementValuePair)* - -ElementValuePair - <- Identifier EQU ElementValue - -ElementValue - <- ConditionalExpression - / Annotation - / ElementValueArrayInitializer - -ElementValueArrayInitializer - <- LWING ElementValues? COMMA? RWING - -ElementValues - <- ElementValue (COMMA ElementValue)* - - -#========================================================================= -# Lexical Structure -#========================================================================= -#------------------------------------------------------------------------- -# JLS 3.6-7 Spacing -#------------------------------------------------------------------------- - -Spacing - <- ( [ \t\r\n]+ # WhiteSpace [ \t\r\n\u000C]+ - / '/*' (!'*/' .)* '*/' # TraditionalComment - / '//' (![\r\n] .)* [\r\n] # EndOfLineComment - )* - -#------------------------------------------------------------------------- -# JLS 3.8 Identifiers -#------------------------------------------------------------------------- - -Identifier <- !Keyword Letter LetterOrDigit* Spacing - -Letter <- [a-z] / [A-Z] / [_$] - -LetterOrDigit <- [a-z] / [A-Z] / [0-9] / [_$] - - # These are traditional definitions of letters and digits. - # JLS defines letters and digits as Unicode characters recognized - # as such by special Java procedures, which is difficult - # to express in terms of Parsing Expressions. - -#------------------------------------------------------------------------- -# JLS 3.9 Keywords -# More precisely: reserved words. According to JLS, "true", "false", -# and "null" are technically not keywords - but still must not appear -# as identifiers. Keywords "const" and "goto" are not used; JLS explains -# the reason. -#------------------------------------------------------------------------- - -Keyword - <- ( 'abstract' - / 'assert' - / 'boolean' - / 'break' - / 'byte' - / 'case' - / 'catch' - / 'char' - / 'class' - / 'const' - / 'continue' - / 'default' - / 'double' - / 'do' - / 'else' - / 'enum' - / 'extends' - / 'false' - / 'finally' - / 'final' - / 'float' - / 'for' - / 'goto' - / 'if' - / 'implements' - / 'import' - / 'interface' - / 'int' - / 'instanceof' - / 'long' - / 'native' - / 'new' - / 'null' - / 'package' - / 'private' - / 'protected' - / 'public' - / 'return' - / 'short' - / 'static' - / 'strictfp' - / 'super' - / 'switch' - / 'synchronized' - / 'this' - / 'throws' - / 'throw' - / 'transient' - / 'true' - / 'try' - / 'void' - / 'volatile' - / 'while' - ) !LetterOrDigit - -ASSERT <- 'assert' !LetterOrDigit Spacing -BREAK <- 'break' !LetterOrDigit Spacing -CASE <- 'case' !LetterOrDigit Spacing -CATCH <- 'catch' !LetterOrDigit Spacing -CLASS <- 'class' !LetterOrDigit Spacing -CONTINUE <- 'continue' !LetterOrDigit Spacing -DEFAULT <- 'default' !LetterOrDigit Spacing -DO <- 'do' !LetterOrDigit Spacing -ELSE <- 'else' !LetterOrDigit Spacing -ENUM <- 'enum' !LetterOrDigit Spacing -EXTENDS <- 'extends' !LetterOrDigit Spacing -FINALLY <- 'finally' !LetterOrDigit Spacing -FINAL <- 'final' !LetterOrDigit Spacing -FOR <- 'for' !LetterOrDigit Spacing -IF <- 'if' !LetterOrDigit Spacing -IMPLEMENTS <- 'implements' !LetterOrDigit Spacing -IMPORT <- 'import' !LetterOrDigit Spacing -INTERFACE <- 'interface' !LetterOrDigit Spacing -INSTANCEOF <- 'instanceof' !LetterOrDigit Spacing -NEW <- 'new' !LetterOrDigit Spacing -PACKAGE <- 'package' !LetterOrDigit Spacing -RETURN <- 'return' !LetterOrDigit Spacing -STATIC <- 'static' !LetterOrDigit Spacing -SUPER <- 'super' !LetterOrDigit Spacing -SWITCH <- 'switch' !LetterOrDigit Spacing -SYNCHRONIZED <- 'synchronized' !LetterOrDigit Spacing -THIS <- 'this' !LetterOrDigit Spacing -THROWS <- 'throws' !LetterOrDigit Spacing -THROW <- 'throw' !LetterOrDigit Spacing -TRY <- 'try' !LetterOrDigit Spacing -VOID <- 'void' !LetterOrDigit Spacing -WHILE <- 'while' !LetterOrDigit Spacing - -#------------------------------------------------------------------------- -# JLS 3.10 Literals -#------------------------------------------------------------------------- - -Literal - <- ( FloatLiteral - / IntegerLiteral # May be a prefix of FloatLiteral - / CharLiteral - / StringLiteral - / 'true' !LetterOrDigit - / 'false' !LetterOrDigit - / 'null' !LetterOrDigit - ) Spacing - -IntegerLiteral - <- ( HexNumeral - / BinaryNumeral - / OctalNumeral # May be a prefix of HexNumeral or BinaryNumeral - / DecimalNumeral # May be a prefix of OctalNumeral - ) [lL]? - -DecimalNumeral <- '0' / [1-9] ([_]* [0-9])* - -HexNumeral <- ('0x' / '0X') HexDigits - -BinaryNumeral <- ('0b' / '0B') [01] ([_]* [01])* - -OctalNumeral <- '0' ([_]* [0-7])+ - -FloatLiteral <- HexFloat / DecimalFloat - -DecimalFloat - <- Digits '.' Digits? Exponent? [fFdD]? - / '.' Digits Exponent? [fFdD]? - / Digits Exponent [fFdD]? - / Digits Exponent? [fFdD] - -Exponent <- [eE] [+\-]? Digits - -HexFloat <- HexSignificand BinaryExponent [fFdD]? - -HexSignificand - <- ('0x' / '0X') HexDigits? '.' HexDigits - / HexNumeral '.'? # May be a prefix of above - -BinaryExponent <- [pP] [+\-]? Digits - -Digits <- [0-9]([_]*[0-9])* - -HexDigits <- HexDigit ([_]*HexDigit)* - -HexDigit <- [a-f] / [A-F] / [0-9] - -CharLiteral <- ['] (Escape / !['\\] .) ['] - -StringLiteral <- '\"' (Escape / !["\\\n\r] .)* '\"' - -Escape <- '\\' ([btnfr"'\\] / OctalEscape / UnicodeEscape) - -OctalEscape - <- [0-3][0-7][0-7] - / [0-7][0-7] - / [0-7] - -UnicodeEscape - <- 'u'+ HexDigit HexDigit HexDigit HexDigit - -#------------------------------------------------------------------------- -# JLS 3.11-12 Separators, Operators -#------------------------------------------------------------------------- - -AT <- '@' Spacing -AND <- '&'![=&] Spacing -ANDAND <- '&&' Spacing -ANDEQU <- '&=' Spacing -BANG <- '!' !'=' Spacing -BSR <- '>>>' !'=' Spacing -BSREQU <- '>>>=' Spacing -COLON <- ':' Spacing -COMMA <- ',' Spacing -DEC <- '--' Spacing -DIV <- '/' !'=' Spacing -DIVEQU <- '/=' Spacing -DOT <- '.' Spacing -ELLIPSIS <- '...' Spacing -EQU <- '=' !'=' Spacing -EQUAL <- '==' Spacing -GE <- '>=' Spacing -GT <- '>'![=>] Spacing -HAT <- '^' !'=' Spacing -HATEQU <- '^=' Spacing -INC <- '++' Spacing -LBRK <- '[' Spacing -LE <- '<=' Spacing -LPAR <- '(' Spacing -LPOINT <- '<' Spacing -LT <- '<' ![=<] Spacing -LWING <- '{' Spacing -MINUS <- '-' ![=\-] Spacing -MINUSEQU <- '-=' Spacing -MOD <- '%' !'=' Spacing -MODEQU <- '%=' Spacing -NOTEQUAL <- '!=' Spacing -OR <- '|' ![=|] Spacing -OREQU <- '|=' Spacing -OROR <- '||' Spacing -PLUS <- '+' ![=+] Spacing -PLUSEQU <- '+=' Spacing -QUERY <- '?' Spacing -RBRK <- ']' Spacing -RPAR <- ')' Spacing -RPOINT <- '>' Spacing -RWING <- '}' Spacing -SEMI <- ';' Spacing -SL <- '<<' !'=' Spacing -SLEQU <- '<<=' Spacing -SR <- '>>' ![=>] Spacing -SREQU <- '>>=' Spacing -STAR <- '*' !'=' Spacing -STAREQU <- '*=' Spacing -TILDA <- '~' Spacing - -EOT <- !. diff --git a/grammars/java/main.go b/grammars/java/main.go deleted file mode 100644 index 46f15fa..0000000 --- a/grammars/java/main.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "strings" -) - -func main() { - if len(os.Args) < 2 { - fmt.Printf("%v FILE\n", os.Args[0]) - os.Exit(1) - } - - var walk func(name string) - walk = func(name string) { - fileInfo, err := os.Stat(name) - if err != nil { - log.Fatal(err) - } - - if fileInfo.Mode() & (os.ModeNamedPipe | os.ModeSocket | os.ModeDevice) != 0 { - /* will lock up if opened */ - } else if fileInfo.IsDir() { - fmt.Printf("directory %v\n", name) - - file, err := os.Open(name) - if err != nil { - log.Fatal(err) - } - - files, err := file.Readdir(-1) - if err != nil { - log.Fatal(err) - } - file.Close() - - for _, f := range files { - if !strings.HasSuffix(name, "/") { - name += "/" - } - walk(name + f.Name()) - } - } else if strings.HasSuffix(name, ".java") { - fmt.Printf("parse %v\n", name) - - file, err := os.Open(name) - if err != nil { - log.Fatal(err) - } - - buffer, err := ioutil.ReadAll(file) - if err != nil { - log.Fatal(err) - } - file.Close() - - java := &Java{Buffer: string(buffer)} - java.Init() - if err := java.Parse(); err != nil { - log.Fatal(err) - } - } - } - walk(os.Args[1]) -} diff --git a/grammars/long_test/Makefile b/grammars/leg/calculator/Makefile similarity index 55% rename from grammars/long_test/Makefile rename to grammars/leg/calculator/Makefile index 0834fb6..85f7b41 100644 --- a/grammars/long_test/Makefile +++ b/grammars/leg/calculator/Makefile @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -long_test: long.peg.go main.go +calculator: calculator.leg.go main.go go build -long.peg.go: long.peg - peg -switch -inline long.peg +calculator.leg.go: calculator.leg + ../../../bin/leg calculator.leg clean: - rm -f long_test long.peg.go + rm -f calculator calculator.leg.go diff --git a/grammars/leg/calculator/calculator.leg b/grammars/leg/calculator/calculator.leg new file mode 100644 index 0000000..dd2de6c --- /dev/null +++ b/grammars/leg/calculator/calculator.leg @@ -0,0 +1,40 @@ + +package main + +YYSTYPE int + +type Calc Peg { +} + +Stmt = - e:Expr EOL { fmt.Println("ans: ", e)} + | ( !EOL . )* EOL { fmt.Println("ERROR")} + +Expr = i:ID ASSIGN s:Sum { } + | s:Sum { $$= s; } + +Sum = l:Product + ( PLUS r:Product { l += r; } + | MINUS r:Product { l -= r; } + )* { $$= l; } + +Product = l:Value + ( TIMES r:Value { l *= r; } + | DIVIDE r:Value { l /= r; } + )* { $$= l; } + +Value = i:NUMBER { temp, _ := strconv.Atoi(buffer[begin:end]); $$ = YYSTYPE(temp) } + | i:ID !ASSIGN { } + | OPEN i:Expr CLOSE { $$= i; } + +NUMBER = < [0-9]+ > - { temp, _ := strconv.Atoi(buffer[begin:end]); $$ = YYSTYPE(temp) } +ID = < [a-z] > - {} +ASSIGN = '=' - +PLUS = '+' - +MINUS = '-' - +TIMES = '*' - +DIVIDE = '/' - +OPEN = '(' - +CLOSE = ')' - + +- = [ \t]* +EOL = '\n' | '\r\n' | '\r' | ';' | !. \ No newline at end of file diff --git a/grammars/calculator/main.go b/grammars/leg/calculator/main.go similarity index 82% rename from grammars/calculator/main.go rename to grammars/leg/calculator/main.go index a9a3309..7dab251 100644 --- a/grammars/calculator/main.go +++ b/grammars/leg/calculator/main.go @@ -18,12 +18,11 @@ func main() { os.Exit(1) } expression := os.Args[1] - calc := &Calculator{Buffer: expression} + calc := &Calc{Buffer: expression} calc.Init() - calc.Expression.Init(expression) if err := calc.Parse(); err != nil { log.Fatal(err) } + // calc.PrintSyntaxTree() calc.Execute() - fmt.Printf("= %v\n", calc.Evaluate()) } diff --git a/grammars/long_test/long.peg b/grammars/long_test/long.peg deleted file mode 100644 index 211c2cf..0000000 --- a/grammars/long_test/long.peg +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -package main - -type Long Peg { - -} - -String <- '\"' (!'\"' .)* '\"' !. diff --git a/grammars/long_test/main.go b/grammars/long_test/main.go deleted file mode 100644 index 1cc9f75..0000000 --- a/grammars/long_test/main.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "log" -) - -func main() { - expression := "" - long := &Long{Buffer: "\"" + expression + "\""} - long.Init() - for c := 0; c < 100000; c++ { - if err := long.Parse(); err != nil { - fmt.Printf("%v\n", c) - log.Fatal(err) - } - long.Reset() - expression = expression + "X" - long.Buffer = "\"" + expression + "\"" - } -} diff --git a/peg.go b/peg.go deleted file mode 100644 index fa86472..0000000 --- a/peg.go +++ /dev/null @@ -1,1543 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "bytes" - "fmt" - "go/parser" - "go/printer" - "go/token" - "os" - "strconv" - "strings" - "text/template" -) - -const PEG_HEADER_TEMPLATE = `package {{.PackageName}} - -import ( - /*"bytes"*/ - "fmt" - "math" - "sort" - "strconv" -) - -const END_SYMBOL rune = {{.EndSymbol}} - -/* The rule types inferred from the grammar are below. */ -type Rule uint8 - -const ( - RuleUnknown Rule = iota - {{range .RuleNames}}Rule{{.String}} - {{end}} - RulePre_ - Rule_In_ - Rule_Suf -) - -var Rul3s = [...]string { - "Unknown", - {{range .RuleNames}}"{{.String}}", - {{end}} - "Pre_", - "_In_", - "_Suf", -} - -type TokenTree interface { - Print() - PrintSyntax() - PrintSyntaxTree(buffer string) - Add(rule Rule, begin, end, next, depth int) - Expand(index int) TokenTree - Tokens() <-chan token32 - Error() []token32 - trim(length int) -} - -{{range .Sizes}} - -/* ${@} bit structure for abstract syntax tree */ -type token{{.}} struct { - Rule - begin, end, next int{{.}} -} - -func (t *token{{.}}) isZero() bool { - return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 -} - -func (t *token{{.}}) isParentOf(u token{{.}}) bool { - return t.begin <= u.begin && t.end >= u.end && t.next > u.next -} - -func (t *token{{.}}) GetToken32() token32 { - return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} -} - -func (t *token{{.}}) String() string { - return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) -} - -type tokens{{.}} struct { - tree []token{{.}} - ordered [][]token{{.}} -} - -func (t *tokens{{.}}) trim(length int) { - t.tree = t.tree[0:length] -} - -func (t *tokens{{.}}) Print() { - for _, token := range t.tree { - fmt.Println(token.String()) - } -} - -func (t *tokens{{.}}) Order() [][]token{{.}} { - if t.ordered != nil { - return t.ordered - } - - depths := make([]int{{.}}, 1, math.MaxInt16) - for i, token := range t.tree { - if token.Rule == RuleUnknown { - t.tree = t.tree[:i] - break - } - depth := int(token.next) - if length := len(depths); depth >= length { - depths = depths[:depth + 1] - } - depths[depth]++ - } - depths = append(depths, 0) - - ordered, pool := make([][]token{{.}}, len(depths)), make([]token{{.}}, len(t.tree) + len(depths)) - for i, depth := range depths { - depth++ - ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 - } - - for i, token := range t.tree { - depth := token.next - token.next = int{{.}}(i) - ordered[depth][depths[depth]] = token - depths[depth]++ - } - t.ordered = ordered - return ordered -} - -type State{{.}} struct { - token{{.}} - depths []int{{.}} - leaf bool -} - -func (t *tokens{{.}}) PreOrder() (<-chan State{{.}}, [][]token{{.}}) { - s, ordered := make(chan State{{.}}, 6), t.Order() - go func() { - var states [8]State{{.}} - for i, _ := range states { - states[i].depths = make([]int{{.}}, len(ordered)) - } - depths, state, depth := make([]int{{.}}, len(ordered)), 0, 1 - write := func(t token{{.}}, leaf bool) { - S := states[state] - state, S.Rule, S.begin, S.end, S.next, S.leaf = (state + 1) % 8, t.Rule, t.begin, t.end, int{{.}}(depth), leaf - copy(S.depths, depths) - s <- S - } - - states[state].token{{.}} = ordered[0][0] - depths[0]++ - state++ - a, b := ordered[depth - 1][depths[depth - 1] - 1], ordered[depth][depths[depth]] - depthFirstSearch: for { - for { - if i := depths[depth]; i > 0 { - if c, j := ordered[depth][i - 1], depths[depth - 1]; a.isParentOf(c) && - (j < 2 || !ordered[depth - 1][j - 2].isParentOf(c)) { - if c.end != b.begin { - write(token{{.}} {Rule: Rule_In_, begin: c.end, end: b.begin}, true) - } - break - } - } - - if a.begin < b.begin { - write(token{{.}} {Rule: RulePre_, begin: a.begin, end: b.begin}, true) - } - break - } - - next := depth + 1 - if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { - write(b, false) - depths[depth]++ - depth, a, b = next, b, c - continue - } - - write(b, true) - depths[depth]++ - c, parent := ordered[depth][depths[depth]], true - for { - if c.Rule != RuleUnknown && a.isParentOf(c) { - b = c - continue depthFirstSearch - } else if parent && b.end != a.end { - write(token{{.}} {Rule: Rule_Suf, begin: b.end, end: a.end}, true) - } - - depth-- - if depth > 0 { - a, b, c = ordered[depth - 1][depths[depth - 1] - 1], a, ordered[depth][depths[depth]] - parent = a.isParentOf(b) - continue - } - - break depthFirstSearch - } - } - - close(s) - }() - return s, ordered -} - -func (t *tokens{{.}}) PrintSyntax() { - tokens, ordered := t.PreOrder() - max := -1 - for token := range tokens { - if !token.leaf { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i] - 1].Rule]) - } - fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) - } else if token.begin == token.end { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i] - 1].Rule]) - } - fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) - } else { - for c, end := token.begin, token.end; c < end; c++ { - if i := int(c); max + 1 < i { - for j := max; j < i; j++ { - fmt.Printf("skip %v %v\n", j, token.String()) - } - max = i - } else if i := int(c); i <= max { - for j := i; j <= max; j++ { - fmt.Printf("dupe %v %v\n", j, token.String()) - } - } else { - max = int(c) - } - fmt.Printf("%v", c) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i] - 1].Rule]) - } - fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) - } - fmt.Printf("\n") - } - } -} - -func (t *tokens{{.}}) PrintSyntaxTree(buffer string) { - tokens, _ := t.PreOrder() - for token := range tokens { - for c := 0; c < int(token.next); c++ { - fmt.Printf(" ") - } - fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) - } -} - -func (t *tokens{{.}}) Add(rule Rule, begin, end, depth, index int) { - t.tree[index] = token{{.}}{Rule: rule, begin: int{{.}}(begin), end: int{{.}}(end), next: int{{.}}(depth)} -} - -func (t *tokens{{.}}) Tokens() <-chan token32 { - s := make(chan token32, 16) - go func() { - for _, v := range t.tree { - s <- v.GetToken32() - } - close(s) - }() - return s -} - -func (t *tokens{{.}}) Error() []token32 { - ordered := t.Order() - length := len(ordered) - tokens, length := make([]token32, length), length - 1 - for i, _ := range tokens { - o := ordered[length - i] - if len(o) > 1 { - tokens[i] = o[len(o) - 2].GetToken32() - } - } - return tokens -} -{{end}} - -func (t *tokens16) Expand(index int) TokenTree { - tree := t.tree - if index >= len(tree) { - expanded := make([]token32, 2 * len(tree)) - for i, v := range tree { - expanded[i] = v.GetToken32() - } - return &tokens32{tree: expanded} - } - return nil -} - -func (t *tokens32) Expand(index int) TokenTree { - tree := t.tree - if index >= len(tree) { - expanded := make([]token32, 2 * len(tree)) - copy(expanded, tree) - t.tree = expanded - } - return nil -} - -type {{.StructName}} struct { - {{.StructVariables}} - Buffer string - buffer []rune - rules [{{.RulesCount}}]func() bool - Parse func(rule ...int) error - Reset func() - TokenTree -} - -type textPosition struct { - line, symbol int -} - -type textPositionMap map[int] textPosition - -func translatePositions(buffer string, positions []int) textPositionMap { - length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 - sort.Ints(positions) - - search: for i, c := range buffer[0:] { - if c == '\n' {line, symbol = line + 1, 0} else {symbol++} - if i == positions[j] { - translations[positions[j]] = textPosition{line, symbol} - for j++; j < length; j++ {if i != positions[j] {continue search}} - break search - } - } - - return translations -} - -type parseError struct { - p *{{.StructName}} -} - -func (e *parseError) Error() string { - tokens, error := e.p.TokenTree.Error(), "\n" - positions, p := make([]int, 2 * len(tokens)), 0 - for _, token := range tokens { - positions[p], p = int(token.begin), p + 1 - positions[p], p = int(token.end), p + 1 - } - translations := translatePositions(e.p.Buffer, positions) - for _, token := range tokens { - begin, end := int(token.begin), int(token.end) - error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", - Rul3s[token.Rule], - translations[begin].line, translations[begin].symbol, - translations[end].line, translations[end].symbol, - /*strconv.Quote(*/e.p.Buffer[begin:end]/*)*/) - } - - return error -} - -func (p *{{.StructName}}) PrintSyntaxTree() { - p.TokenTree.PrintSyntaxTree(p.Buffer) -} - -func (p *{{.StructName}}) Highlighter() { - p.TokenTree.PrintSyntax() -} - -{{if .HasActions}} -func (p *{{.StructName}}) Execute() { - buffer, begin, end := p.Buffer, 0, 0 - for token := range p.TokenTree.Tokens() { - switch (token.Rule) { - case RulePegText: - begin, end = int(token.begin), int(token.end) - {{range .Actions}}case RuleAction{{.GetId}}: - {{.String}} - {{end}} - } - } -} -{{end}} - -func (p *{{.StructName}}) Init() { - p.buffer = []rune(p.Buffer) - if len(p.buffer) == 0 || p.buffer[len(p.buffer) - 1] != END_SYMBOL { - p.buffer = append(p.buffer, END_SYMBOL) - } - - var tree TokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} - position, depth, tokenIndex, buffer, rules := 0, 0, 0, p.buffer, p.rules - - p.Parse = func(rule ...int) error { - r := 1 - if len(rule) > 0 { - r = rule[0] - } - matches := p.rules[r]() - p.TokenTree = tree - if matches { - p.TokenTree.trim(tokenIndex) - return nil - } - return &parseError{p} - } - - p.Reset = func() { - position, tokenIndex, depth = 0, 0, 0 - } - - add := func(rule Rule, begin int) { - if t := tree.Expand(tokenIndex); t != nil { - tree = t - } - tree.Add(rule, begin, position, depth, tokenIndex) - tokenIndex++ - } - - {{if .HasDot}} - matchDot := func() bool { - if buffer[position] != END_SYMBOL { - position++ - return true - } - return false - } - {{end}} - - {{if .HasCharacter}} - /*matchChar := func(c byte) bool { - if buffer[position] == c { - position++ - return true - } - return false - }*/ - {{end}} - - {{if .HasString}} - matchString := func(s string) bool { - i := position - for _, c := range s { - if buffer[i] != c { - return false - } - i++ - } - position = i - return true - } - {{end}} - - {{if .HasRange}} - /*matchRange := func(lower byte, upper byte) bool { - if c := buffer[position]; c >= lower && c <= upper { - position++ - return true - } - return false - }*/ - {{end}} - - rules = [...]func() bool { - nil,` - -type Type uint8 - -const ( - TypeUnknown Type = iota - TypeRule - TypeName - TypeDot - TypeCharacter - TypeRange - TypeString - TypePredicate - TypeCommit - TypeAction - TypePackage - TypeState - TypeAlternate - TypeUnorderedAlternate - TypeSequence - TypePeekFor - TypePeekNot - TypeQuery - TypeStar - TypePlus - TypePeg - TypePush - TypeImplicitPush - TypeNil - TypeLast -) - -var TypeMap = [...]string{ - "TypeUnknown", - "TypeRule", - "TypeName", - "TypeDot", - "TypeCharacter", - "TypeRange", - "TypeString", - "TypePredicate", - "TypeCommit", - "TypeAction", - "TypePackage", - "TypeState", - "TypeAlternate", - "TypeUnorderedAlternate", - "TypeSequence", - "TypePeekFor", - "TypePeekNot", - "TypeQuery", - "TypeStar", - "TypePlus", - "TypePeg", - "TypePush", - "TypeImplicitPush", - "TypeNil", - "TypeLast"} - -func (t Type) GetType() Type { - return t -} - -type Node interface { - fmt.Stringer - debug() - - Escaped() string - SetString(s string) - - GetType() Type - SetType(t Type) - - GetId() int - SetId(id int) - - Init() - Front() *node - Next() *node - PushFront(value *node) - PopFront() *node - PushBack(value *node) - Len() int - Copy() *node - Slice() []*node -} - -type node struct { - Type - string - id int - - front *node - back *node - length int - - /* use hash table here instead of Copy? */ - next *node -} - -func (n *node) String() string { - return n.string -} - -func (n *node) debug() { - if len(n.string) == 1 { - fmt.Printf("%v %v '%v' %d\n", n.id, TypeMap[n.Type], n.string, n.string[0]) - } else { - fmt.Printf("%v %v '%v'\n", n.id, TypeMap[n.Type], n.string) - } -} - -func (n *node) Escaped() string { - return escape(n.string) -} - -func (n *node) SetString(s string) { - n.string = s -} - -func (n *node) SetType(t Type) { - n.Type = t -} - -func (n *node) GetId() int { - return n.id -} - -func (n *node) SetId(id int) { - n.id = id -} - -func (n *node) Init() { - n.front = nil - n.back = nil - n.length = 0 -} - -func (n *node) Front() *node { - return n.front -} - -func (n *node) Next() *node { - return n.next -} - -func (n *node) PushFront(value *node) { - if n.back == nil { - n.back = value - } else { - value.next = n.front - } - n.front = value - n.length++ -} - -func (n *node) PopFront() *node { - front := n.front - - switch true { - case front == nil: - panic("tree is empty") - case front == n.back: - n.front, n.back = nil, nil - default: - n.front, front.next = front.next, nil - } - - n.length-- - return front -} - -func (n *node) PushBack(value *node) { - if n.front == nil { - n.front = value - } else { - n.back.next = value - } - n.back = value - n.length++ -} - -func (n *node) Len() (c int) { - return n.length -} - -func (n *node) Copy() *node { - return &node{Type: n.Type, string: n.string, id: n.id, front: n.front, back: n.back, length: n.length} -} - -func (n *node) Slice() []*node { - s := make([]*node, n.length) - for element, i := n.Front(), 0; element != nil; element, i = element.Next(), i+1 { - s[i] = element - } - return s -} - -/* A tree data structure into which a PEG can be parsed. */ -type Tree struct { - Rules map[string]Node - rulesCount map[string]uint - node - inline, _switch bool - - RuleNames []Node - Sizes [2]int - PackageName string - EndSymbol rune - StructName string - StructVariables string - RulesCount int - Bits int - HasActions bool - Actions []Node - HasCommit bool - HasDot bool - HasCharacter bool - HasString bool - HasRange bool -} - -func New(inline, _switch bool) *Tree { - return &Tree{Rules: make(map[string]Node), - Sizes: [2]int{16, 32}, - rulesCount: make(map[string]uint), - inline: inline, - _switch: _switch} -} - -func (t *Tree) AddRule(name string) { - t.PushFront(&node{Type: TypeRule, string: name, id: t.RulesCount}) - t.RulesCount++ -} - -func (t *Tree) AddExpression() { - expression := t.PopFront() - rule := t.PopFront() - rule.PushBack(expression) - t.PushBack(rule) -} - -func (t *Tree) AddName(text string) { - t.PushFront(&node{Type: TypeName, string: text}) -} - -func (t *Tree) AddDot() { t.PushFront(&node{Type: TypeDot, string: "."}) } -func (t *Tree) AddCharacter(text string) { - t.PushFront(&node{Type: TypeCharacter, string: text}) -} -func (t *Tree) AddDoubleCharacter(text string) { - t.PushFront(&node{Type: TypeCharacter, string: strings.ToLower(text)}) - t.PushFront(&node{Type: TypeCharacter, string: strings.ToUpper(text)}) - t.AddAlternate() -} -func (t *Tree) AddOctalCharacter(text string) { - octal, _ := strconv.ParseInt(text, 8, 8) - t.PushFront(&node{Type: TypeCharacter, string: string(octal)}) -} -func (t *Tree) AddPredicate(text string) { t.PushFront(&node{Type: TypePredicate, string: text}) } -func (t *Tree) AddNil() { t.PushFront(&node{Type: TypeNil, string: ""}) } -func (t *Tree) AddAction(text string) { t.PushFront(&node{Type: TypeAction, string: text}) } -func (t *Tree) AddPackage(text string) { t.PushBack(&node{Type: TypePackage, string: text}) } -func (t *Tree) AddState(text string) { - peg := t.PopFront() - peg.PushBack(&node{Type: TypeState, string: text}) - t.PushBack(peg) -} - -func (t *Tree) addList(listType Type) { - a := t.PopFront() - b := t.PopFront() - var l *node - if b.GetType() == listType { - l = b - } else { - l = &node{Type: listType} - l.PushBack(b) - } - l.PushBack(a) - t.PushFront(l) -} -func (t *Tree) AddAlternate() { t.addList(TypeAlternate) } -func (t *Tree) AddSequence() { t.addList(TypeSequence) } -func (t *Tree) AddRange() { t.addList(TypeRange) } -func (t *Tree) AddDoubleRange() { - a := t.PopFront() - b := t.PopFront() - - t.AddCharacter(strings.ToLower(b.String())) - t.AddCharacter(strings.ToLower(a.String())) - t.addList(TypeRange) - - t.AddCharacter(strings.ToUpper(b.String())) - t.AddCharacter(strings.ToUpper(a.String())) - t.addList(TypeRange) - - t.AddAlternate() -} - -func (t *Tree) addFix(fixType Type) { - n := &node{Type: fixType} - n.PushBack(t.PopFront()) - t.PushFront(n) -} -func (t *Tree) AddPeekFor() { t.addFix(TypePeekFor) } -func (t *Tree) AddPeekNot() { t.addFix(TypePeekNot) } -func (t *Tree) AddQuery() { t.addFix(TypeQuery) } -func (t *Tree) AddStar() { t.addFix(TypeStar) } -func (t *Tree) AddPlus() { t.addFix(TypePlus) } -func (t *Tree) AddPush() { t.addFix(TypePush) } - -func (t *Tree) AddPeg(text string) { t.PushFront(&node{Type: TypePeg, string: text}) } - -func join(tasks []func()) { - length := len(tasks) - done := make(chan int, length) - for _, task := range tasks { - go func(task func()) { task(); done <- 1 }(task) - } - for d := <-done; d < length; d += <-done { - } -} - -func escape(c string) string { - switch c { - case "'": - return "\\'" - case "\"": - return "\"" - default: - c = strconv.Quote(c) - return c[1 : len(c)-1] - } - return "" -} - -func (t *Tree) Compile(file string) { - t.EndSymbol = '\u0004' - t.RulesCount++ - - counts := [TypeLast]uint{} - { - var rule *node - var link func(node Node) - link = func(n Node) { - nodeType := n.GetType() - id := counts[nodeType] - counts[nodeType]++ - switch nodeType { - case TypeAction: - n.SetId(int(id)) - copy, name := n.Copy(), fmt.Sprintf("Action%v", id) - t.Actions = append(t.Actions, copy) - n.Init() - n.SetType(TypeName) - n.SetString(name) - n.SetId(t.RulesCount) - - emptyRule := &node{Type: TypeRule, string: name, id: t.RulesCount} - implicitPush := &node{Type: TypeImplicitPush} - emptyRule.PushBack(implicitPush) - implicitPush.PushBack(copy) - implicitPush.PushBack(emptyRule.Copy()) - t.PushBack(emptyRule) - t.RulesCount++ - - t.Rules[name] = emptyRule - t.RuleNames = append(t.RuleNames, emptyRule) - case TypeName: - name := n.String() - if _, ok := t.Rules[name]; !ok { - emptyRule := &node{Type: TypeRule, string: name, id: t.RulesCount} - implicitPush := &node{Type: TypeImplicitPush} - emptyRule.PushBack(implicitPush) - implicitPush.PushBack(&node{Type: TypeNil, string: ""}) - implicitPush.PushBack(emptyRule.Copy()) - t.PushBack(emptyRule) - t.RulesCount++ - - t.Rules[name] = emptyRule - t.RuleNames = append(t.RuleNames, emptyRule) - } - case TypePush: - copy, name := rule.Copy(), "PegText" - copy.SetString(name) - if _, ok := t.Rules[name]; !ok { - emptyRule := &node{Type: TypeRule, string: name, id: t.RulesCount} - emptyRule.PushBack(&node{Type: TypeNil, string: ""}) - t.PushBack(emptyRule) - t.RulesCount++ - - t.Rules[name] = emptyRule - t.RuleNames = append(t.RuleNames, emptyRule) - } - n.PushBack(copy) - fallthrough - case TypeImplicitPush: - link(n.Front()) - case TypeRule, TypeAlternate, TypeUnorderedAlternate, TypeSequence, - TypePeekFor, TypePeekNot, TypeQuery, TypeStar, TypePlus: - for _, node := range n.Slice() { - link(node) - } - } - } - /* first pass */ - for _, node := range t.Slice() { - switch node.GetType() { - case TypePackage: - t.PackageName = node.String() - case TypePeg: - t.StructName = node.String() - t.StructVariables = node.Front().String() - case TypeRule: - if _, ok := t.Rules[node.String()]; !ok { - expression := node.Front() - copy := expression.Copy() - expression.Init() - expression.SetType(TypeImplicitPush) - expression.PushBack(copy) - expression.PushBack(node.Copy()) - - t.Rules[node.String()] = node - t.RuleNames = append(t.RuleNames, node) - } - } - } - /* second pass */ - for _, node := range t.Slice() { - if node.GetType() == TypeRule { - rule = node - link(node) - } - } - } - - join([]func(){ - func() { - var countRules func(node Node) - ruleReached := make([]bool, t.RulesCount) - countRules = func(node Node) { - switch node.GetType() { - case TypeRule: - name, id := node.String(), node.GetId() - if count, ok := t.rulesCount[name]; ok { - t.rulesCount[name] = count + 1 - } else { - t.rulesCount[name] = 1 - } - if ruleReached[id] { - return - } - ruleReached[id] = true - countRules(node.Front()) - case TypeName: - countRules(t.Rules[node.String()]) - case TypeImplicitPush, TypePush: - countRules(node.Front()) - case TypeAlternate, TypeUnorderedAlternate, TypeSequence, - TypePeekFor, TypePeekNot, TypeQuery, TypeStar, TypePlus: - for _, element := range node.Slice() { - countRules(element) - } - } - } - for _, node := range t.Slice() { - if node.GetType() == TypeRule { - countRules(node) - break - } - } - }, - func() { - var checkRecursion func(node Node) bool - ruleReached := make([]bool, t.RulesCount) - checkRecursion = func(node Node) bool { - switch node.GetType() { - case TypeRule: - id := node.GetId() - if ruleReached[id] { - fmt.Fprintf(os.Stderr, "possible infinite left recursion in rule '%v'\n", node) - return false - } - ruleReached[id] = true - consumes := checkRecursion(node.Front()) - ruleReached[id] = false - return consumes - case TypeAlternate: - for _, element := range node.Slice() { - if !checkRecursion(element) { - return false - } - } - return true - case TypeSequence: - for _, element := range node.Slice() { - if checkRecursion(element) { - return true - } - } - case TypeName: - return checkRecursion(t.Rules[node.String()]) - case TypePlus, TypePush, TypeImplicitPush: - return checkRecursion(node.Front()) - case TypeCharacter, TypeString: - return len(node.String()) > 0 - case TypeDot, TypeRange: - return true - } - return false - } - for _, node := range t.Slice() { - if node.GetType() == TypeRule { - checkRecursion(node) - } - } - }}) - - if t._switch { - var optimizeAlternates func(node Node) (consumes bool, s *set) - cache, firstPass := make([]struct { - reached, consumes bool - s *set - }, t.RulesCount), true - optimizeAlternates = func(n Node) (consumes bool, s *set) { - /*n.debug()*/ - switch n.GetType() { - case TypeRule: - cache := &cache[n.GetId()] - if cache.reached { - consumes, s = cache.consumes, cache.s - return - } - - cache.reached = true - consumes, s = optimizeAlternates(n.Front()) - cache.consumes, cache.s = consumes, s - case TypeName: - consumes, s = optimizeAlternates(t.Rules[n.String()]) - case TypeDot: - consumes, s = true, &set{} - /* TypeDot set doesn't include the EndSymbol */ - s.add(byte(t.EndSymbol)) - s.complement() - case TypeString, TypeCharacter: - consumes, s = true, &set{} - s.add(n.String()[0]) - case TypeRange: - consumes, s = true, &set{} - element := n.Front() - lower := element.String()[0] - element = element.Next() - upper := element.String()[0] - for c := lower; c <= upper; c++ { - s.add(c) - } - case TypeAlternate: - consumes, s = true, &set{} - mconsumes, properties, c := - consumes, make([]struct { - intersects bool - s *set - }, n.Len()), 0 - for _, element := range n.Slice() { - mconsumes, properties[c].s = optimizeAlternates(element) - consumes = consumes && mconsumes - if properties[c].s == nil { - /* recursive definition, so set has yet to be completed */ - } else { - s.union(properties[c].s) - } - c++ - } - - if firstPass { - break - } - - intersections := 2 - compare: - for ai, a := range properties[0 : len(properties)-1] { - for _, b := range properties[ai+1:] { - if a.s.intersects(b.s) { - intersections++ - properties[ai].intersects = true - continue compare - } - } - } - if intersections >= len(properties) { - break - } - - c, unordered, ordered, max := - 0, &node{Type: TypeUnorderedAlternate}, &node{Type: TypeAlternate}, 0 - for _, element := range n.Slice() { - if properties[c].intersects { - ordered.PushBack(element.Copy()) - } else { - class := &node{Type: TypeUnorderedAlternate} - for d := 0; d < 256; d++ { - if properties[c].s.has(uint8(d)) { - class.PushBack(&node{Type: TypeCharacter, string: string(d)}) - } - } - - sequence, predicate, length := - &node{Type: TypeSequence}, &node{Type: TypePeekFor}, properties[c].s.len() - if length == 0 { - class.PushBack(&node{Type: TypeNil, string: ""}) - } - predicate.PushBack(class) - sequence.PushBack(predicate) - sequence.PushBack(element.Copy()) - - if element.GetType() == TypeNil { - unordered.PushBack(sequence) - } else if length > max { - unordered.PushBack(sequence) - max = length - } else { - unordered.PushFront(sequence) - } - } - c++ - } - n.Init() - if ordered.Front() == nil { - n.SetType(TypeUnorderedAlternate) - for _, element := range unordered.Slice() { - n.PushBack(element.Copy()) - } - } else { - for _, element := range ordered.Slice() { - n.PushBack(element.Copy()) - } - n.PushBack(unordered) - } - case TypeSequence: - classes, elements := - make([]struct { - s *set - }, n.Len()), n.Slice() - - for c, element := range elements { - consumes, classes[c].s = optimizeAlternates(element) - if consumes { - elements, classes = elements[c+1:], classes[:c+1] - break - } - } - - s = &set{} - for c := len(classes) - 1; c >= 0; c-- { - if classes[c].s != nil { - s.union(classes[c].s) - } - } - - for _, element := range elements { - optimizeAlternates(element) - } - case TypePeekNot, TypePeekFor: - optimizeAlternates(n.Front()) - s = &set{} - case TypeQuery, TypeStar: - _, s = optimizeAlternates(n.Front()) - case TypePlus, TypePush, TypeImplicitPush: - consumes, s = optimizeAlternates(n.Front()) - case TypeAction, TypeNil: - s = &set{} - } - return - } - for _, element := range t.Slice() { - if element.GetType() == TypeRule { - optimizeAlternates(element) - break - } - } - - for i, _ := range cache { - cache[i].reached = false - } - firstPass = false - for _, element := range t.Slice() { - if element.GetType() == TypeRule { - optimizeAlternates(element) - break - } - } - } - - out, error := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) - if error != nil { - fmt.Printf("%v: %v\n", file, error) - return - } - defer out.Close() - - var buffer bytes.Buffer - defer func() { - fileSet := token.NewFileSet() - code, error := parser.ParseFile(fileSet, file, &buffer, parser.ParseComments) - if error != nil { - buffer.WriteTo(out) - fmt.Printf("%v: %v\n", file, error) - return - } - formatter := printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8} - error = formatter.Fprint(out, fileSet, code) - if error != nil { - buffer.WriteTo(out) - fmt.Printf("%v: %v\n", file, error) - return - } - - }() - - print := func(format string, a ...interface{}) { fmt.Fprintf(&buffer, format, a...) } - printSave := func(n uint) { print("\n position%d, tokenIndex%d, depth%d := position, tokenIndex, depth", n, n, n) } - printRestore := func(n uint) { print(" position, tokenIndex, depth = position%d, tokenIndex%d, depth%d", n, n, n) } - printTemplate := func(s string) { - if error := template.Must(template.New("peg").Parse(s)).Execute(&buffer, t); error != nil { - panic(error) - } - } - - t.HasActions = counts[TypeAction] > 0 - t.HasCommit = counts[TypeCommit] > 0 - t.HasDot = counts[TypeDot] > 0 - t.HasCharacter = counts[TypeCharacter] > 0 - t.HasString = counts[TypeString] > 0 - t.HasRange = counts[TypeRange] > 0 - - var printRule func(n Node) - var compile func(expression Node, ko uint) - var label uint - labels := make(map[uint]bool) - printBegin := func() { print("\n {") } - printEnd := func() { print("\n }") } - printLabel := func(n uint) { - print("\n") - if labels[n] { - print(" l%d:\t", n) - } - } - printJump := func(n uint) { - print("\n goto l%d", n) - labels[n] = true - } - printRule = func(n Node) { - switch n.GetType() { - case TypeRule: - print("%v <- ", n) - printRule(n.Front()) - case TypeDot: - print(".") - case TypeName: - print("%v", n) - case TypeCharacter: - print("'%v'", escape(n.String())) - case TypeString: - s := escape(n.String()) - print("'%v'", s[1:len(s)-1]) - case TypeRange: - element := n.Front() - lower := element - element = element.Next() - upper := element - print("[%v-%v]", lower, upper) - case TypePredicate: - print("&{%v}", n) - case TypeAction: - print("{%v}", n) - case TypeCommit: - print("commit") - case TypeAlternate: - print("(") - elements := n.Slice() - printRule(elements[0]) - for _, element := range elements[1:] { - print(" / ") - printRule(element) - } - print(")") - case TypeUnorderedAlternate: - print("(") - elements := n.Slice() - printRule(elements[0]) - for _, element := range elements[1:] { - print(" | ") - printRule(element) - } - print(")") - case TypeSequence: - print("(") - elements := n.Slice() - printRule(elements[0]) - for _, element := range elements[1:] { - print(" ") - printRule(element) - } - print(")") - case TypePeekFor: - print("&") - printRule(n.Front()) - case TypePeekNot: - print("!") - printRule(n.Front()) - case TypeQuery: - printRule(n.Front()) - print("?") - case TypeStar: - printRule(n.Front()) - print("*") - case TypePlus: - printRule(n.Front()) - print("+") - case TypePush, TypeImplicitPush: - print("<") - printRule(n.Front()) - print(">") - case TypeNil: - default: - fmt.Fprintf(os.Stderr, "illegal node type: %v\n", n.GetType()) - } - } - compile = func(n Node, ko uint) { - switch n.GetType() { - case TypeRule: - fmt.Fprintf(os.Stderr, "internal error #1 (%v)\n", n) - case TypeDot: - print("\n if !matchDot() {") - /*print("\n if buffer[position] == END_SYMBOL {")*/ - printJump(ko) - /*print("}\nposition++")*/ - print("}") - case TypeName: - name := n.String() - rule := t.Rules[name] - if t.inline && t.rulesCount[name] == 1 { - compile(rule.Front(), ko) - return - } - print("\n if !rules[Rule%v]() {", name /*rule.GetId()*/) - printJump(ko) - print("}") - case TypeRange: - element := n.Front() - lower := element - element = element.Next() - upper := element - /*print("\n if !matchRange('%v', '%v') {", escape(lower.String()), escape(upper.String()))*/ - print("\n if c := buffer[position]; c < rune('%v') || c > rune('%v') {", escape(lower.String()), escape(upper.String())) - printJump(ko) - print("}\nposition++") - case TypeCharacter: - /*print("\n if !matchChar('%v') {", escape(n.String()))*/ - print("\n if buffer[position] != rune('%v') {", escape(n.String())) - printJump(ko) - print("}\nposition++") - case TypeString: - print("\n if !matchString(%v) {", strconv.Quote(n.String())) - printJump(ko) - print("}") - case TypePredicate: - print("\n if !(%v) {", n) - printJump(ko) - print("}") - case TypeAction: - case TypeCommit: - case TypePush: - fallthrough - case TypeImplicitPush: - ok, element := label, n.Front() - label++ - nodeType, rule := element.GetType(), element.Next() - printBegin() - if nodeType == TypeAction { - print("\nadd(Rule%v, position)", rule) - } else { - print("\nposition%d := position", ok) - print("\ndepth++") - compile(element, ko) - print("\ndepth--") - print("\nadd(Rule%v, position%d)", rule, ok) - } - printEnd() - case TypeAlternate: - ok := label - label++ - printBegin() - elements := n.Slice() - printSave(ok) - for _, element := range elements[:len(elements)-1] { - next := label - label++ - compile(element, next) - printJump(ok) - printLabel(next) - printRestore(ok) - } - compile(elements[len(elements)-1], ko) - printEnd() - printLabel(ok) - case TypeUnorderedAlternate: - done, ok := ko, label - label++ - printBegin() - print("\n switch buffer[position] {") - elements := n.Slice() - elements, last := elements[:len(elements)-1], elements[len(elements)-1].Front().Next() - for _, element := range elements { - sequence := element.Front() - class := sequence.Front() - sequence = sequence.Next() - print("\n case") - comma := false - for _, character := range class.Slice() { - if comma { - print(",") - } else { - comma = true - } - print(" '%s'", escape(character.String())) - } - print(":") - compile(sequence, done) - print("\nbreak") - } - print("\n default:") - compile(last, done) - print("\nbreak") - print("\n }") - printEnd() - printLabel(ok) - case TypeSequence: - for _, element := range n.Slice() { - compile(element, ko) - } - case TypePeekFor: - ok := label - label++ - printBegin() - printSave(ok) - compile(n.Front(), ko) - printRestore(ok) - printEnd() - case TypePeekNot: - ok := label - label++ - printBegin() - printSave(ok) - compile(n.Front(), ok) - printJump(ko) - printLabel(ok) - printRestore(ok) - printEnd() - case TypeQuery: - qko := label - label++ - qok := label - label++ - printBegin() - printSave(qko) - compile(n.Front(), qko) - printJump(qok) - printLabel(qko) - printRestore(qko) - printEnd() - printLabel(qok) - case TypeStar: - again := label - label++ - out := label - label++ - printLabel(again) - printBegin() - printSave(out) - compile(n.Front(), out) - printJump(again) - printLabel(out) - printRestore(out) - printEnd() - case TypePlus: - again := label - label++ - out := label - label++ - compile(n.Front(), ko) - printLabel(again) - printBegin() - printSave(out) - compile(n.Front(), out) - printJump(again) - printLabel(out) - printRestore(out) - printEnd() - case TypeNil: - default: - fmt.Fprintf(os.Stderr, "illegal node type: %v\n", n.GetType()) - } - } - - /* lets figure out which jump labels are going to be used with this dry compile */ - printTemp, print := print, func(format string, a ...interface{}) {} - for _, element := range t.Slice() { - if element.GetType() != TypeRule { - continue - } - expression := element.Front() - if expression.GetType() == TypeNil { - continue - } - ko := label - label++ - if count, ok := t.rulesCount[element.String()]; !ok { - continue - } else if t.inline && count == 1 && ko != 0 { - continue - } - compile(expression, ko) - } - print, label = printTemp, 0 - - /* now for the real compile pass */ - printTemplate(PEG_HEADER_TEMPLATE) - for _, element := range t.Slice() { - if element.GetType() != TypeRule { - continue - } - expression := element.Front() - if expression.GetType() == TypeNil { - fmt.Fprintf(os.Stderr, "rule '%v' used but not defined\n", element) - print("\n nil,") - continue - } - ko := label - label++ - print("\n /* %v ", element.GetId()) - printRule(element) - print(" */") - if count, ok := t.rulesCount[element.String()]; !ok { - fmt.Fprintf(os.Stderr, "rule '%v' defined but not used\n", element) - print("\n nil,") - continue - } else if t.inline && count == 1 && ko != 0 { - print("\n nil,") - continue - } - print("\n func() bool {") - if labels[ko] { - printSave(ko) - } - compile(expression, ko) - print("\n return true") - if labels[ko] { - printLabel(ko) - printRestore(ko) - print("\n return false") - } - print("\n },") - } - print("\n }\n p.rules = rules") - print("\n}\n") -} diff --git a/peg.peg b/peg.peg deleted file mode 100644 index 4ded014..0000000 --- a/peg.peg +++ /dev/null @@ -1,111 +0,0 @@ -# PE Grammar for PE Grammars -# -# Adapted from [1] by Ian Piumarta . -# -# 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 - -# parser declaration - -type Peg Peg { - *Tree -} - -# Hierarchical syntax -Grammar <- Spacing 'package' Spacing Identifier { p.AddPackage(buffer[begin:end]) } - 'type' Spacing Identifier { p.AddPeg(buffer[begin:end]) } - 'Peg' Spacing Action { p.AddState(buffer[begin:end]) } - Definition+ EndOfFile -Definition <- Identifier { p.AddRule(buffer[begin:end]) } - 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(buffer[begin:end]) } - / 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(buffer[begin:end]) } - / Open Expression Close - / Literal - / Class - / Dot { p.AddDot() } - / Action { p.AddAction(buffer[begin:end]) } - / 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(buffer[begin:end]) } -DoubleChar <- Escape - / <[a-zA-Z]> { p.AddDoubleCharacter(buffer[begin:end]) } - / !'\\' <.> { p.AddCharacter(buffer[begin:end]) } -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("-") } - / '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(buffer[begin:end]) } - / '\\' <[0-7][0-7]?> { p.AddOctalCharacter(buffer[begin:end]) } - / '\\\\' { p.AddCharacter("\\") } -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 -Begin <- '<' Spacing -End <- '>' Spacing diff --git a/src/bootstrap/leg/bootstrap.leg.go b/src/bootstrap/leg/bootstrap.leg.go new file mode 100644 index 0000000..77bacc5 --- /dev/null +++ b/src/bootstrap/leg/bootstrap.leg.go @@ -0,0 +1,3362 @@ +package main + +import ( + /*"bytes"*/ + "fmt" + "math" + "sort" + "strconv" +) + +const END_SYMBOL rune = 4 + +type YYSTYPE int + +/* The rule types inferred from the grammar are below. */ +type Rule uint8 + +const ( + RuleUnknown Rule = iota + RuleGrammar + RuleDeclaration + RuleTrailer + RuleDefinition + RuleExpression + RuleSequence + RulePrefix + RuleSuffix + RulePrimary + RuleIdentifier + RuleLiteral + RuleClass + RuleRanges + RuleDoubleRanges + RuleRange + RuleDoubleRange + RuleChar + RuleDoubleChar + RuleEscape + RuleAction + RuleBraces + RuleEqual + RuleColon + RuleBar + RuleAnd + RuleNot + RuleQuestion + RuleStar + RulePlus + RuleOpen + RuleClose + RuleDot + RuleRPERCENT + Rule_ + RuleComment + RuleSpace + RuleEndOfLine + RuleEndOfFile + RuleBegin + RuleEnd + RuleAction0 + RuleAction1 + RuleAction2 + RuleAction3 + RulePegText + RuleAction4 + RuleAction5 + RuleAction6 + RuleAction7 + RuleAction8 + RuleAction9 + RuleAction10 + RuleAction11 + RuleAction12 + RuleAction13 + RuleAction14 + RuleAction15 + RuleAction16 + RuleAction17 + RuleAction18 + RuleAction19 + RuleAction20 + RuleAction21 + RuleAction22 + RuleAction23 + RuleAction24 + RuleAction25 + RuleAction26 + RuleAction27 + RuleAction28 + RuleAction29 + RuleAction30 + RuleAction31 + RuleAction32 + RuleAction33 + RuleAction34 + RuleAction35 + RuleAction36 + RuleAction37 + RuleAction38 + RuleAction39 + RuleAction40 + RuleAction41 + RuleAction42 + RuleAction43 + RuleAction44 + RuleAction45 + RuleAction46 + RuleAction47 + RuleAction48 + RuleAction49 + RuleAction50 + + RuleActionPush + RuleActionPop + RulePre_ + Rule_In_ + Rule_Suf +) + +var Rul3s = [...]string{ + "Unknown", + "Grammar", + "Declaration", + "Trailer", + "Definition", + "Expression", + "Sequence", + "Prefix", + "Suffix", + "Primary", + "Identifier", + "Literal", + "Class", + "Ranges", + "DoubleRanges", + "Range", + "DoubleRange", + "Char", + "DoubleChar", + "Escape", + "Action", + "Braces", + "Equal", + "Colon", + "Bar", + "And", + "Not", + "Question", + "Star", + "Plus", + "Open", + "Close", + "Dot", + "RPERCENT", + "_", + "Comment", + "Space", + "EndOfLine", + "EndOfFile", + "Begin", + "End", + "Action0", + "Action1", + "Action2", + "Action3", + "PegText", + "Action4", + "Action5", + "Action6", + "Action7", + "Action8", + "Action9", + "Action10", + "Action11", + "Action12", + "Action13", + "Action14", + "Action15", + "Action16", + "Action17", + "Action18", + "Action19", + "Action20", + "Action21", + "Action22", + "Action23", + "Action24", + "Action25", + "Action26", + "Action27", + "Action28", + "Action29", + "Action30", + "Action31", + "Action32", + "Action33", + "Action34", + "Action35", + "Action36", + "Action37", + "Action38", + "Action39", + "Action40", + "Action41", + "Action42", + "Action43", + "Action44", + "Action45", + "Action46", + "Action47", + "Action48", + "Action49", + "Action50", + + "RuleActionPush", + "RuleActionPop", + "Pre_", + "_In_", + "_Suf", +} + +type TokenTree interface { + Print() + PrintSyntax() + PrintSyntaxTree(buffer string) + Add(rule Rule, begin, end, next, depth int) + Expand(index int) TokenTree + Tokens() <-chan token32 + Error() []token32 + trim(length int) +} + +/* ${@} bit structure for abstract syntax tree */ +type token16 struct { + Rule + begin, end, next int16 +} + +func (t *token16) isZero() bool { + return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 +} + +func (t *token16) isParentOf(u token16) bool { + return t.begin <= u.begin && t.end >= u.end && t.next > u.next +} + +func (t *token16) GetToken32() token32 { + return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} +} + +func (t *token16) String() string { + return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) +} + +type tokens16 struct { + tree []token16 + ordered [][]token16 +} + +func (t *tokens16) trim(length int) { + t.tree = t.tree[0:length] +} + +func (t *tokens16) Print() { + for _, token := range t.tree { + fmt.Println(token.String()) + } +} + +func (t *tokens16) Order() [][]token16 { + if t.ordered != nil { + return t.ordered + } + + depths := make([]int16, 1, math.MaxInt16) + for i, token := range t.tree { + if token.Rule == RuleUnknown { + t.tree = t.tree[:i] + break + } + depth := int(token.next) + if length := len(depths); depth >= length { + depths = depths[:depth+1] + } + depths[depth]++ + } + depths = append(depths, 0) + + ordered, pool := make([][]token16, len(depths)), make([]token16, len(t.tree)+len(depths)) + for i, depth := range depths { + depth++ + ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 + } + + for i, token := range t.tree { + depth := token.next + token.next = int16(i) + ordered[depth][depths[depth]] = token + depths[depth]++ + } + t.ordered = ordered + return ordered +} + +type State16 struct { + token16 + depths []int16 + leaf bool +} + +func (t *tokens16) PreOrder() (<-chan State16, [][]token16) { + s, ordered := make(chan State16, 6), t.Order() + go func() { + var states [8]State16 + for i, _ := range states { + states[i].depths = make([]int16, len(ordered)) + } + depths, state, depth := make([]int16, len(ordered)), 0, 1 + write := func(t token16, leaf bool) { + S := states[state] + state, S.Rule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.Rule, t.begin, t.end, int16(depth), leaf + copy(S.depths, depths) + s <- S + } + + states[state].token16 = ordered[0][0] + depths[0]++ + state++ + a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] + depthFirstSearch: + for { + for { + if i := depths[depth]; i > 0 { + if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && + (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { + if c.end != b.begin { + write(token16{Rule: Rule_In_, begin: c.end, end: b.begin}, true) + } + break + } + } + + if a.begin < b.begin { + write(token16{Rule: RulePre_, begin: a.begin, end: b.begin}, true) + } + break + } + + next := depth + 1 + if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { + write(b, false) + depths[depth]++ + depth, a, b = next, b, c + continue + } + + write(b, true) + depths[depth]++ + c, parent := ordered[depth][depths[depth]], true + for { + if c.Rule != RuleUnknown && a.isParentOf(c) { + b = c + continue depthFirstSearch + } else if parent && b.end != a.end { + write(token16{Rule: Rule_Suf, begin: b.end, end: a.end}, true) + } + + depth-- + if depth > 0 { + a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] + parent = a.isParentOf(b) + continue + } + + break depthFirstSearch + } + } + + close(s) + }() + return s, ordered +} + +func (t *tokens16) PrintSyntax() { + tokens, ordered := t.PreOrder() + max := -1 + for token := range tokens { + if !token.leaf { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) + } else if token.begin == token.end { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) + } else { + for c, end := token.begin, token.end; c < end; c++ { + if i := int(c); max+1 < i { + for j := max; j < i; j++ { + fmt.Printf("skip %v %v\n", j, token.String()) + } + max = i + } else if i := int(c); i <= max { + for j := i; j <= max; j++ { + fmt.Printf("dupe %v %v\n", j, token.String()) + } + } else { + max = int(c) + } + fmt.Printf("%v", c) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) + } + fmt.Printf("\n") + } + } +} + +func (t *tokens16) PrintSyntaxTree(buffer string) { + tokens, _ := t.PreOrder() + for token := range tokens { + for c := 0; c < int(token.next); c++ { + fmt.Printf(" ") + } + fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) + } +} + +func (t *tokens16) Add(rule Rule, begin, end, depth, index int) { + t.tree[index] = token16{Rule: rule, begin: int16(begin), end: int16(end), next: int16(depth)} +} + +func (t *tokens16) Tokens() <-chan token32 { + s := make(chan token32, 16) + go func() { + for _, v := range t.tree { + s <- v.GetToken32() + } + close(s) + }() + return s +} + +func (t *tokens16) Error() []token32 { + ordered := t.Order() + length := len(ordered) + tokens, length := make([]token32, length), length-1 + for i, _ := range tokens { + o := ordered[length-i] + if len(o) > 1 { + tokens[i] = o[len(o)-2].GetToken32() + } + } + return tokens +} + +/* ${@} bit structure for abstract syntax tree */ +type token32 struct { + Rule + begin, end, next int32 +} + +func (t *token32) isZero() bool { + return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 +} + +func (t *token32) isParentOf(u token32) bool { + return t.begin <= u.begin && t.end >= u.end && t.next > u.next +} + +func (t *token32) GetToken32() token32 { + return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} +} + +func (t *token32) String() string { + return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) +} + +type tokens32 struct { + tree []token32 + ordered [][]token32 +} + +func (t *tokens32) trim(length int) { + t.tree = t.tree[0:length] +} + +func (t *tokens32) Print() { + for _, token := range t.tree { + fmt.Println(token.String()) + } +} + +func (t *tokens32) Order() [][]token32 { + if t.ordered != nil { + return t.ordered + } + + depths := make([]int32, 1, math.MaxInt16) + for i, token := range t.tree { + if token.Rule == RuleUnknown { + t.tree = t.tree[:i] + break + } + depth := int(token.next) + if length := len(depths); depth >= length { + depths = depths[:depth+1] + } + depths[depth]++ + } + depths = append(depths, 0) + + ordered, pool := make([][]token32, len(depths)), make([]token32, len(t.tree)+len(depths)) + for i, depth := range depths { + depth++ + ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 + } + + for i, token := range t.tree { + depth := token.next + token.next = int32(i) + ordered[depth][depths[depth]] = token + depths[depth]++ + } + t.ordered = ordered + return ordered +} + +type State32 struct { + token32 + depths []int32 + leaf bool +} + +func (t *tokens32) PreOrder() (<-chan State32, [][]token32) { + s, ordered := make(chan State32, 6), t.Order() + go func() { + var states [8]State32 + for i, _ := range states { + states[i].depths = make([]int32, len(ordered)) + } + depths, state, depth := make([]int32, len(ordered)), 0, 1 + write := func(t token32, leaf bool) { + S := states[state] + state, S.Rule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.Rule, t.begin, t.end, int32(depth), leaf + copy(S.depths, depths) + s <- S + } + + states[state].token32 = ordered[0][0] + depths[0]++ + state++ + a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] + depthFirstSearch: + for { + for { + if i := depths[depth]; i > 0 { + if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && + (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { + if c.end != b.begin { + write(token32{Rule: Rule_In_, begin: c.end, end: b.begin}, true) + } + break + } + } + + if a.begin < b.begin { + write(token32{Rule: RulePre_, begin: a.begin, end: b.begin}, true) + } + break + } + + next := depth + 1 + if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { + write(b, false) + depths[depth]++ + depth, a, b = next, b, c + continue + } + + write(b, true) + depths[depth]++ + c, parent := ordered[depth][depths[depth]], true + for { + if c.Rule != RuleUnknown && a.isParentOf(c) { + b = c + continue depthFirstSearch + } else if parent && b.end != a.end { + write(token32{Rule: Rule_Suf, begin: b.end, end: a.end}, true) + } + + depth-- + if depth > 0 { + a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] + parent = a.isParentOf(b) + continue + } + + break depthFirstSearch + } + } + + close(s) + }() + return s, ordered +} + +func (t *tokens32) PrintSyntax() { + tokens, ordered := t.PreOrder() + max := -1 + for token := range tokens { + if !token.leaf { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) + } else if token.begin == token.end { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) + } else { + for c, end := token.begin, token.end; c < end; c++ { + if i := int(c); max+1 < i { + for j := max; j < i; j++ { + fmt.Printf("skip %v %v\n", j, token.String()) + } + max = i + } else if i := int(c); i <= max { + for j := i; j <= max; j++ { + fmt.Printf("dupe %v %v\n", j, token.String()) + } + } else { + max = int(c) + } + fmt.Printf("%v", c) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) + } + fmt.Printf("\n") + } + } +} + +func (t *tokens32) PrintSyntaxTree(buffer string) { + tokens, _ := t.PreOrder() + for token := range tokens { + for c := 0; c < int(token.next); c++ { + fmt.Printf(" ") + } + fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) + } +} + +func (t *tokens32) Add(rule Rule, begin, end, depth, index int) { + t.tree[index] = token32{Rule: rule, begin: int32(begin), end: int32(end), next: int32(depth)} +} + +func (t *tokens32) Tokens() <-chan token32 { + s := make(chan token32, 16) + go func() { + for _, v := range t.tree { + s <- v.GetToken32() + } + close(s) + }() + return s +} + +func (t *tokens32) Error() []token32 { + ordered := t.Order() + length := len(ordered) + tokens, length := make([]token32, length), length-1 + for i, _ := range tokens { + o := ordered[length-i] + if len(o) > 1 { + tokens[i] = o[len(o)-2].GetToken32() + } + } + return tokens +} + +func (t *tokens16) Expand(index int) TokenTree { + tree := t.tree + if index >= len(tree) { + expanded := make([]token32, 2*len(tree)) + for i, v := range tree { + expanded[i] = v.GetToken32() + } + return &tokens32{tree: expanded} + } + return nil +} + +func (t *tokens32) Expand(index int) TokenTree { + tree := t.tree + if index >= len(tree) { + expanded := make([]token32, 2*len(tree)) + copy(expanded, tree) + t.tree = expanded + } + return nil +} + +type Leg struct { + *Tree + + Buffer string + buffer []rune + rules [93]func() bool + Parse func(rule ...int) error + Reset func() + TokenTree +} + +type textPosition struct { + line, symbol int +} + +type textPositionMap map[int]textPosition + +func translatePositions(buffer string, positions []int) textPositionMap { + length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 + sort.Ints(positions) + +search: + for i, c := range buffer[0:] { + if c == '\n' { + line, symbol = line+1, 0 + } else { + symbol++ + } + if i == positions[j] { + translations[positions[j]] = textPosition{line, symbol} + for j++; j < length; j++ { + if i != positions[j] { + continue search + } + } + break search + } + } + + return translations +} + +type parseError struct { + p *Leg +} + +func (e *parseError) Error() string { + tokens, error := e.p.TokenTree.Error(), "\n" + positions, p := make([]int, 2*len(tokens)), 0 + for _, token := range tokens { + positions[p], p = int(token.begin), p+1 + positions[p], p = int(token.end), p+1 + } + translations := translatePositions(e.p.Buffer, positions) + for _, token := range tokens { + begin, end := int(token.begin), int(token.end) + error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", + Rul3s[token.Rule], + translations[begin].line, translations[begin].symbol, + translations[end].line, translations[end].symbol, + /*strconv.Quote(*/ e.p.Buffer[begin:end] /*)*/) + } + + return error +} + +func (p *Leg) PrintSyntaxTree() { + p.TokenTree.PrintSyntaxTree(p.Buffer) +} + +func (p *Leg) Highlighter() { + p.TokenTree.PrintSyntax() +} + +func (p *Leg) Execute() { + buffer, begin, end := p.Buffer, 0, 0 + + for token := range p.TokenTree.Tokens() { + switch token.Rule { + case RulePegText: + begin, end = int(token.begin), int(token.end) + case RuleAction0: + p.AddPackage(buffer[begin:end]) + case RuleAction1: + p.AddYYSType(buffer[begin:end]) + case RuleAction2: + p.AddLeg(buffer[begin:end]) + case RuleAction3: + p.AddState(buffer[begin:end]) + case RuleAction4: + p.AddDeclaration(buffer[begin:end]) + case RuleAction5: + p.AddTrailer(buffer[begin:end]) + case RuleAction6: + p.AddRule(buffer[begin:end]) + case RuleAction7: + p.AddExpression() + case RuleAction8: + p.AddAlternate() + case RuleAction9: + p.AddNil() + p.AddAlternate() + case RuleAction10: + p.AddNil() + case RuleAction11: + p.AddSequence() + case RuleAction12: + p.AddPredicate(buffer[begin:end]) + case RuleAction13: + p.AddPeekFor() + case RuleAction14: + p.AddPeekNot() + case RuleAction15: + p.AddQuery() + case RuleAction16: + p.AddStar() + case RuleAction17: + p.AddPlus() + case RuleAction18: + p.AddVariable(buffer[begin:end]) + case RuleAction19: + p.AddName(buffer[begin:end]) + case RuleAction20: + p.AddName(buffer[begin:end]) + case RuleAction21: + p.AddDot() + case RuleAction22: + p.AddAction(buffer[begin:end]) + case RuleAction23: + p.AddPush() + case RuleAction24: + p.AddSequence() + case RuleAction25: + p.AddSequence() + case RuleAction26: + p.AddPeekNot() + p.AddDot() + p.AddSequence() + case RuleAction27: + p.AddPeekNot() + p.AddDot() + p.AddSequence() + case RuleAction28: + p.AddAlternate() + case RuleAction29: + p.AddAlternate() + case RuleAction30: + p.AddRange() + case RuleAction31: + p.AddDoubleRange() + case RuleAction32: + p.AddCharacter(buffer[begin:end]) + case RuleAction33: + p.AddDoubleCharacter(buffer[begin:end]) + case RuleAction34: + p.AddCharacter(buffer[begin:end]) + case RuleAction35: + p.AddCharacter("\a") + case RuleAction36: + p.AddCharacter("\b") + case RuleAction37: + p.AddCharacter("\x1B") + case RuleAction38: + p.AddCharacter("\f") + case RuleAction39: + p.AddCharacter("\n") + case RuleAction40: + p.AddCharacter("\r") + case RuleAction41: + p.AddCharacter("\t") + case RuleAction42: + p.AddCharacter("\v") + case RuleAction43: + p.AddCharacter("'") + case RuleAction44: + p.AddCharacter("\"") + case RuleAction45: + p.AddCharacter("[") + case RuleAction46: + p.AddCharacter("]") + case RuleAction47: + p.AddCharacter("-") + case RuleAction48: + p.AddOctalCharacter(buffer[begin:end]) + case RuleAction49: + p.AddOctalCharacter(buffer[begin:end]) + case RuleAction50: + p.AddCharacter("\\") + + } + } +} + +func (p *Leg) Init() { + p.buffer = []rune(p.Buffer) + if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != END_SYMBOL { + p.buffer = append(p.buffer, END_SYMBOL) + } + + var tree TokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} + position, depth, tokenIndex, buffer, rules := 0, 0, 0, p.buffer, p.rules + + p.Parse = func(rule ...int) error { + r := 1 + if len(rule) > 0 { + r = rule[0] + } + matches := p.rules[r]() + p.TokenTree = tree + if matches { + p.TokenTree.trim(tokenIndex) + return nil + } + return &parseError{p} + } + + p.Reset = func() { + position, tokenIndex, depth = 0, 0, 0 + } + + add := func(rule Rule, begin int) { + if t := tree.Expand(tokenIndex); t != nil { + tree = t + } + tree.Add(rule, begin, position, depth, tokenIndex) + tokenIndex++ + } + + matchDot := func() bool { + if buffer[position] != END_SYMBOL { + position++ + return true + } + return false + } + + /*matchChar := func(c byte) bool { + if buffer[position] == c { + position++ + return true + } + return false + }*/ + + /*matchRange := func(lower byte, upper byte) bool { + if c := buffer[position]; c >= lower && c <= upper { + position++ + return true + } + return false + }*/ + + rules = [...]func() bool{ + nil, + /* 0 Grammar <- <(_ ('p' 'a' 'c' 'k' 'a' 'g' 'e') _ Identifier Action0 ('Y' 'Y' 'S' 'T' 'Y' 'P' 'E') _ Identifier Action1 ('t' 'y' 'p' 'e') _ Identifier Action2 ('P' 'e' 'g') _ Action Action3 (Declaration / Definition)+ Trailer? EndOfFile)> */ + func() bool { + position0, tokenIndex0, depth0 := position, tokenIndex, depth + { + + position1 := position + depth++ + if !rules[Rule_]() { + goto l0 + } + if buffer[position] != rune('p') { + goto l0 + } + position++ + if buffer[position] != rune('a') { + goto l0 + } + position++ + if buffer[position] != rune('c') { + goto l0 + } + position++ + if buffer[position] != rune('k') { + goto l0 + } + position++ + if buffer[position] != rune('a') { + goto l0 + } + position++ + if buffer[position] != rune('g') { + goto l0 + } + position++ + if buffer[position] != rune('e') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction0, position) + } + if buffer[position] != rune('Y') { + goto l0 + } + position++ + if buffer[position] != rune('Y') { + goto l0 + } + position++ + if buffer[position] != rune('S') { + goto l0 + } + position++ + if buffer[position] != rune('T') { + goto l0 + } + position++ + if buffer[position] != rune('Y') { + goto l0 + } + position++ + if buffer[position] != rune('P') { + goto l0 + } + position++ + if buffer[position] != rune('E') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction1, position) + } + if buffer[position] != rune('t') { + goto l0 + } + position++ + if buffer[position] != rune('y') { + goto l0 + } + position++ + if buffer[position] != rune('p') { + goto l0 + } + position++ + if buffer[position] != rune('e') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction2, position) + } + if buffer[position] != rune('P') { + goto l0 + } + position++ + if buffer[position] != rune('e') { + goto l0 + } + position++ + if buffer[position] != rune('g') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleAction]() { + goto l0 + } + { + + add(RuleAction3, position) + } + { + + position8, tokenIndex8, depth8 := position, tokenIndex, depth + { + + position10 := position + depth++ + { + + position11 := position + depth++ + if buffer[position] != rune('%') { + goto l9 + } + position++ + if buffer[position] != rune('{') { + goto l9 + } + position++ + depth-- + add(RulePegText, position11) + } + { + + position12 := position + depth++ + l13: + { + + position14, tokenIndex14, depth14 := position, tokenIndex, depth + { + + position15, tokenIndex15, depth15 := position, tokenIndex, depth + { + + position16 := position + depth++ + if buffer[position] != rune('%') { + goto l15 + } + position++ + if buffer[position] != rune('}') { + goto l15 + } + position++ + depth-- + add(RulePegText, position16) + } + goto l14 + l15: + position, tokenIndex, depth = position15, tokenIndex15, depth15 + } + if !matchDot() { + goto l14 + } + goto l13 + l14: + position, tokenIndex, depth = position14, tokenIndex14, depth14 + } + depth-- + add(RulePegText, position12) + } + { + + position17 := position + depth++ + if buffer[position] != rune('%') { + goto l9 + } + position++ + if buffer[position] != rune('}') { + goto l9 + } + position++ + if !rules[Rule_]() { + goto l9 + } + depth-- + add(RuleRPERCENT, position17) + } + { + + add(RuleAction4, position) + } + depth-- + add(RuleDeclaration, position10) + } + goto l8 + l9: + position, tokenIndex, depth = position8, tokenIndex8, depth8 + { + + position19 := position + depth++ + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction6, position) + } + if !rules[RuleEqual]() { + goto l0 + } + if !rules[RuleExpression]() { + goto l0 + } + { + + add(RuleAction7, position) + } + depth-- + add(RuleDefinition, position19) + } + } + l8: + l6: + { + + position7, tokenIndex7, depth7 := position, tokenIndex, depth + { + + position22, tokenIndex22, depth22 := position, tokenIndex, depth + { + + position24 := position + depth++ + { + + position25 := position + depth++ + if buffer[position] != rune('%') { + goto l23 + } + position++ + if buffer[position] != rune('{') { + goto l23 + } + position++ + depth-- + add(RulePegText, position25) + } + { + + position26 := position + depth++ + l27: + { + + position28, tokenIndex28, depth28 := position, tokenIndex, depth + { + + position29, tokenIndex29, depth29 := position, tokenIndex, depth + { + + position30 := position + depth++ + if buffer[position] != rune('%') { + goto l29 + } + position++ + if buffer[position] != rune('}') { + goto l29 + } + position++ + depth-- + add(RulePegText, position30) + } + goto l28 + l29: + position, tokenIndex, depth = position29, tokenIndex29, depth29 + } + if !matchDot() { + goto l28 + } + goto l27 + l28: + position, tokenIndex, depth = position28, tokenIndex28, depth28 + } + depth-- + add(RulePegText, position26) + } + { + + position31 := position + depth++ + if buffer[position] != rune('%') { + goto l23 + } + position++ + if buffer[position] != rune('}') { + goto l23 + } + position++ + if !rules[Rule_]() { + goto l23 + } + depth-- + add(RuleRPERCENT, position31) + } + { + + add(RuleAction4, position) + } + depth-- + add(RuleDeclaration, position24) + } + goto l22 + l23: + position, tokenIndex, depth = position22, tokenIndex22, depth22 + { + + position33 := position + depth++ + if !rules[RuleIdentifier]() { + goto l7 + } + { + + add(RuleAction6, position) + } + if !rules[RuleEqual]() { + goto l7 + } + if !rules[RuleExpression]() { + goto l7 + } + { + + add(RuleAction7, position) + } + depth-- + add(RuleDefinition, position33) + } + } + l22: + goto l6 + l7: + position, tokenIndex, depth = position7, tokenIndex7, depth7 + } + { + + position36, tokenIndex36, depth36 := position, tokenIndex, depth + { + + position38 := position + depth++ + if buffer[position] != rune('%') { + goto l36 + } + position++ + if buffer[position] != rune('%') { + goto l36 + } + position++ + { + + position39 := position + depth++ + l40: + { + + position41, tokenIndex41, depth41 := position, tokenIndex, depth + if !matchDot() { + goto l41 + } + goto l40 + l41: + position, tokenIndex, depth = position41, tokenIndex41, depth41 + } + depth-- + add(RulePegText, position39) + } + { + + add(RuleAction5, position) + } + depth-- + add(RuleTrailer, position38) + } + goto l37 + l36: + position, tokenIndex, depth = position36, tokenIndex36, depth36 + } + l37: + { + + position43 := position + depth++ + { + + position44, tokenIndex44, depth44 := position, tokenIndex, depth + if !matchDot() { + goto l44 + } + goto l0 + l44: + position, tokenIndex, depth = position44, tokenIndex44, depth44 + } + depth-- + add(RuleEndOfFile, position43) + } + depth-- + add(RuleGrammar, position1) + } + return true + l0: + position, tokenIndex, depth = position0, tokenIndex0, depth0 + return false + }, + /* 1 Declaration <- <(<('%' '{')> <(!<('%' '}')> .)*> RPERCENT Action4)> */ + nil, + /* 2 Trailer <- <('%' '%' (<.*> Action5))> */ + nil, + /* 3 Definition <- <(Identifier Action6 Equal Expression Action7)> */ + nil, + /* 4 Expression <- <((Sequence (Bar Sequence Action8)* (Bar Action9)?) / Action10)> */ + func() bool { + { + + position49 := position + depth++ + { + + position50, tokenIndex50, depth50 := position, tokenIndex, depth + if !rules[RuleSequence]() { + goto l51 + } + l52: + { + + position53, tokenIndex53, depth53 := position, tokenIndex, depth + if !rules[RuleBar]() { + goto l53 + } + if !rules[RuleSequence]() { + goto l53 + } + { + + add(RuleAction8, position) + } + goto l52 + l53: + position, tokenIndex, depth = position53, tokenIndex53, depth53 + } + { + + position55, tokenIndex55, depth55 := position, tokenIndex, depth + if !rules[RuleBar]() { + goto l55 + } + { + + add(RuleAction9, position) + } + goto l56 + l55: + position, tokenIndex, depth = position55, tokenIndex55, depth55 + } + l56: + goto l50 + l51: + position, tokenIndex, depth = position50, tokenIndex50, depth50 + { + + add(RuleAction10, position) + } + } + l50: + depth-- + add(RuleExpression, position49) + } + return true + }, + /* 5 Sequence <- <(Prefix (Prefix Action11)*)> */ + func() bool { + position59, tokenIndex59, depth59 := position, tokenIndex, depth + { + + position60 := position + depth++ + if !rules[RulePrefix]() { + goto l59 + } + l61: + { + + position62, tokenIndex62, depth62 := position, tokenIndex, depth + if !rules[RulePrefix]() { + goto l62 + } + { + + add(RuleAction11, position) + } + goto l61 + l62: + position, tokenIndex, depth = position62, tokenIndex62, depth62 + } + depth-- + add(RuleSequence, position60) + } + return true + l59: + position, tokenIndex, depth = position59, tokenIndex59, depth59 + return false + }, + /* 6 Prefix <- <((And Action Action12) / ((&('!') (Not Suffix Action14)) | (&('&') (And Suffix Action13)) | (&('"' | '\'' | '(' | '-' | '.' | '<' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[' | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{') Suffix)))> */ + func() bool { + position64, tokenIndex64, depth64 := position, tokenIndex, depth + { + + position65 := position + depth++ + { + + position66, tokenIndex66, depth66 := position, tokenIndex, depth + if !rules[RuleAnd]() { + goto l67 + } + if !rules[RuleAction]() { + goto l67 + } + { + + add(RuleAction12, position) + } + goto l66 + l67: + position, tokenIndex, depth = position66, tokenIndex66, depth66 + { + + switch buffer[position] { + case '!': + { + + position70 := position + depth++ + if buffer[position] != rune('!') { + goto l64 + } + position++ + if !rules[Rule_]() { + goto l64 + } + depth-- + add(RuleNot, position70) + } + if !rules[RuleSuffix]() { + goto l64 + } + { + + add(RuleAction14, position) + } + break + case '&': + if !rules[RuleAnd]() { + goto l64 + } + if !rules[RuleSuffix]() { + goto l64 + } + { + + add(RuleAction13, position) + } + break + default: + if !rules[RuleSuffix]() { + goto l64 + } + break + } + } + + } + l66: + depth-- + add(RulePrefix, position65) + } + return true + l64: + position, tokenIndex, depth = position64, tokenIndex64, depth64 + return false + }, + /* 7 Suffix <- <(Primary ((&('+') (Plus Action17)) | (&('*') (Star Action16)) | (&('?') (Question Action15)))?)> */ + func() bool { + position73, tokenIndex73, depth73 := position, tokenIndex, depth + { + + position74 := position + depth++ + { + + position75 := position + depth++ + { + + position76, tokenIndex76, depth76 := position, tokenIndex, depth + if !rules[RuleIdentifier]() { + goto l77 + } + { + + add(RuleAction18, position) + } + { + + position79 := position + depth++ + if buffer[position] != rune(':') { + goto l77 + } + position++ + if !rules[Rule_]() { + goto l77 + } + depth-- + add(RuleColon, position79) + } + if !rules[RuleIdentifier]() { + goto l77 + } + { + + position80, tokenIndex80, depth80 := position, tokenIndex, depth + if !rules[RuleEqual]() { + goto l80 + } + goto l77 + l80: + position, tokenIndex, depth = position80, tokenIndex80, depth80 + } + { + + add(RuleAction19, position) + } + goto l76 + l77: + position, tokenIndex, depth = position76, tokenIndex76, depth76 + { + + switch buffer[position] { + case '<': + { + + position83 := position + depth++ + if buffer[position] != rune('<') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleBegin, position83) + } + if !rules[RuleExpression]() { + goto l73 + } + { + + position84 := position + depth++ + if buffer[position] != rune('>') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleEnd, position84) + } + { + + add(RuleAction23, position) + } + break + case '{': + if !rules[RuleAction]() { + goto l73 + } + { + + add(RuleAction22, position) + } + break + case '.': + { + + position87 := position + depth++ + if buffer[position] != rune('.') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleDot, position87) + } + { + + add(RuleAction21, position) + } + break + case '[': + { + + position89 := position + depth++ + { + + position90, tokenIndex90, depth90 := position, tokenIndex, depth + if buffer[position] != rune('[') { + goto l91 + } + position++ + if buffer[position] != rune('[') { + goto l91 + } + position++ + { + + position92, tokenIndex92, depth92 := position, tokenIndex, depth + { + + position94, tokenIndex94, depth94 := position, tokenIndex, depth + if buffer[position] != rune('^') { + goto l95 + } + position++ + if !rules[RuleDoubleRanges]() { + goto l95 + } + { + + add(RuleAction26, position) + } + goto l94 + l95: + position, tokenIndex, depth = position94, tokenIndex94, depth94 + if !rules[RuleDoubleRanges]() { + goto l92 + } + } + l94: + goto l93 + l92: + position, tokenIndex, depth = position92, tokenIndex92, depth92 + } + l93: + if buffer[position] != rune(']') { + goto l91 + } + position++ + if buffer[position] != rune(']') { + goto l91 + } + position++ + goto l90 + l91: + position, tokenIndex, depth = position90, tokenIndex90, depth90 + if buffer[position] != rune('[') { + goto l73 + } + position++ + { + + position97, tokenIndex97, depth97 := position, tokenIndex, depth + { + + position99, tokenIndex99, depth99 := position, tokenIndex, depth + if buffer[position] != rune('^') { + goto l100 + } + position++ + if !rules[RuleRanges]() { + goto l100 + } + { + + add(RuleAction27, position) + } + goto l99 + l100: + position, tokenIndex, depth = position99, tokenIndex99, depth99 + if !rules[RuleRanges]() { + goto l97 + } + } + l99: + goto l98 + l97: + position, tokenIndex, depth = position97, tokenIndex97, depth97 + } + l98: + if buffer[position] != rune(']') { + goto l73 + } + position++ + } + l90: + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleClass, position89) + } + break + case '"', '\'': + { + + position102 := position + depth++ + { + + position103, tokenIndex103, depth103 := position, tokenIndex, depth + if buffer[position] != rune('\'') { + goto l104 + } + position++ + { + + position105, tokenIndex105, depth105 := position, tokenIndex, depth + { + + position107, tokenIndex107, depth107 := position, tokenIndex, depth + if buffer[position] != rune('\'') { + goto l107 + } + position++ + goto l105 + l107: + position, tokenIndex, depth = position107, tokenIndex107, depth107 + } + if !rules[RuleChar]() { + goto l105 + } + goto l106 + l105: + position, tokenIndex, depth = position105, tokenIndex105, depth105 + } + l106: + l108: + { + + position109, tokenIndex109, depth109 := position, tokenIndex, depth + { + + position110, tokenIndex110, depth110 := position, tokenIndex, depth + if buffer[position] != rune('\'') { + goto l110 + } + position++ + goto l109 + l110: + position, tokenIndex, depth = position110, tokenIndex110, depth110 + } + if !rules[RuleChar]() { + goto l109 + } + { + + add(RuleAction24, position) + } + goto l108 + l109: + position, tokenIndex, depth = position109, tokenIndex109, depth109 + } + if buffer[position] != rune('\'') { + goto l104 + } + position++ + if !rules[Rule_]() { + goto l104 + } + goto l103 + l104: + position, tokenIndex, depth = position103, tokenIndex103, depth103 + if buffer[position] != rune('"') { + goto l73 + } + position++ + { + + position112, tokenIndex112, depth112 := position, tokenIndex, depth + { + + position114, tokenIndex114, depth114 := position, tokenIndex, depth + if buffer[position] != rune('"') { + goto l114 + } + position++ + goto l112 + l114: + position, tokenIndex, depth = position114, tokenIndex114, depth114 + } + if !rules[RuleDoubleChar]() { + goto l112 + } + goto l113 + l112: + position, tokenIndex, depth = position112, tokenIndex112, depth112 + } + l113: + l115: + { + + position116, tokenIndex116, depth116 := position, tokenIndex, depth + { + + position117, tokenIndex117, depth117 := position, tokenIndex, depth + if buffer[position] != rune('"') { + goto l117 + } + position++ + goto l116 + l117: + position, tokenIndex, depth = position117, tokenIndex117, depth117 + } + if !rules[RuleDoubleChar]() { + goto l116 + } + { + + add(RuleAction25, position) + } + goto l115 + l116: + position, tokenIndex, depth = position116, tokenIndex116, depth116 + } + if buffer[position] != rune('"') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + } + l103: + depth-- + add(RuleLiteral, position102) + } + break + case '(': + { + + position119 := position + depth++ + if buffer[position] != rune('(') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleOpen, position119) + } + if !rules[RuleExpression]() { + goto l73 + } + { + + position120 := position + depth++ + if buffer[position] != rune(')') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleClose, position120) + } + break + default: + if !rules[RuleIdentifier]() { + goto l73 + } + { + + position121, tokenIndex121, depth121 := position, tokenIndex, depth + if !rules[RuleEqual]() { + goto l121 + } + goto l73 + l121: + position, tokenIndex, depth = position121, tokenIndex121, depth121 + } + { + + add(RuleAction20, position) + } + break + } + } + + } + l76: + depth-- + add(RulePrimary, position75) + } + { + + position123, tokenIndex123, depth123 := position, tokenIndex, depth + { + + switch buffer[position] { + case '+': + { + + position126 := position + depth++ + if buffer[position] != rune('+') { + goto l123 + } + position++ + if !rules[Rule_]() { + goto l123 + } + depth-- + add(RulePlus, position126) + } + { + + add(RuleAction17, position) + } + break + case '*': + { + + position128 := position + depth++ + if buffer[position] != rune('*') { + goto l123 + } + position++ + if !rules[Rule_]() { + goto l123 + } + depth-- + add(RuleStar, position128) + } + { + + add(RuleAction16, position) + } + break + default: + { + + position130 := position + depth++ + if buffer[position] != rune('?') { + goto l123 + } + position++ + if !rules[Rule_]() { + goto l123 + } + depth-- + add(RuleQuestion, position130) + } + { + + add(RuleAction15, position) + } + break + } + } + + goto l124 + l123: + position, tokenIndex, depth = position123, tokenIndex123, depth123 + } + l124: + depth-- + add(RuleSuffix, position74) + } + return true + l73: + position, tokenIndex, depth = position73, tokenIndex73, depth73 + return false + }, + /* 8 Primary <- <((Identifier Action18 Colon Identifier !Equal Action19) / ((&('<') (Begin Expression End Action23)) | (&('{') (Action Action22)) | (&('.') (Dot Action21)) | (&('[') Class) | (&('"' | '\'') Literal) | (&('(') (Open Expression Close)) | (&('-' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') (Identifier !Equal Action20))))> */ + nil, + /* 9 Identifier <- <(<(((&('_') '_') | (&('-') '-') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') ([a-z] / [A-Z]))) ((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('-') '-') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') ([a-z] / [A-Z])))*)> _)> */ + func() bool { + position133, tokenIndex133, depth133 := position, tokenIndex, depth + { + + position134 := position + depth++ + { + + position135 := position + depth++ + { + + switch buffer[position] { + case '_': + if buffer[position] != rune('_') { + goto l133 + } + position++ + break + case '-': + if buffer[position] != rune('-') { + goto l133 + } + position++ + break + default: + { + + position137, tokenIndex137, depth137 := position, tokenIndex, depth + if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l138 + } + position++ + goto l137 + l138: + position, tokenIndex, depth = position137, tokenIndex137, depth137 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l133 + } + position++ + } + l137: + break + } + } + + l139: + { + + position140, tokenIndex140, depth140 := position, tokenIndex, depth + { + + switch buffer[position] { + case '_': + if buffer[position] != rune('_') { + goto l140 + } + position++ + break + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l140 + } + position++ + break + case '-': + if buffer[position] != rune('-') { + goto l140 + } + position++ + break + default: + { + + position142, tokenIndex142, depth142 := position, tokenIndex, depth + if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l143 + } + position++ + goto l142 + l143: + position, tokenIndex, depth = position142, tokenIndex142, depth142 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l140 + } + position++ + } + l142: + break + } + } + + goto l139 + l140: + position, tokenIndex, depth = position140, tokenIndex140, depth140 + } + depth-- + add(RulePegText, position135) + } + if !rules[Rule_]() { + goto l133 + } + depth-- + add(RuleIdentifier, position134) + } + return true + l133: + position, tokenIndex, depth = position133, tokenIndex133, depth133 + return false + }, + /* 10 Literal <- <(('\'' (!'\'' Char)? (!'\'' Char Action24)* '\'' _) / ('"' (!'"' DoubleChar)? (!'"' DoubleChar Action25)* '"' _))> */ + nil, + /* 11 Class <- <((('[' '[' (('^' DoubleRanges Action26) / DoubleRanges)? (']' ']')) / ('[' (('^' Ranges Action27) / Ranges)? ']')) _)> */ + nil, + /* 12 Ranges <- <(!']' Range (!']' Range Action28)*)> */ + func() bool { + position146, tokenIndex146, depth146 := position, tokenIndex, depth + { + + position147 := position + depth++ + { + + position148, tokenIndex148, depth148 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l148 + } + position++ + goto l146 + l148: + position, tokenIndex, depth = position148, tokenIndex148, depth148 + } + if !rules[RuleRange]() { + goto l146 + } + l149: + { + + position150, tokenIndex150, depth150 := position, tokenIndex, depth + { + + position151, tokenIndex151, depth151 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l151 + } + position++ + goto l150 + l151: + position, tokenIndex, depth = position151, tokenIndex151, depth151 + } + if !rules[RuleRange]() { + goto l150 + } + { + + add(RuleAction28, position) + } + goto l149 + l150: + position, tokenIndex, depth = position150, tokenIndex150, depth150 + } + depth-- + add(RuleRanges, position147) + } + return true + l146: + position, tokenIndex, depth = position146, tokenIndex146, depth146 + return false + }, + /* 13 DoubleRanges <- <(!(']' ']') DoubleRange (!(']' ']') DoubleRange Action29)*)> */ + func() bool { + position153, tokenIndex153, depth153 := position, tokenIndex, depth + { + + position154 := position + depth++ + { + + position155, tokenIndex155, depth155 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l155 + } + position++ + if buffer[position] != rune(']') { + goto l155 + } + position++ + goto l153 + l155: + position, tokenIndex, depth = position155, tokenIndex155, depth155 + } + if !rules[RuleDoubleRange]() { + goto l153 + } + l156: + { + + position157, tokenIndex157, depth157 := position, tokenIndex, depth + { + + position158, tokenIndex158, depth158 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l158 + } + position++ + if buffer[position] != rune(']') { + goto l158 + } + position++ + goto l157 + l158: + position, tokenIndex, depth = position158, tokenIndex158, depth158 + } + if !rules[RuleDoubleRange]() { + goto l157 + } + { + + add(RuleAction29, position) + } + goto l156 + l157: + position, tokenIndex, depth = position157, tokenIndex157, depth157 + } + depth-- + add(RuleDoubleRanges, position154) + } + return true + l153: + position, tokenIndex, depth = position153, tokenIndex153, depth153 + return false + }, + /* 14 Range <- <((Char '-' Char Action30) / Char)> */ + func() bool { + position160, tokenIndex160, depth160 := position, tokenIndex, depth + { + + position161 := position + depth++ + { + + position162, tokenIndex162, depth162 := position, tokenIndex, depth + if !rules[RuleChar]() { + goto l163 + } + if buffer[position] != rune('-') { + goto l163 + } + position++ + if !rules[RuleChar]() { + goto l163 + } + { + + add(RuleAction30, position) + } + goto l162 + l163: + position, tokenIndex, depth = position162, tokenIndex162, depth162 + if !rules[RuleChar]() { + goto l160 + } + } + l162: + depth-- + add(RuleRange, position161) + } + return true + l160: + position, tokenIndex, depth = position160, tokenIndex160, depth160 + return false + }, + /* 15 DoubleRange <- <((Char '-' Char Action31) / DoubleChar)> */ + func() bool { + position165, tokenIndex165, depth165 := position, tokenIndex, depth + { + + position166 := position + depth++ + { + + position167, tokenIndex167, depth167 := position, tokenIndex, depth + if !rules[RuleChar]() { + goto l168 + } + if buffer[position] != rune('-') { + goto l168 + } + position++ + if !rules[RuleChar]() { + goto l168 + } + { + + add(RuleAction31, position) + } + goto l167 + l168: + position, tokenIndex, depth = position167, tokenIndex167, depth167 + if !rules[RuleDoubleChar]() { + goto l165 + } + } + l167: + depth-- + add(RuleDoubleRange, position166) + } + return true + l165: + position, tokenIndex, depth = position165, tokenIndex165, depth165 + return false + }, + /* 16 Char <- <(Escape / (!'\\' <.> Action32))> */ + func() bool { + position170, tokenIndex170, depth170 := position, tokenIndex, depth + { + + position171 := position + depth++ + { + + position172, tokenIndex172, depth172 := position, tokenIndex, depth + if !rules[RuleEscape]() { + goto l173 + } + goto l172 + l173: + position, tokenIndex, depth = position172, tokenIndex172, depth172 + { + + position174, tokenIndex174, depth174 := position, tokenIndex, depth + if buffer[position] != rune('\\') { + goto l174 + } + position++ + goto l170 + l174: + position, tokenIndex, depth = position174, tokenIndex174, depth174 + } + { + + position175 := position + depth++ + if !matchDot() { + goto l170 + } + depth-- + add(RulePegText, position175) + } + { + + add(RuleAction32, position) + } + } + l172: + depth-- + add(RuleChar, position171) + } + return true + l170: + position, tokenIndex, depth = position170, tokenIndex170, depth170 + return false + }, + /* 17 DoubleChar <- <(Escape / (<([a-z] / [A-Z])> Action33) / (!'\\' <.> Action34))> */ + func() bool { + position177, tokenIndex177, depth177 := position, tokenIndex, depth + { + + position178 := position + depth++ + { + + position179, tokenIndex179, depth179 := position, tokenIndex, depth + if !rules[RuleEscape]() { + goto l180 + } + goto l179 + l180: + position, tokenIndex, depth = position179, tokenIndex179, depth179 + { + + position182 := position + depth++ + { + + position183, tokenIndex183, depth183 := position, tokenIndex, depth + if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l184 + } + position++ + goto l183 + l184: + position, tokenIndex, depth = position183, tokenIndex183, depth183 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l181 + } + position++ + } + l183: + depth-- + add(RulePegText, position182) + } + { + + add(RuleAction33, position) + } + goto l179 + l181: + position, tokenIndex, depth = position179, tokenIndex179, depth179 + { + + position186, tokenIndex186, depth186 := position, tokenIndex, depth + if buffer[position] != rune('\\') { + goto l186 + } + position++ + goto l177 + l186: + position, tokenIndex, depth = position186, tokenIndex186, depth186 + } + { + + position187 := position + depth++ + if !matchDot() { + goto l177 + } + depth-- + add(RulePegText, position187) + } + { + + add(RuleAction34, position) + } + } + l179: + depth-- + add(RuleDoubleChar, position178) + } + return true + l177: + position, tokenIndex, depth = position177, tokenIndex177, depth177 + return false + }, + /* 18 Escape <- <(('\\' ('a' / 'A') Action35) / ('\\' ('b' / 'B') Action36) / ('\\' ('e' / 'E') Action37) / ('\\' ('f' / 'F') Action38) / ('\\' ('n' / 'N') Action39) / ('\\' ('r' / 'R') Action40) / ('\\' ('t' / 'T') Action41) / ('\\' ('v' / 'V') Action42) / ('\\' '\'' Action43) / ('\\' '"' Action44) / ('\\' '[' Action45) / ('\\' ']' Action46) / ('\\' '-' Action47) / ('\\' <([0-3] [0-7] [0-7])> Action48) / ('\\' <([0-7] [0-7]?)> Action49) / ('\\' '\\' Action50))> */ + func() bool { + position189, tokenIndex189, depth189 := position, tokenIndex, depth + { + + position190 := position + depth++ + { + + position191, tokenIndex191, depth191 := position, tokenIndex, depth + if buffer[position] != rune('\\') { + goto l192 + } + position++ + { + + position193, tokenIndex193, depth193 := position, tokenIndex, depth + if buffer[position] != rune('a') { + goto l194 + } + position++ + goto l193 + l194: + position, tokenIndex, depth = position193, tokenIndex193, depth193 + if buffer[position] != rune('A') { + goto l192 + } + position++ + } + l193: + { + + add(RuleAction35, position) + } + goto l191 + l192: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l196 + } + position++ + { + + position197, tokenIndex197, depth197 := position, tokenIndex, depth + if buffer[position] != rune('b') { + goto l198 + } + position++ + goto l197 + l198: + position, tokenIndex, depth = position197, tokenIndex197, depth197 + if buffer[position] != rune('B') { + goto l196 + } + position++ + } + l197: + { + + add(RuleAction36, position) + } + goto l191 + l196: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l200 + } + position++ + { + + position201, tokenIndex201, depth201 := position, tokenIndex, depth + if buffer[position] != rune('e') { + goto l202 + } + position++ + goto l201 + l202: + position, tokenIndex, depth = position201, tokenIndex201, depth201 + if buffer[position] != rune('E') { + goto l200 + } + position++ + } + l201: + { + + add(RuleAction37, position) + } + goto l191 + l200: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l204 + } + position++ + { + + position205, tokenIndex205, depth205 := position, tokenIndex, depth + if buffer[position] != rune('f') { + goto l206 + } + position++ + goto l205 + l206: + position, tokenIndex, depth = position205, tokenIndex205, depth205 + if buffer[position] != rune('F') { + goto l204 + } + position++ + } + l205: + { + + add(RuleAction38, position) + } + goto l191 + l204: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l208 + } + position++ + { + + position209, tokenIndex209, depth209 := position, tokenIndex, depth + if buffer[position] != rune('n') { + goto l210 + } + position++ + goto l209 + l210: + position, tokenIndex, depth = position209, tokenIndex209, depth209 + if buffer[position] != rune('N') { + goto l208 + } + position++ + } + l209: + { + + add(RuleAction39, position) + } + goto l191 + l208: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l212 + } + position++ + { + + position213, tokenIndex213, depth213 := position, tokenIndex, depth + if buffer[position] != rune('r') { + goto l214 + } + position++ + goto l213 + l214: + position, tokenIndex, depth = position213, tokenIndex213, depth213 + if buffer[position] != rune('R') { + goto l212 + } + position++ + } + l213: + { + + add(RuleAction40, position) + } + goto l191 + l212: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l216 + } + position++ + { + + position217, tokenIndex217, depth217 := position, tokenIndex, depth + if buffer[position] != rune('t') { + goto l218 + } + position++ + goto l217 + l218: + position, tokenIndex, depth = position217, tokenIndex217, depth217 + if buffer[position] != rune('T') { + goto l216 + } + position++ + } + l217: + { + + add(RuleAction41, position) + } + goto l191 + l216: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l220 + } + position++ + { + + position221, tokenIndex221, depth221 := position, tokenIndex, depth + if buffer[position] != rune('v') { + goto l222 + } + position++ + goto l221 + l222: + position, tokenIndex, depth = position221, tokenIndex221, depth221 + if buffer[position] != rune('V') { + goto l220 + } + position++ + } + l221: + { + + add(RuleAction42, position) + } + goto l191 + l220: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l224 + } + position++ + if buffer[position] != rune('\'') { + goto l224 + } + position++ + { + + add(RuleAction43, position) + } + goto l191 + l224: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l226 + } + position++ + if buffer[position] != rune('"') { + goto l226 + } + position++ + { + + add(RuleAction44, position) + } + goto l191 + l226: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l228 + } + position++ + if buffer[position] != rune('[') { + goto l228 + } + position++ + { + + add(RuleAction45, position) + } + goto l191 + l228: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l230 + } + position++ + if buffer[position] != rune(']') { + goto l230 + } + position++ + { + + add(RuleAction46, position) + } + goto l191 + l230: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l232 + } + position++ + if buffer[position] != rune('-') { + goto l232 + } + position++ + { + + add(RuleAction47, position) + } + goto l191 + l232: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l234 + } + position++ + { + + position235 := position + depth++ + if c := buffer[position]; c < rune('0') || c > rune('3') { + goto l234 + } + position++ + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l234 + } + position++ + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l234 + } + position++ + depth-- + add(RulePegText, position235) + } + { + + add(RuleAction48, position) + } + goto l191 + l234: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l237 + } + position++ + { + + position238 := position + depth++ + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l237 + } + position++ + { + + position239, tokenIndex239, depth239 := position, tokenIndex, depth + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l239 + } + position++ + goto l240 + l239: + position, tokenIndex, depth = position239, tokenIndex239, depth239 + } + l240: + depth-- + add(RulePegText, position238) + } + { + + add(RuleAction49, position) + } + goto l191 + l237: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l189 + } + position++ + if buffer[position] != rune('\\') { + goto l189 + } + position++ + { + + add(RuleAction50, position) + } + } + l191: + depth-- + add(RuleEscape, position190) + } + return true + l189: + position, tokenIndex, depth = position189, tokenIndex189, depth189 + return false + }, + /* 19 Action <- <('{' '}' _)> */ + func() bool { + position243, tokenIndex243, depth243 := position, tokenIndex, depth + { + + position244 := position + depth++ + if buffer[position] != rune('{') { + goto l243 + } + position++ + { + + position245 := position + depth++ + l246: + { + + position247, tokenIndex247, depth247 := position, tokenIndex, depth + if !rules[RuleBraces]() { + goto l247 + } + goto l246 + l247: + position, tokenIndex, depth = position247, tokenIndex247, depth247 + } + depth-- + add(RulePegText, position245) + } + if buffer[position] != rune('}') { + goto l243 + } + position++ + if !rules[Rule_]() { + goto l243 + } + depth-- + add(RuleAction, position244) + } + return true + l243: + position, tokenIndex, depth = position243, tokenIndex243, depth243 + return false + }, + /* 20 Braces <- <(('{' Braces* '}') / (!'}' .))> */ + func() bool { + position248, tokenIndex248, depth248 := position, tokenIndex, depth + { + + position249 := position + depth++ + { + + position250, tokenIndex250, depth250 := position, tokenIndex, depth + if buffer[position] != rune('{') { + goto l251 + } + position++ + l252: + { + + position253, tokenIndex253, depth253 := position, tokenIndex, depth + if !rules[RuleBraces]() { + goto l253 + } + goto l252 + l253: + position, tokenIndex, depth = position253, tokenIndex253, depth253 + } + if buffer[position] != rune('}') { + goto l251 + } + position++ + goto l250 + l251: + position, tokenIndex, depth = position250, tokenIndex250, depth250 + { + + position254, tokenIndex254, depth254 := position, tokenIndex, depth + if buffer[position] != rune('}') { + goto l254 + } + position++ + goto l248 + l254: + position, tokenIndex, depth = position254, tokenIndex254, depth254 + } + if !matchDot() { + goto l248 + } + } + l250: + depth-- + add(RuleBraces, position249) + } + return true + l248: + position, tokenIndex, depth = position248, tokenIndex248, depth248 + return false + }, + /* 21 Equal <- <('=' _)> */ + func() bool { + position255, tokenIndex255, depth255 := position, tokenIndex, depth + { + + position256 := position + depth++ + if buffer[position] != rune('=') { + goto l255 + } + position++ + if !rules[Rule_]() { + goto l255 + } + depth-- + add(RuleEqual, position256) + } + return true + l255: + position, tokenIndex, depth = position255, tokenIndex255, depth255 + return false + }, + /* 22 Colon <- <(':' _)> */ + nil, + /* 23 Bar <- <('|' _)> */ + func() bool { + position258, tokenIndex258, depth258 := position, tokenIndex, depth + { + + position259 := position + depth++ + if buffer[position] != rune('|') { + goto l258 + } + position++ + if !rules[Rule_]() { + goto l258 + } + depth-- + add(RuleBar, position259) + } + return true + l258: + position, tokenIndex, depth = position258, tokenIndex258, depth258 + return false + }, + /* 24 And <- <('&' _)> */ + func() bool { + position260, tokenIndex260, depth260 := position, tokenIndex, depth + { + + position261 := position + depth++ + if buffer[position] != rune('&') { + goto l260 + } + position++ + if !rules[Rule_]() { + goto l260 + } + depth-- + add(RuleAnd, position261) + } + return true + l260: + position, tokenIndex, depth = position260, tokenIndex260, depth260 + return false + }, + /* 25 Not <- <('!' _)> */ + nil, + /* 26 Question <- <('?' _)> */ + nil, + /* 27 Star <- <('*' _)> */ + nil, + /* 28 Plus <- <('+' _)> */ + nil, + /* 29 Open <- <('(' _)> */ + nil, + /* 30 Close <- <(')' _)> */ + nil, + /* 31 Dot <- <('.' _)> */ + nil, + /* 32 RPERCENT <- <('%' '}' _)> */ + nil, + /* 33 _ <- <(Space / Comment)*> */ + func() bool { + { + + position271 := position + depth++ + l272: + { + + position273, tokenIndex273, depth273 := position, tokenIndex, depth + { + + position274, tokenIndex274, depth274 := position, tokenIndex, depth + { + + position276 := position + depth++ + { + + switch buffer[position] { + case '\t': + if buffer[position] != rune('\t') { + goto l275 + } + position++ + break + case ' ': + if buffer[position] != rune(' ') { + goto l275 + } + position++ + break + default: + if !rules[RuleEndOfLine]() { + goto l275 + } + break + } + } + + depth-- + add(RuleSpace, position276) + } + goto l274 + l275: + position, tokenIndex, depth = position274, tokenIndex274, depth274 + { + + position278 := position + depth++ + if buffer[position] != rune('#') { + goto l273 + } + position++ + l279: + { + + position280, tokenIndex280, depth280 := position, tokenIndex, depth + { + + position281, tokenIndex281, depth281 := position, tokenIndex, depth + if !rules[RuleEndOfLine]() { + goto l281 + } + goto l280 + l281: + position, tokenIndex, depth = position281, tokenIndex281, depth281 + } + if !matchDot() { + goto l280 + } + goto l279 + l280: + position, tokenIndex, depth = position280, tokenIndex280, depth280 + } + if !rules[RuleEndOfLine]() { + goto l273 + } + depth-- + add(RuleComment, position278) + } + } + l274: + goto l272 + l273: + position, tokenIndex, depth = position273, tokenIndex273, depth273 + } + depth-- + add(Rule_, position271) + } + return true + }, + /* 34 Comment <- <('#' (!EndOfLine .)* EndOfLine)> */ + nil, + /* 35 Space <- <((&('\t') '\t') | (&(' ') ' ') | (&('\n' | '\r') EndOfLine))> */ + nil, + /* 36 EndOfLine <- <(('\r' '\n') / '\n' / '\r')> */ + func() bool { + position284, tokenIndex284, depth284 := position, tokenIndex, depth + { + + position285 := position + depth++ + { + + position286, tokenIndex286, depth286 := position, tokenIndex, depth + if buffer[position] != rune('\r') { + goto l287 + } + position++ + if buffer[position] != rune('\n') { + goto l287 + } + position++ + goto l286 + l287: + position, tokenIndex, depth = position286, tokenIndex286, depth286 + if buffer[position] != rune('\n') { + goto l288 + } + position++ + goto l286 + l288: + position, tokenIndex, depth = position286, tokenIndex286, depth286 + if buffer[position] != rune('\r') { + goto l284 + } + position++ + } + l286: + depth-- + add(RuleEndOfLine, position285) + } + return true + l284: + position, tokenIndex, depth = position284, tokenIndex284, depth284 + return false + }, + /* 37 EndOfFile <- */ + nil, + /* 38 Begin <- <('<' _)> */ + nil, + /* 39 End <- <('>' _)> */ + nil, + /* 41 Action0 <- <{ p.AddPackage(buffer[begin:end]) }> */ + nil, + /* 42 Action1 <- <{ p.AddYYSType(buffer[begin:end]) }> */ + nil, + /* 43 Action2 <- <{ p.AddLeg(buffer[begin:end]) }> */ + nil, + /* 44 Action3 <- <{ p.AddState(buffer[begin:end]) }> */ + nil, + nil, + /* 46 Action4 <- <{ p.AddDeclaration(buffer[begin:end]) }> */ + nil, + /* 47 Action5 <- <{ p.AddTrailer(buffer[begin:end]) }> */ + nil, + /* 48 Action6 <- <{ p.AddRule(buffer[begin:end]) }> */ + nil, + /* 49 Action7 <- <{ p.AddExpression() }> */ + nil, + /* 50 Action8 <- <{ p.AddAlternate() }> */ + nil, + /* 51 Action9 <- <{ p.AddNil(); p.AddAlternate() }> */ + nil, + /* 52 Action10 <- <{ p.AddNil() }> */ + nil, + /* 53 Action11 <- <{ p.AddSequence() }> */ + nil, + /* 54 Action12 <- <{ p.AddPredicate(buffer[begin:end]) }> */ + nil, + /* 55 Action13 <- <{ p.AddPeekFor() }> */ + nil, + /* 56 Action14 <- <{ p.AddPeekNot() }> */ + nil, + /* 57 Action15 <- <{ p.AddQuery() }> */ + nil, + /* 58 Action16 <- <{ p.AddStar() }> */ + nil, + /* 59 Action17 <- <{ p.AddPlus() }> */ + nil, + /* 60 Action18 <- <{ p.AddVariable(buffer[begin:end]) }> */ + nil, + /* 61 Action19 <- <{ p.AddName(buffer[begin:end]) }> */ + nil, + /* 62 Action20 <- <{ p.AddName(buffer[begin:end]) }> */ + nil, + /* 63 Action21 <- <{ p.AddDot() }> */ + nil, + /* 64 Action22 <- <{ p.AddAction(buffer[begin:end]) }> */ + nil, + /* 65 Action23 <- <{ p.AddPush() }> */ + nil, + /* 66 Action24 <- <{ p.AddSequence() }> */ + nil, + /* 67 Action25 <- <{ p.AddSequence() }> */ + nil, + /* 68 Action26 <- <{ p.AddPeekNot(); p.AddDot(); p.AddSequence() }> */ + nil, + /* 69 Action27 <- <{ p.AddPeekNot(); p.AddDot(); p.AddSequence() }> */ + nil, + /* 70 Action28 <- <{ p.AddAlternate() }> */ + nil, + /* 71 Action29 <- <{ p.AddAlternate() }> */ + nil, + /* 72 Action30 <- <{ p.AddRange() }> */ + nil, + /* 73 Action31 <- <{ p.AddDoubleRange() }> */ + nil, + /* 74 Action32 <- <{ p.AddCharacter(buffer[begin:end]) }> */ + nil, + /* 75 Action33 <- <{ p.AddDoubleCharacter(buffer[begin:end]) }> */ + nil, + /* 76 Action34 <- <{ p.AddCharacter(buffer[begin:end]) }> */ + nil, + /* 77 Action35 <- <{ p.AddCharacter("\a") }> */ + nil, + /* 78 Action36 <- <{ p.AddCharacter("\b") }> */ + nil, + /* 79 Action37 <- <{ p.AddCharacter("\x1B") }> */ + nil, + /* 80 Action38 <- <{ p.AddCharacter("\f") }> */ + nil, + /* 81 Action39 <- <{ p.AddCharacter("\n") }> */ + nil, + /* 82 Action40 <- <{ p.AddCharacter("\r") }> */ + nil, + /* 83 Action41 <- <{ p.AddCharacter("\t") }> */ + nil, + /* 84 Action42 <- <{ p.AddCharacter("\v") }> */ + nil, + /* 85 Action43 <- <{ p.AddCharacter("'") }> */ + nil, + /* 86 Action44 <- <{ p.AddCharacter("\"") }> */ + nil, + /* 87 Action45 <- <{ p.AddCharacter("[") }> */ + nil, + /* 88 Action46 <- <{ p.AddCharacter("]") }> */ + nil, + /* 89 Action47 <- <{ p.AddCharacter("-") }> */ + nil, + /* 90 Action48 <- <{ p.AddOctalCharacter(buffer[begin:end]) }> */ + nil, + /* 91 Action49 <- <{ p.AddOctalCharacter(buffer[begin:end]) }> */ + nil, + /* 92 Action50 <- <{ p.AddCharacter("\\") }> */ + nil, + } + p.rules = rules +} diff --git a/src/bootstrap/leg/leg.go b/src/bootstrap/leg/leg.go new file mode 120000 index 0000000..ea64921 --- /dev/null +++ b/src/bootstrap/leg/leg.go @@ -0,0 +1 @@ +../../leg/leg.go \ No newline at end of file diff --git a/bootstrap/leg/main.go b/src/bootstrap/leg/main.go similarity index 100% rename from bootstrap/leg/main.go rename to src/bootstrap/leg/main.go diff --git a/bootstrap/leg/set.go b/src/bootstrap/leg/set.go similarity index 100% rename from bootstrap/leg/set.go rename to src/bootstrap/leg/set.go diff --git a/src/leg/bootstrap.leg.go b/src/leg/bootstrap.leg.go new file mode 100644 index 0000000..77bacc5 --- /dev/null +++ b/src/leg/bootstrap.leg.go @@ -0,0 +1,3362 @@ +package main + +import ( + /*"bytes"*/ + "fmt" + "math" + "sort" + "strconv" +) + +const END_SYMBOL rune = 4 + +type YYSTYPE int + +/* The rule types inferred from the grammar are below. */ +type Rule uint8 + +const ( + RuleUnknown Rule = iota + RuleGrammar + RuleDeclaration + RuleTrailer + RuleDefinition + RuleExpression + RuleSequence + RulePrefix + RuleSuffix + RulePrimary + RuleIdentifier + RuleLiteral + RuleClass + RuleRanges + RuleDoubleRanges + RuleRange + RuleDoubleRange + RuleChar + RuleDoubleChar + RuleEscape + RuleAction + RuleBraces + RuleEqual + RuleColon + RuleBar + RuleAnd + RuleNot + RuleQuestion + RuleStar + RulePlus + RuleOpen + RuleClose + RuleDot + RuleRPERCENT + Rule_ + RuleComment + RuleSpace + RuleEndOfLine + RuleEndOfFile + RuleBegin + RuleEnd + RuleAction0 + RuleAction1 + RuleAction2 + RuleAction3 + RulePegText + RuleAction4 + RuleAction5 + RuleAction6 + RuleAction7 + RuleAction8 + RuleAction9 + RuleAction10 + RuleAction11 + RuleAction12 + RuleAction13 + RuleAction14 + RuleAction15 + RuleAction16 + RuleAction17 + RuleAction18 + RuleAction19 + RuleAction20 + RuleAction21 + RuleAction22 + RuleAction23 + RuleAction24 + RuleAction25 + RuleAction26 + RuleAction27 + RuleAction28 + RuleAction29 + RuleAction30 + RuleAction31 + RuleAction32 + RuleAction33 + RuleAction34 + RuleAction35 + RuleAction36 + RuleAction37 + RuleAction38 + RuleAction39 + RuleAction40 + RuleAction41 + RuleAction42 + RuleAction43 + RuleAction44 + RuleAction45 + RuleAction46 + RuleAction47 + RuleAction48 + RuleAction49 + RuleAction50 + + RuleActionPush + RuleActionPop + RulePre_ + Rule_In_ + Rule_Suf +) + +var Rul3s = [...]string{ + "Unknown", + "Grammar", + "Declaration", + "Trailer", + "Definition", + "Expression", + "Sequence", + "Prefix", + "Suffix", + "Primary", + "Identifier", + "Literal", + "Class", + "Ranges", + "DoubleRanges", + "Range", + "DoubleRange", + "Char", + "DoubleChar", + "Escape", + "Action", + "Braces", + "Equal", + "Colon", + "Bar", + "And", + "Not", + "Question", + "Star", + "Plus", + "Open", + "Close", + "Dot", + "RPERCENT", + "_", + "Comment", + "Space", + "EndOfLine", + "EndOfFile", + "Begin", + "End", + "Action0", + "Action1", + "Action2", + "Action3", + "PegText", + "Action4", + "Action5", + "Action6", + "Action7", + "Action8", + "Action9", + "Action10", + "Action11", + "Action12", + "Action13", + "Action14", + "Action15", + "Action16", + "Action17", + "Action18", + "Action19", + "Action20", + "Action21", + "Action22", + "Action23", + "Action24", + "Action25", + "Action26", + "Action27", + "Action28", + "Action29", + "Action30", + "Action31", + "Action32", + "Action33", + "Action34", + "Action35", + "Action36", + "Action37", + "Action38", + "Action39", + "Action40", + "Action41", + "Action42", + "Action43", + "Action44", + "Action45", + "Action46", + "Action47", + "Action48", + "Action49", + "Action50", + + "RuleActionPush", + "RuleActionPop", + "Pre_", + "_In_", + "_Suf", +} + +type TokenTree interface { + Print() + PrintSyntax() + PrintSyntaxTree(buffer string) + Add(rule Rule, begin, end, next, depth int) + Expand(index int) TokenTree + Tokens() <-chan token32 + Error() []token32 + trim(length int) +} + +/* ${@} bit structure for abstract syntax tree */ +type token16 struct { + Rule + begin, end, next int16 +} + +func (t *token16) isZero() bool { + return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 +} + +func (t *token16) isParentOf(u token16) bool { + return t.begin <= u.begin && t.end >= u.end && t.next > u.next +} + +func (t *token16) GetToken32() token32 { + return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} +} + +func (t *token16) String() string { + return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) +} + +type tokens16 struct { + tree []token16 + ordered [][]token16 +} + +func (t *tokens16) trim(length int) { + t.tree = t.tree[0:length] +} + +func (t *tokens16) Print() { + for _, token := range t.tree { + fmt.Println(token.String()) + } +} + +func (t *tokens16) Order() [][]token16 { + if t.ordered != nil { + return t.ordered + } + + depths := make([]int16, 1, math.MaxInt16) + for i, token := range t.tree { + if token.Rule == RuleUnknown { + t.tree = t.tree[:i] + break + } + depth := int(token.next) + if length := len(depths); depth >= length { + depths = depths[:depth+1] + } + depths[depth]++ + } + depths = append(depths, 0) + + ordered, pool := make([][]token16, len(depths)), make([]token16, len(t.tree)+len(depths)) + for i, depth := range depths { + depth++ + ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 + } + + for i, token := range t.tree { + depth := token.next + token.next = int16(i) + ordered[depth][depths[depth]] = token + depths[depth]++ + } + t.ordered = ordered + return ordered +} + +type State16 struct { + token16 + depths []int16 + leaf bool +} + +func (t *tokens16) PreOrder() (<-chan State16, [][]token16) { + s, ordered := make(chan State16, 6), t.Order() + go func() { + var states [8]State16 + for i, _ := range states { + states[i].depths = make([]int16, len(ordered)) + } + depths, state, depth := make([]int16, len(ordered)), 0, 1 + write := func(t token16, leaf bool) { + S := states[state] + state, S.Rule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.Rule, t.begin, t.end, int16(depth), leaf + copy(S.depths, depths) + s <- S + } + + states[state].token16 = ordered[0][0] + depths[0]++ + state++ + a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] + depthFirstSearch: + for { + for { + if i := depths[depth]; i > 0 { + if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && + (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { + if c.end != b.begin { + write(token16{Rule: Rule_In_, begin: c.end, end: b.begin}, true) + } + break + } + } + + if a.begin < b.begin { + write(token16{Rule: RulePre_, begin: a.begin, end: b.begin}, true) + } + break + } + + next := depth + 1 + if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { + write(b, false) + depths[depth]++ + depth, a, b = next, b, c + continue + } + + write(b, true) + depths[depth]++ + c, parent := ordered[depth][depths[depth]], true + for { + if c.Rule != RuleUnknown && a.isParentOf(c) { + b = c + continue depthFirstSearch + } else if parent && b.end != a.end { + write(token16{Rule: Rule_Suf, begin: b.end, end: a.end}, true) + } + + depth-- + if depth > 0 { + a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] + parent = a.isParentOf(b) + continue + } + + break depthFirstSearch + } + } + + close(s) + }() + return s, ordered +} + +func (t *tokens16) PrintSyntax() { + tokens, ordered := t.PreOrder() + max := -1 + for token := range tokens { + if !token.leaf { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) + } else if token.begin == token.end { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) + } else { + for c, end := token.begin, token.end; c < end; c++ { + if i := int(c); max+1 < i { + for j := max; j < i; j++ { + fmt.Printf("skip %v %v\n", j, token.String()) + } + max = i + } else if i := int(c); i <= max { + for j := i; j <= max; j++ { + fmt.Printf("dupe %v %v\n", j, token.String()) + } + } else { + max = int(c) + } + fmt.Printf("%v", c) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) + } + fmt.Printf("\n") + } + } +} + +func (t *tokens16) PrintSyntaxTree(buffer string) { + tokens, _ := t.PreOrder() + for token := range tokens { + for c := 0; c < int(token.next); c++ { + fmt.Printf(" ") + } + fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) + } +} + +func (t *tokens16) Add(rule Rule, begin, end, depth, index int) { + t.tree[index] = token16{Rule: rule, begin: int16(begin), end: int16(end), next: int16(depth)} +} + +func (t *tokens16) Tokens() <-chan token32 { + s := make(chan token32, 16) + go func() { + for _, v := range t.tree { + s <- v.GetToken32() + } + close(s) + }() + return s +} + +func (t *tokens16) Error() []token32 { + ordered := t.Order() + length := len(ordered) + tokens, length := make([]token32, length), length-1 + for i, _ := range tokens { + o := ordered[length-i] + if len(o) > 1 { + tokens[i] = o[len(o)-2].GetToken32() + } + } + return tokens +} + +/* ${@} bit structure for abstract syntax tree */ +type token32 struct { + Rule + begin, end, next int32 +} + +func (t *token32) isZero() bool { + return t.Rule == RuleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 +} + +func (t *token32) isParentOf(u token32) bool { + return t.begin <= u.begin && t.end >= u.end && t.next > u.next +} + +func (t *token32) GetToken32() token32 { + return token32{Rule: t.Rule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} +} + +func (t *token32) String() string { + return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", Rul3s[t.Rule], t.begin, t.end, t.next) +} + +type tokens32 struct { + tree []token32 + ordered [][]token32 +} + +func (t *tokens32) trim(length int) { + t.tree = t.tree[0:length] +} + +func (t *tokens32) Print() { + for _, token := range t.tree { + fmt.Println(token.String()) + } +} + +func (t *tokens32) Order() [][]token32 { + if t.ordered != nil { + return t.ordered + } + + depths := make([]int32, 1, math.MaxInt16) + for i, token := range t.tree { + if token.Rule == RuleUnknown { + t.tree = t.tree[:i] + break + } + depth := int(token.next) + if length := len(depths); depth >= length { + depths = depths[:depth+1] + } + depths[depth]++ + } + depths = append(depths, 0) + + ordered, pool := make([][]token32, len(depths)), make([]token32, len(t.tree)+len(depths)) + for i, depth := range depths { + depth++ + ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 + } + + for i, token := range t.tree { + depth := token.next + token.next = int32(i) + ordered[depth][depths[depth]] = token + depths[depth]++ + } + t.ordered = ordered + return ordered +} + +type State32 struct { + token32 + depths []int32 + leaf bool +} + +func (t *tokens32) PreOrder() (<-chan State32, [][]token32) { + s, ordered := make(chan State32, 6), t.Order() + go func() { + var states [8]State32 + for i, _ := range states { + states[i].depths = make([]int32, len(ordered)) + } + depths, state, depth := make([]int32, len(ordered)), 0, 1 + write := func(t token32, leaf bool) { + S := states[state] + state, S.Rule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.Rule, t.begin, t.end, int32(depth), leaf + copy(S.depths, depths) + s <- S + } + + states[state].token32 = ordered[0][0] + depths[0]++ + state++ + a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] + depthFirstSearch: + for { + for { + if i := depths[depth]; i > 0 { + if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && + (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { + if c.end != b.begin { + write(token32{Rule: Rule_In_, begin: c.end, end: b.begin}, true) + } + break + } + } + + if a.begin < b.begin { + write(token32{Rule: RulePre_, begin: a.begin, end: b.begin}, true) + } + break + } + + next := depth + 1 + if c := ordered[next][depths[next]]; c.Rule != RuleUnknown && b.isParentOf(c) { + write(b, false) + depths[depth]++ + depth, a, b = next, b, c + continue + } + + write(b, true) + depths[depth]++ + c, parent := ordered[depth][depths[depth]], true + for { + if c.Rule != RuleUnknown && a.isParentOf(c) { + b = c + continue depthFirstSearch + } else if parent && b.end != a.end { + write(token32{Rule: Rule_Suf, begin: b.end, end: a.end}, true) + } + + depth-- + if depth > 0 { + a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] + parent = a.isParentOf(b) + continue + } + + break depthFirstSearch + } + } + + close(s) + }() + return s, ordered +} + +func (t *tokens32) PrintSyntax() { + tokens, ordered := t.PreOrder() + max := -1 + for token := range tokens { + if !token.leaf { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[36m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[36m%v\x1B[m\n", Rul3s[token.Rule]) + } else if token.begin == token.end { + fmt.Printf("%v", token.begin) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[31m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[31m%v\x1B[m\n", Rul3s[token.Rule]) + } else { + for c, end := token.begin, token.end; c < end; c++ { + if i := int(c); max+1 < i { + for j := max; j < i; j++ { + fmt.Printf("skip %v %v\n", j, token.String()) + } + max = i + } else if i := int(c); i <= max { + for j := i; j <= max; j++ { + fmt.Printf("dupe %v %v\n", j, token.String()) + } + } else { + max = int(c) + } + fmt.Printf("%v", c) + for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { + fmt.Printf(" \x1B[34m%v\x1B[m", Rul3s[ordered[i][depths[i]-1].Rule]) + } + fmt.Printf(" \x1B[34m%v\x1B[m\n", Rul3s[token.Rule]) + } + fmt.Printf("\n") + } + } +} + +func (t *tokens32) PrintSyntaxTree(buffer string) { + tokens, _ := t.PreOrder() + for token := range tokens { + for c := 0; c < int(token.next); c++ { + fmt.Printf(" ") + } + fmt.Printf("\x1B[34m%v\x1B[m %v\n", Rul3s[token.Rule], strconv.Quote(buffer[token.begin:token.end])) + } +} + +func (t *tokens32) Add(rule Rule, begin, end, depth, index int) { + t.tree[index] = token32{Rule: rule, begin: int32(begin), end: int32(end), next: int32(depth)} +} + +func (t *tokens32) Tokens() <-chan token32 { + s := make(chan token32, 16) + go func() { + for _, v := range t.tree { + s <- v.GetToken32() + } + close(s) + }() + return s +} + +func (t *tokens32) Error() []token32 { + ordered := t.Order() + length := len(ordered) + tokens, length := make([]token32, length), length-1 + for i, _ := range tokens { + o := ordered[length-i] + if len(o) > 1 { + tokens[i] = o[len(o)-2].GetToken32() + } + } + return tokens +} + +func (t *tokens16) Expand(index int) TokenTree { + tree := t.tree + if index >= len(tree) { + expanded := make([]token32, 2*len(tree)) + for i, v := range tree { + expanded[i] = v.GetToken32() + } + return &tokens32{tree: expanded} + } + return nil +} + +func (t *tokens32) Expand(index int) TokenTree { + tree := t.tree + if index >= len(tree) { + expanded := make([]token32, 2*len(tree)) + copy(expanded, tree) + t.tree = expanded + } + return nil +} + +type Leg struct { + *Tree + + Buffer string + buffer []rune + rules [93]func() bool + Parse func(rule ...int) error + Reset func() + TokenTree +} + +type textPosition struct { + line, symbol int +} + +type textPositionMap map[int]textPosition + +func translatePositions(buffer string, positions []int) textPositionMap { + length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 + sort.Ints(positions) + +search: + for i, c := range buffer[0:] { + if c == '\n' { + line, symbol = line+1, 0 + } else { + symbol++ + } + if i == positions[j] { + translations[positions[j]] = textPosition{line, symbol} + for j++; j < length; j++ { + if i != positions[j] { + continue search + } + } + break search + } + } + + return translations +} + +type parseError struct { + p *Leg +} + +func (e *parseError) Error() string { + tokens, error := e.p.TokenTree.Error(), "\n" + positions, p := make([]int, 2*len(tokens)), 0 + for _, token := range tokens { + positions[p], p = int(token.begin), p+1 + positions[p], p = int(token.end), p+1 + } + translations := translatePositions(e.p.Buffer, positions) + for _, token := range tokens { + begin, end := int(token.begin), int(token.end) + error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", + Rul3s[token.Rule], + translations[begin].line, translations[begin].symbol, + translations[end].line, translations[end].symbol, + /*strconv.Quote(*/ e.p.Buffer[begin:end] /*)*/) + } + + return error +} + +func (p *Leg) PrintSyntaxTree() { + p.TokenTree.PrintSyntaxTree(p.Buffer) +} + +func (p *Leg) Highlighter() { + p.TokenTree.PrintSyntax() +} + +func (p *Leg) Execute() { + buffer, begin, end := p.Buffer, 0, 0 + + for token := range p.TokenTree.Tokens() { + switch token.Rule { + case RulePegText: + begin, end = int(token.begin), int(token.end) + case RuleAction0: + p.AddPackage(buffer[begin:end]) + case RuleAction1: + p.AddYYSType(buffer[begin:end]) + case RuleAction2: + p.AddLeg(buffer[begin:end]) + case RuleAction3: + p.AddState(buffer[begin:end]) + case RuleAction4: + p.AddDeclaration(buffer[begin:end]) + case RuleAction5: + p.AddTrailer(buffer[begin:end]) + case RuleAction6: + p.AddRule(buffer[begin:end]) + case RuleAction7: + p.AddExpression() + case RuleAction8: + p.AddAlternate() + case RuleAction9: + p.AddNil() + p.AddAlternate() + case RuleAction10: + p.AddNil() + case RuleAction11: + p.AddSequence() + case RuleAction12: + p.AddPredicate(buffer[begin:end]) + case RuleAction13: + p.AddPeekFor() + case RuleAction14: + p.AddPeekNot() + case RuleAction15: + p.AddQuery() + case RuleAction16: + p.AddStar() + case RuleAction17: + p.AddPlus() + case RuleAction18: + p.AddVariable(buffer[begin:end]) + case RuleAction19: + p.AddName(buffer[begin:end]) + case RuleAction20: + p.AddName(buffer[begin:end]) + case RuleAction21: + p.AddDot() + case RuleAction22: + p.AddAction(buffer[begin:end]) + case RuleAction23: + p.AddPush() + case RuleAction24: + p.AddSequence() + case RuleAction25: + p.AddSequence() + case RuleAction26: + p.AddPeekNot() + p.AddDot() + p.AddSequence() + case RuleAction27: + p.AddPeekNot() + p.AddDot() + p.AddSequence() + case RuleAction28: + p.AddAlternate() + case RuleAction29: + p.AddAlternate() + case RuleAction30: + p.AddRange() + case RuleAction31: + p.AddDoubleRange() + case RuleAction32: + p.AddCharacter(buffer[begin:end]) + case RuleAction33: + p.AddDoubleCharacter(buffer[begin:end]) + case RuleAction34: + p.AddCharacter(buffer[begin:end]) + case RuleAction35: + p.AddCharacter("\a") + case RuleAction36: + p.AddCharacter("\b") + case RuleAction37: + p.AddCharacter("\x1B") + case RuleAction38: + p.AddCharacter("\f") + case RuleAction39: + p.AddCharacter("\n") + case RuleAction40: + p.AddCharacter("\r") + case RuleAction41: + p.AddCharacter("\t") + case RuleAction42: + p.AddCharacter("\v") + case RuleAction43: + p.AddCharacter("'") + case RuleAction44: + p.AddCharacter("\"") + case RuleAction45: + p.AddCharacter("[") + case RuleAction46: + p.AddCharacter("]") + case RuleAction47: + p.AddCharacter("-") + case RuleAction48: + p.AddOctalCharacter(buffer[begin:end]) + case RuleAction49: + p.AddOctalCharacter(buffer[begin:end]) + case RuleAction50: + p.AddCharacter("\\") + + } + } +} + +func (p *Leg) Init() { + p.buffer = []rune(p.Buffer) + if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != END_SYMBOL { + p.buffer = append(p.buffer, END_SYMBOL) + } + + var tree TokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} + position, depth, tokenIndex, buffer, rules := 0, 0, 0, p.buffer, p.rules + + p.Parse = func(rule ...int) error { + r := 1 + if len(rule) > 0 { + r = rule[0] + } + matches := p.rules[r]() + p.TokenTree = tree + if matches { + p.TokenTree.trim(tokenIndex) + return nil + } + return &parseError{p} + } + + p.Reset = func() { + position, tokenIndex, depth = 0, 0, 0 + } + + add := func(rule Rule, begin int) { + if t := tree.Expand(tokenIndex); t != nil { + tree = t + } + tree.Add(rule, begin, position, depth, tokenIndex) + tokenIndex++ + } + + matchDot := func() bool { + if buffer[position] != END_SYMBOL { + position++ + return true + } + return false + } + + /*matchChar := func(c byte) bool { + if buffer[position] == c { + position++ + return true + } + return false + }*/ + + /*matchRange := func(lower byte, upper byte) bool { + if c := buffer[position]; c >= lower && c <= upper { + position++ + return true + } + return false + }*/ + + rules = [...]func() bool{ + nil, + /* 0 Grammar <- <(_ ('p' 'a' 'c' 'k' 'a' 'g' 'e') _ Identifier Action0 ('Y' 'Y' 'S' 'T' 'Y' 'P' 'E') _ Identifier Action1 ('t' 'y' 'p' 'e') _ Identifier Action2 ('P' 'e' 'g') _ Action Action3 (Declaration / Definition)+ Trailer? EndOfFile)> */ + func() bool { + position0, tokenIndex0, depth0 := position, tokenIndex, depth + { + + position1 := position + depth++ + if !rules[Rule_]() { + goto l0 + } + if buffer[position] != rune('p') { + goto l0 + } + position++ + if buffer[position] != rune('a') { + goto l0 + } + position++ + if buffer[position] != rune('c') { + goto l0 + } + position++ + if buffer[position] != rune('k') { + goto l0 + } + position++ + if buffer[position] != rune('a') { + goto l0 + } + position++ + if buffer[position] != rune('g') { + goto l0 + } + position++ + if buffer[position] != rune('e') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction0, position) + } + if buffer[position] != rune('Y') { + goto l0 + } + position++ + if buffer[position] != rune('Y') { + goto l0 + } + position++ + if buffer[position] != rune('S') { + goto l0 + } + position++ + if buffer[position] != rune('T') { + goto l0 + } + position++ + if buffer[position] != rune('Y') { + goto l0 + } + position++ + if buffer[position] != rune('P') { + goto l0 + } + position++ + if buffer[position] != rune('E') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction1, position) + } + if buffer[position] != rune('t') { + goto l0 + } + position++ + if buffer[position] != rune('y') { + goto l0 + } + position++ + if buffer[position] != rune('p') { + goto l0 + } + position++ + if buffer[position] != rune('e') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction2, position) + } + if buffer[position] != rune('P') { + goto l0 + } + position++ + if buffer[position] != rune('e') { + goto l0 + } + position++ + if buffer[position] != rune('g') { + goto l0 + } + position++ + if !rules[Rule_]() { + goto l0 + } + if !rules[RuleAction]() { + goto l0 + } + { + + add(RuleAction3, position) + } + { + + position8, tokenIndex8, depth8 := position, tokenIndex, depth + { + + position10 := position + depth++ + { + + position11 := position + depth++ + if buffer[position] != rune('%') { + goto l9 + } + position++ + if buffer[position] != rune('{') { + goto l9 + } + position++ + depth-- + add(RulePegText, position11) + } + { + + position12 := position + depth++ + l13: + { + + position14, tokenIndex14, depth14 := position, tokenIndex, depth + { + + position15, tokenIndex15, depth15 := position, tokenIndex, depth + { + + position16 := position + depth++ + if buffer[position] != rune('%') { + goto l15 + } + position++ + if buffer[position] != rune('}') { + goto l15 + } + position++ + depth-- + add(RulePegText, position16) + } + goto l14 + l15: + position, tokenIndex, depth = position15, tokenIndex15, depth15 + } + if !matchDot() { + goto l14 + } + goto l13 + l14: + position, tokenIndex, depth = position14, tokenIndex14, depth14 + } + depth-- + add(RulePegText, position12) + } + { + + position17 := position + depth++ + if buffer[position] != rune('%') { + goto l9 + } + position++ + if buffer[position] != rune('}') { + goto l9 + } + position++ + if !rules[Rule_]() { + goto l9 + } + depth-- + add(RuleRPERCENT, position17) + } + { + + add(RuleAction4, position) + } + depth-- + add(RuleDeclaration, position10) + } + goto l8 + l9: + position, tokenIndex, depth = position8, tokenIndex8, depth8 + { + + position19 := position + depth++ + if !rules[RuleIdentifier]() { + goto l0 + } + { + + add(RuleAction6, position) + } + if !rules[RuleEqual]() { + goto l0 + } + if !rules[RuleExpression]() { + goto l0 + } + { + + add(RuleAction7, position) + } + depth-- + add(RuleDefinition, position19) + } + } + l8: + l6: + { + + position7, tokenIndex7, depth7 := position, tokenIndex, depth + { + + position22, tokenIndex22, depth22 := position, tokenIndex, depth + { + + position24 := position + depth++ + { + + position25 := position + depth++ + if buffer[position] != rune('%') { + goto l23 + } + position++ + if buffer[position] != rune('{') { + goto l23 + } + position++ + depth-- + add(RulePegText, position25) + } + { + + position26 := position + depth++ + l27: + { + + position28, tokenIndex28, depth28 := position, tokenIndex, depth + { + + position29, tokenIndex29, depth29 := position, tokenIndex, depth + { + + position30 := position + depth++ + if buffer[position] != rune('%') { + goto l29 + } + position++ + if buffer[position] != rune('}') { + goto l29 + } + position++ + depth-- + add(RulePegText, position30) + } + goto l28 + l29: + position, tokenIndex, depth = position29, tokenIndex29, depth29 + } + if !matchDot() { + goto l28 + } + goto l27 + l28: + position, tokenIndex, depth = position28, tokenIndex28, depth28 + } + depth-- + add(RulePegText, position26) + } + { + + position31 := position + depth++ + if buffer[position] != rune('%') { + goto l23 + } + position++ + if buffer[position] != rune('}') { + goto l23 + } + position++ + if !rules[Rule_]() { + goto l23 + } + depth-- + add(RuleRPERCENT, position31) + } + { + + add(RuleAction4, position) + } + depth-- + add(RuleDeclaration, position24) + } + goto l22 + l23: + position, tokenIndex, depth = position22, tokenIndex22, depth22 + { + + position33 := position + depth++ + if !rules[RuleIdentifier]() { + goto l7 + } + { + + add(RuleAction6, position) + } + if !rules[RuleEqual]() { + goto l7 + } + if !rules[RuleExpression]() { + goto l7 + } + { + + add(RuleAction7, position) + } + depth-- + add(RuleDefinition, position33) + } + } + l22: + goto l6 + l7: + position, tokenIndex, depth = position7, tokenIndex7, depth7 + } + { + + position36, tokenIndex36, depth36 := position, tokenIndex, depth + { + + position38 := position + depth++ + if buffer[position] != rune('%') { + goto l36 + } + position++ + if buffer[position] != rune('%') { + goto l36 + } + position++ + { + + position39 := position + depth++ + l40: + { + + position41, tokenIndex41, depth41 := position, tokenIndex, depth + if !matchDot() { + goto l41 + } + goto l40 + l41: + position, tokenIndex, depth = position41, tokenIndex41, depth41 + } + depth-- + add(RulePegText, position39) + } + { + + add(RuleAction5, position) + } + depth-- + add(RuleTrailer, position38) + } + goto l37 + l36: + position, tokenIndex, depth = position36, tokenIndex36, depth36 + } + l37: + { + + position43 := position + depth++ + { + + position44, tokenIndex44, depth44 := position, tokenIndex, depth + if !matchDot() { + goto l44 + } + goto l0 + l44: + position, tokenIndex, depth = position44, tokenIndex44, depth44 + } + depth-- + add(RuleEndOfFile, position43) + } + depth-- + add(RuleGrammar, position1) + } + return true + l0: + position, tokenIndex, depth = position0, tokenIndex0, depth0 + return false + }, + /* 1 Declaration <- <(<('%' '{')> <(!<('%' '}')> .)*> RPERCENT Action4)> */ + nil, + /* 2 Trailer <- <('%' '%' (<.*> Action5))> */ + nil, + /* 3 Definition <- <(Identifier Action6 Equal Expression Action7)> */ + nil, + /* 4 Expression <- <((Sequence (Bar Sequence Action8)* (Bar Action9)?) / Action10)> */ + func() bool { + { + + position49 := position + depth++ + { + + position50, tokenIndex50, depth50 := position, tokenIndex, depth + if !rules[RuleSequence]() { + goto l51 + } + l52: + { + + position53, tokenIndex53, depth53 := position, tokenIndex, depth + if !rules[RuleBar]() { + goto l53 + } + if !rules[RuleSequence]() { + goto l53 + } + { + + add(RuleAction8, position) + } + goto l52 + l53: + position, tokenIndex, depth = position53, tokenIndex53, depth53 + } + { + + position55, tokenIndex55, depth55 := position, tokenIndex, depth + if !rules[RuleBar]() { + goto l55 + } + { + + add(RuleAction9, position) + } + goto l56 + l55: + position, tokenIndex, depth = position55, tokenIndex55, depth55 + } + l56: + goto l50 + l51: + position, tokenIndex, depth = position50, tokenIndex50, depth50 + { + + add(RuleAction10, position) + } + } + l50: + depth-- + add(RuleExpression, position49) + } + return true + }, + /* 5 Sequence <- <(Prefix (Prefix Action11)*)> */ + func() bool { + position59, tokenIndex59, depth59 := position, tokenIndex, depth + { + + position60 := position + depth++ + if !rules[RulePrefix]() { + goto l59 + } + l61: + { + + position62, tokenIndex62, depth62 := position, tokenIndex, depth + if !rules[RulePrefix]() { + goto l62 + } + { + + add(RuleAction11, position) + } + goto l61 + l62: + position, tokenIndex, depth = position62, tokenIndex62, depth62 + } + depth-- + add(RuleSequence, position60) + } + return true + l59: + position, tokenIndex, depth = position59, tokenIndex59, depth59 + return false + }, + /* 6 Prefix <- <((And Action Action12) / ((&('!') (Not Suffix Action14)) | (&('&') (And Suffix Action13)) | (&('"' | '\'' | '(' | '-' | '.' | '<' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[' | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{') Suffix)))> */ + func() bool { + position64, tokenIndex64, depth64 := position, tokenIndex, depth + { + + position65 := position + depth++ + { + + position66, tokenIndex66, depth66 := position, tokenIndex, depth + if !rules[RuleAnd]() { + goto l67 + } + if !rules[RuleAction]() { + goto l67 + } + { + + add(RuleAction12, position) + } + goto l66 + l67: + position, tokenIndex, depth = position66, tokenIndex66, depth66 + { + + switch buffer[position] { + case '!': + { + + position70 := position + depth++ + if buffer[position] != rune('!') { + goto l64 + } + position++ + if !rules[Rule_]() { + goto l64 + } + depth-- + add(RuleNot, position70) + } + if !rules[RuleSuffix]() { + goto l64 + } + { + + add(RuleAction14, position) + } + break + case '&': + if !rules[RuleAnd]() { + goto l64 + } + if !rules[RuleSuffix]() { + goto l64 + } + { + + add(RuleAction13, position) + } + break + default: + if !rules[RuleSuffix]() { + goto l64 + } + break + } + } + + } + l66: + depth-- + add(RulePrefix, position65) + } + return true + l64: + position, tokenIndex, depth = position64, tokenIndex64, depth64 + return false + }, + /* 7 Suffix <- <(Primary ((&('+') (Plus Action17)) | (&('*') (Star Action16)) | (&('?') (Question Action15)))?)> */ + func() bool { + position73, tokenIndex73, depth73 := position, tokenIndex, depth + { + + position74 := position + depth++ + { + + position75 := position + depth++ + { + + position76, tokenIndex76, depth76 := position, tokenIndex, depth + if !rules[RuleIdentifier]() { + goto l77 + } + { + + add(RuleAction18, position) + } + { + + position79 := position + depth++ + if buffer[position] != rune(':') { + goto l77 + } + position++ + if !rules[Rule_]() { + goto l77 + } + depth-- + add(RuleColon, position79) + } + if !rules[RuleIdentifier]() { + goto l77 + } + { + + position80, tokenIndex80, depth80 := position, tokenIndex, depth + if !rules[RuleEqual]() { + goto l80 + } + goto l77 + l80: + position, tokenIndex, depth = position80, tokenIndex80, depth80 + } + { + + add(RuleAction19, position) + } + goto l76 + l77: + position, tokenIndex, depth = position76, tokenIndex76, depth76 + { + + switch buffer[position] { + case '<': + { + + position83 := position + depth++ + if buffer[position] != rune('<') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleBegin, position83) + } + if !rules[RuleExpression]() { + goto l73 + } + { + + position84 := position + depth++ + if buffer[position] != rune('>') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleEnd, position84) + } + { + + add(RuleAction23, position) + } + break + case '{': + if !rules[RuleAction]() { + goto l73 + } + { + + add(RuleAction22, position) + } + break + case '.': + { + + position87 := position + depth++ + if buffer[position] != rune('.') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleDot, position87) + } + { + + add(RuleAction21, position) + } + break + case '[': + { + + position89 := position + depth++ + { + + position90, tokenIndex90, depth90 := position, tokenIndex, depth + if buffer[position] != rune('[') { + goto l91 + } + position++ + if buffer[position] != rune('[') { + goto l91 + } + position++ + { + + position92, tokenIndex92, depth92 := position, tokenIndex, depth + { + + position94, tokenIndex94, depth94 := position, tokenIndex, depth + if buffer[position] != rune('^') { + goto l95 + } + position++ + if !rules[RuleDoubleRanges]() { + goto l95 + } + { + + add(RuleAction26, position) + } + goto l94 + l95: + position, tokenIndex, depth = position94, tokenIndex94, depth94 + if !rules[RuleDoubleRanges]() { + goto l92 + } + } + l94: + goto l93 + l92: + position, tokenIndex, depth = position92, tokenIndex92, depth92 + } + l93: + if buffer[position] != rune(']') { + goto l91 + } + position++ + if buffer[position] != rune(']') { + goto l91 + } + position++ + goto l90 + l91: + position, tokenIndex, depth = position90, tokenIndex90, depth90 + if buffer[position] != rune('[') { + goto l73 + } + position++ + { + + position97, tokenIndex97, depth97 := position, tokenIndex, depth + { + + position99, tokenIndex99, depth99 := position, tokenIndex, depth + if buffer[position] != rune('^') { + goto l100 + } + position++ + if !rules[RuleRanges]() { + goto l100 + } + { + + add(RuleAction27, position) + } + goto l99 + l100: + position, tokenIndex, depth = position99, tokenIndex99, depth99 + if !rules[RuleRanges]() { + goto l97 + } + } + l99: + goto l98 + l97: + position, tokenIndex, depth = position97, tokenIndex97, depth97 + } + l98: + if buffer[position] != rune(']') { + goto l73 + } + position++ + } + l90: + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleClass, position89) + } + break + case '"', '\'': + { + + position102 := position + depth++ + { + + position103, tokenIndex103, depth103 := position, tokenIndex, depth + if buffer[position] != rune('\'') { + goto l104 + } + position++ + { + + position105, tokenIndex105, depth105 := position, tokenIndex, depth + { + + position107, tokenIndex107, depth107 := position, tokenIndex, depth + if buffer[position] != rune('\'') { + goto l107 + } + position++ + goto l105 + l107: + position, tokenIndex, depth = position107, tokenIndex107, depth107 + } + if !rules[RuleChar]() { + goto l105 + } + goto l106 + l105: + position, tokenIndex, depth = position105, tokenIndex105, depth105 + } + l106: + l108: + { + + position109, tokenIndex109, depth109 := position, tokenIndex, depth + { + + position110, tokenIndex110, depth110 := position, tokenIndex, depth + if buffer[position] != rune('\'') { + goto l110 + } + position++ + goto l109 + l110: + position, tokenIndex, depth = position110, tokenIndex110, depth110 + } + if !rules[RuleChar]() { + goto l109 + } + { + + add(RuleAction24, position) + } + goto l108 + l109: + position, tokenIndex, depth = position109, tokenIndex109, depth109 + } + if buffer[position] != rune('\'') { + goto l104 + } + position++ + if !rules[Rule_]() { + goto l104 + } + goto l103 + l104: + position, tokenIndex, depth = position103, tokenIndex103, depth103 + if buffer[position] != rune('"') { + goto l73 + } + position++ + { + + position112, tokenIndex112, depth112 := position, tokenIndex, depth + { + + position114, tokenIndex114, depth114 := position, tokenIndex, depth + if buffer[position] != rune('"') { + goto l114 + } + position++ + goto l112 + l114: + position, tokenIndex, depth = position114, tokenIndex114, depth114 + } + if !rules[RuleDoubleChar]() { + goto l112 + } + goto l113 + l112: + position, tokenIndex, depth = position112, tokenIndex112, depth112 + } + l113: + l115: + { + + position116, tokenIndex116, depth116 := position, tokenIndex, depth + { + + position117, tokenIndex117, depth117 := position, tokenIndex, depth + if buffer[position] != rune('"') { + goto l117 + } + position++ + goto l116 + l117: + position, tokenIndex, depth = position117, tokenIndex117, depth117 + } + if !rules[RuleDoubleChar]() { + goto l116 + } + { + + add(RuleAction25, position) + } + goto l115 + l116: + position, tokenIndex, depth = position116, tokenIndex116, depth116 + } + if buffer[position] != rune('"') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + } + l103: + depth-- + add(RuleLiteral, position102) + } + break + case '(': + { + + position119 := position + depth++ + if buffer[position] != rune('(') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleOpen, position119) + } + if !rules[RuleExpression]() { + goto l73 + } + { + + position120 := position + depth++ + if buffer[position] != rune(')') { + goto l73 + } + position++ + if !rules[Rule_]() { + goto l73 + } + depth-- + add(RuleClose, position120) + } + break + default: + if !rules[RuleIdentifier]() { + goto l73 + } + { + + position121, tokenIndex121, depth121 := position, tokenIndex, depth + if !rules[RuleEqual]() { + goto l121 + } + goto l73 + l121: + position, tokenIndex, depth = position121, tokenIndex121, depth121 + } + { + + add(RuleAction20, position) + } + break + } + } + + } + l76: + depth-- + add(RulePrimary, position75) + } + { + + position123, tokenIndex123, depth123 := position, tokenIndex, depth + { + + switch buffer[position] { + case '+': + { + + position126 := position + depth++ + if buffer[position] != rune('+') { + goto l123 + } + position++ + if !rules[Rule_]() { + goto l123 + } + depth-- + add(RulePlus, position126) + } + { + + add(RuleAction17, position) + } + break + case '*': + { + + position128 := position + depth++ + if buffer[position] != rune('*') { + goto l123 + } + position++ + if !rules[Rule_]() { + goto l123 + } + depth-- + add(RuleStar, position128) + } + { + + add(RuleAction16, position) + } + break + default: + { + + position130 := position + depth++ + if buffer[position] != rune('?') { + goto l123 + } + position++ + if !rules[Rule_]() { + goto l123 + } + depth-- + add(RuleQuestion, position130) + } + { + + add(RuleAction15, position) + } + break + } + } + + goto l124 + l123: + position, tokenIndex, depth = position123, tokenIndex123, depth123 + } + l124: + depth-- + add(RuleSuffix, position74) + } + return true + l73: + position, tokenIndex, depth = position73, tokenIndex73, depth73 + return false + }, + /* 8 Primary <- <((Identifier Action18 Colon Identifier !Equal Action19) / ((&('<') (Begin Expression End Action23)) | (&('{') (Action Action22)) | (&('.') (Dot Action21)) | (&('[') Class) | (&('"' | '\'') Literal) | (&('(') (Open Expression Close)) | (&('-' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') (Identifier !Equal Action20))))> */ + nil, + /* 9 Identifier <- <(<(((&('_') '_') | (&('-') '-') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') ([a-z] / [A-Z]))) ((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('-') '-') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') ([a-z] / [A-Z])))*)> _)> */ + func() bool { + position133, tokenIndex133, depth133 := position, tokenIndex, depth + { + + position134 := position + depth++ + { + + position135 := position + depth++ + { + + switch buffer[position] { + case '_': + if buffer[position] != rune('_') { + goto l133 + } + position++ + break + case '-': + if buffer[position] != rune('-') { + goto l133 + } + position++ + break + default: + { + + position137, tokenIndex137, depth137 := position, tokenIndex, depth + if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l138 + } + position++ + goto l137 + l138: + position, tokenIndex, depth = position137, tokenIndex137, depth137 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l133 + } + position++ + } + l137: + break + } + } + + l139: + { + + position140, tokenIndex140, depth140 := position, tokenIndex, depth + { + + switch buffer[position] { + case '_': + if buffer[position] != rune('_') { + goto l140 + } + position++ + break + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l140 + } + position++ + break + case '-': + if buffer[position] != rune('-') { + goto l140 + } + position++ + break + default: + { + + position142, tokenIndex142, depth142 := position, tokenIndex, depth + if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l143 + } + position++ + goto l142 + l143: + position, tokenIndex, depth = position142, tokenIndex142, depth142 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l140 + } + position++ + } + l142: + break + } + } + + goto l139 + l140: + position, tokenIndex, depth = position140, tokenIndex140, depth140 + } + depth-- + add(RulePegText, position135) + } + if !rules[Rule_]() { + goto l133 + } + depth-- + add(RuleIdentifier, position134) + } + return true + l133: + position, tokenIndex, depth = position133, tokenIndex133, depth133 + return false + }, + /* 10 Literal <- <(('\'' (!'\'' Char)? (!'\'' Char Action24)* '\'' _) / ('"' (!'"' DoubleChar)? (!'"' DoubleChar Action25)* '"' _))> */ + nil, + /* 11 Class <- <((('[' '[' (('^' DoubleRanges Action26) / DoubleRanges)? (']' ']')) / ('[' (('^' Ranges Action27) / Ranges)? ']')) _)> */ + nil, + /* 12 Ranges <- <(!']' Range (!']' Range Action28)*)> */ + func() bool { + position146, tokenIndex146, depth146 := position, tokenIndex, depth + { + + position147 := position + depth++ + { + + position148, tokenIndex148, depth148 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l148 + } + position++ + goto l146 + l148: + position, tokenIndex, depth = position148, tokenIndex148, depth148 + } + if !rules[RuleRange]() { + goto l146 + } + l149: + { + + position150, tokenIndex150, depth150 := position, tokenIndex, depth + { + + position151, tokenIndex151, depth151 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l151 + } + position++ + goto l150 + l151: + position, tokenIndex, depth = position151, tokenIndex151, depth151 + } + if !rules[RuleRange]() { + goto l150 + } + { + + add(RuleAction28, position) + } + goto l149 + l150: + position, tokenIndex, depth = position150, tokenIndex150, depth150 + } + depth-- + add(RuleRanges, position147) + } + return true + l146: + position, tokenIndex, depth = position146, tokenIndex146, depth146 + return false + }, + /* 13 DoubleRanges <- <(!(']' ']') DoubleRange (!(']' ']') DoubleRange Action29)*)> */ + func() bool { + position153, tokenIndex153, depth153 := position, tokenIndex, depth + { + + position154 := position + depth++ + { + + position155, tokenIndex155, depth155 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l155 + } + position++ + if buffer[position] != rune(']') { + goto l155 + } + position++ + goto l153 + l155: + position, tokenIndex, depth = position155, tokenIndex155, depth155 + } + if !rules[RuleDoubleRange]() { + goto l153 + } + l156: + { + + position157, tokenIndex157, depth157 := position, tokenIndex, depth + { + + position158, tokenIndex158, depth158 := position, tokenIndex, depth + if buffer[position] != rune(']') { + goto l158 + } + position++ + if buffer[position] != rune(']') { + goto l158 + } + position++ + goto l157 + l158: + position, tokenIndex, depth = position158, tokenIndex158, depth158 + } + if !rules[RuleDoubleRange]() { + goto l157 + } + { + + add(RuleAction29, position) + } + goto l156 + l157: + position, tokenIndex, depth = position157, tokenIndex157, depth157 + } + depth-- + add(RuleDoubleRanges, position154) + } + return true + l153: + position, tokenIndex, depth = position153, tokenIndex153, depth153 + return false + }, + /* 14 Range <- <((Char '-' Char Action30) / Char)> */ + func() bool { + position160, tokenIndex160, depth160 := position, tokenIndex, depth + { + + position161 := position + depth++ + { + + position162, tokenIndex162, depth162 := position, tokenIndex, depth + if !rules[RuleChar]() { + goto l163 + } + if buffer[position] != rune('-') { + goto l163 + } + position++ + if !rules[RuleChar]() { + goto l163 + } + { + + add(RuleAction30, position) + } + goto l162 + l163: + position, tokenIndex, depth = position162, tokenIndex162, depth162 + if !rules[RuleChar]() { + goto l160 + } + } + l162: + depth-- + add(RuleRange, position161) + } + return true + l160: + position, tokenIndex, depth = position160, tokenIndex160, depth160 + return false + }, + /* 15 DoubleRange <- <((Char '-' Char Action31) / DoubleChar)> */ + func() bool { + position165, tokenIndex165, depth165 := position, tokenIndex, depth + { + + position166 := position + depth++ + { + + position167, tokenIndex167, depth167 := position, tokenIndex, depth + if !rules[RuleChar]() { + goto l168 + } + if buffer[position] != rune('-') { + goto l168 + } + position++ + if !rules[RuleChar]() { + goto l168 + } + { + + add(RuleAction31, position) + } + goto l167 + l168: + position, tokenIndex, depth = position167, tokenIndex167, depth167 + if !rules[RuleDoubleChar]() { + goto l165 + } + } + l167: + depth-- + add(RuleDoubleRange, position166) + } + return true + l165: + position, tokenIndex, depth = position165, tokenIndex165, depth165 + return false + }, + /* 16 Char <- <(Escape / (!'\\' <.> Action32))> */ + func() bool { + position170, tokenIndex170, depth170 := position, tokenIndex, depth + { + + position171 := position + depth++ + { + + position172, tokenIndex172, depth172 := position, tokenIndex, depth + if !rules[RuleEscape]() { + goto l173 + } + goto l172 + l173: + position, tokenIndex, depth = position172, tokenIndex172, depth172 + { + + position174, tokenIndex174, depth174 := position, tokenIndex, depth + if buffer[position] != rune('\\') { + goto l174 + } + position++ + goto l170 + l174: + position, tokenIndex, depth = position174, tokenIndex174, depth174 + } + { + + position175 := position + depth++ + if !matchDot() { + goto l170 + } + depth-- + add(RulePegText, position175) + } + { + + add(RuleAction32, position) + } + } + l172: + depth-- + add(RuleChar, position171) + } + return true + l170: + position, tokenIndex, depth = position170, tokenIndex170, depth170 + return false + }, + /* 17 DoubleChar <- <(Escape / (<([a-z] / [A-Z])> Action33) / (!'\\' <.> Action34))> */ + func() bool { + position177, tokenIndex177, depth177 := position, tokenIndex, depth + { + + position178 := position + depth++ + { + + position179, tokenIndex179, depth179 := position, tokenIndex, depth + if !rules[RuleEscape]() { + goto l180 + } + goto l179 + l180: + position, tokenIndex, depth = position179, tokenIndex179, depth179 + { + + position182 := position + depth++ + { + + position183, tokenIndex183, depth183 := position, tokenIndex, depth + if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l184 + } + position++ + goto l183 + l184: + position, tokenIndex, depth = position183, tokenIndex183, depth183 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l181 + } + position++ + } + l183: + depth-- + add(RulePegText, position182) + } + { + + add(RuleAction33, position) + } + goto l179 + l181: + position, tokenIndex, depth = position179, tokenIndex179, depth179 + { + + position186, tokenIndex186, depth186 := position, tokenIndex, depth + if buffer[position] != rune('\\') { + goto l186 + } + position++ + goto l177 + l186: + position, tokenIndex, depth = position186, tokenIndex186, depth186 + } + { + + position187 := position + depth++ + if !matchDot() { + goto l177 + } + depth-- + add(RulePegText, position187) + } + { + + add(RuleAction34, position) + } + } + l179: + depth-- + add(RuleDoubleChar, position178) + } + return true + l177: + position, tokenIndex, depth = position177, tokenIndex177, depth177 + return false + }, + /* 18 Escape <- <(('\\' ('a' / 'A') Action35) / ('\\' ('b' / 'B') Action36) / ('\\' ('e' / 'E') Action37) / ('\\' ('f' / 'F') Action38) / ('\\' ('n' / 'N') Action39) / ('\\' ('r' / 'R') Action40) / ('\\' ('t' / 'T') Action41) / ('\\' ('v' / 'V') Action42) / ('\\' '\'' Action43) / ('\\' '"' Action44) / ('\\' '[' Action45) / ('\\' ']' Action46) / ('\\' '-' Action47) / ('\\' <([0-3] [0-7] [0-7])> Action48) / ('\\' <([0-7] [0-7]?)> Action49) / ('\\' '\\' Action50))> */ + func() bool { + position189, tokenIndex189, depth189 := position, tokenIndex, depth + { + + position190 := position + depth++ + { + + position191, tokenIndex191, depth191 := position, tokenIndex, depth + if buffer[position] != rune('\\') { + goto l192 + } + position++ + { + + position193, tokenIndex193, depth193 := position, tokenIndex, depth + if buffer[position] != rune('a') { + goto l194 + } + position++ + goto l193 + l194: + position, tokenIndex, depth = position193, tokenIndex193, depth193 + if buffer[position] != rune('A') { + goto l192 + } + position++ + } + l193: + { + + add(RuleAction35, position) + } + goto l191 + l192: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l196 + } + position++ + { + + position197, tokenIndex197, depth197 := position, tokenIndex, depth + if buffer[position] != rune('b') { + goto l198 + } + position++ + goto l197 + l198: + position, tokenIndex, depth = position197, tokenIndex197, depth197 + if buffer[position] != rune('B') { + goto l196 + } + position++ + } + l197: + { + + add(RuleAction36, position) + } + goto l191 + l196: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l200 + } + position++ + { + + position201, tokenIndex201, depth201 := position, tokenIndex, depth + if buffer[position] != rune('e') { + goto l202 + } + position++ + goto l201 + l202: + position, tokenIndex, depth = position201, tokenIndex201, depth201 + if buffer[position] != rune('E') { + goto l200 + } + position++ + } + l201: + { + + add(RuleAction37, position) + } + goto l191 + l200: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l204 + } + position++ + { + + position205, tokenIndex205, depth205 := position, tokenIndex, depth + if buffer[position] != rune('f') { + goto l206 + } + position++ + goto l205 + l206: + position, tokenIndex, depth = position205, tokenIndex205, depth205 + if buffer[position] != rune('F') { + goto l204 + } + position++ + } + l205: + { + + add(RuleAction38, position) + } + goto l191 + l204: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l208 + } + position++ + { + + position209, tokenIndex209, depth209 := position, tokenIndex, depth + if buffer[position] != rune('n') { + goto l210 + } + position++ + goto l209 + l210: + position, tokenIndex, depth = position209, tokenIndex209, depth209 + if buffer[position] != rune('N') { + goto l208 + } + position++ + } + l209: + { + + add(RuleAction39, position) + } + goto l191 + l208: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l212 + } + position++ + { + + position213, tokenIndex213, depth213 := position, tokenIndex, depth + if buffer[position] != rune('r') { + goto l214 + } + position++ + goto l213 + l214: + position, tokenIndex, depth = position213, tokenIndex213, depth213 + if buffer[position] != rune('R') { + goto l212 + } + position++ + } + l213: + { + + add(RuleAction40, position) + } + goto l191 + l212: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l216 + } + position++ + { + + position217, tokenIndex217, depth217 := position, tokenIndex, depth + if buffer[position] != rune('t') { + goto l218 + } + position++ + goto l217 + l218: + position, tokenIndex, depth = position217, tokenIndex217, depth217 + if buffer[position] != rune('T') { + goto l216 + } + position++ + } + l217: + { + + add(RuleAction41, position) + } + goto l191 + l216: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l220 + } + position++ + { + + position221, tokenIndex221, depth221 := position, tokenIndex, depth + if buffer[position] != rune('v') { + goto l222 + } + position++ + goto l221 + l222: + position, tokenIndex, depth = position221, tokenIndex221, depth221 + if buffer[position] != rune('V') { + goto l220 + } + position++ + } + l221: + { + + add(RuleAction42, position) + } + goto l191 + l220: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l224 + } + position++ + if buffer[position] != rune('\'') { + goto l224 + } + position++ + { + + add(RuleAction43, position) + } + goto l191 + l224: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l226 + } + position++ + if buffer[position] != rune('"') { + goto l226 + } + position++ + { + + add(RuleAction44, position) + } + goto l191 + l226: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l228 + } + position++ + if buffer[position] != rune('[') { + goto l228 + } + position++ + { + + add(RuleAction45, position) + } + goto l191 + l228: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l230 + } + position++ + if buffer[position] != rune(']') { + goto l230 + } + position++ + { + + add(RuleAction46, position) + } + goto l191 + l230: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l232 + } + position++ + if buffer[position] != rune('-') { + goto l232 + } + position++ + { + + add(RuleAction47, position) + } + goto l191 + l232: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l234 + } + position++ + { + + position235 := position + depth++ + if c := buffer[position]; c < rune('0') || c > rune('3') { + goto l234 + } + position++ + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l234 + } + position++ + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l234 + } + position++ + depth-- + add(RulePegText, position235) + } + { + + add(RuleAction48, position) + } + goto l191 + l234: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l237 + } + position++ + { + + position238 := position + depth++ + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l237 + } + position++ + { + + position239, tokenIndex239, depth239 := position, tokenIndex, depth + if c := buffer[position]; c < rune('0') || c > rune('7') { + goto l239 + } + position++ + goto l240 + l239: + position, tokenIndex, depth = position239, tokenIndex239, depth239 + } + l240: + depth-- + add(RulePegText, position238) + } + { + + add(RuleAction49, position) + } + goto l191 + l237: + position, tokenIndex, depth = position191, tokenIndex191, depth191 + if buffer[position] != rune('\\') { + goto l189 + } + position++ + if buffer[position] != rune('\\') { + goto l189 + } + position++ + { + + add(RuleAction50, position) + } + } + l191: + depth-- + add(RuleEscape, position190) + } + return true + l189: + position, tokenIndex, depth = position189, tokenIndex189, depth189 + return false + }, + /* 19 Action <- <('{' '}' _)> */ + func() bool { + position243, tokenIndex243, depth243 := position, tokenIndex, depth + { + + position244 := position + depth++ + if buffer[position] != rune('{') { + goto l243 + } + position++ + { + + position245 := position + depth++ + l246: + { + + position247, tokenIndex247, depth247 := position, tokenIndex, depth + if !rules[RuleBraces]() { + goto l247 + } + goto l246 + l247: + position, tokenIndex, depth = position247, tokenIndex247, depth247 + } + depth-- + add(RulePegText, position245) + } + if buffer[position] != rune('}') { + goto l243 + } + position++ + if !rules[Rule_]() { + goto l243 + } + depth-- + add(RuleAction, position244) + } + return true + l243: + position, tokenIndex, depth = position243, tokenIndex243, depth243 + return false + }, + /* 20 Braces <- <(('{' Braces* '}') / (!'}' .))> */ + func() bool { + position248, tokenIndex248, depth248 := position, tokenIndex, depth + { + + position249 := position + depth++ + { + + position250, tokenIndex250, depth250 := position, tokenIndex, depth + if buffer[position] != rune('{') { + goto l251 + } + position++ + l252: + { + + position253, tokenIndex253, depth253 := position, tokenIndex, depth + if !rules[RuleBraces]() { + goto l253 + } + goto l252 + l253: + position, tokenIndex, depth = position253, tokenIndex253, depth253 + } + if buffer[position] != rune('}') { + goto l251 + } + position++ + goto l250 + l251: + position, tokenIndex, depth = position250, tokenIndex250, depth250 + { + + position254, tokenIndex254, depth254 := position, tokenIndex, depth + if buffer[position] != rune('}') { + goto l254 + } + position++ + goto l248 + l254: + position, tokenIndex, depth = position254, tokenIndex254, depth254 + } + if !matchDot() { + goto l248 + } + } + l250: + depth-- + add(RuleBraces, position249) + } + return true + l248: + position, tokenIndex, depth = position248, tokenIndex248, depth248 + return false + }, + /* 21 Equal <- <('=' _)> */ + func() bool { + position255, tokenIndex255, depth255 := position, tokenIndex, depth + { + + position256 := position + depth++ + if buffer[position] != rune('=') { + goto l255 + } + position++ + if !rules[Rule_]() { + goto l255 + } + depth-- + add(RuleEqual, position256) + } + return true + l255: + position, tokenIndex, depth = position255, tokenIndex255, depth255 + return false + }, + /* 22 Colon <- <(':' _)> */ + nil, + /* 23 Bar <- <('|' _)> */ + func() bool { + position258, tokenIndex258, depth258 := position, tokenIndex, depth + { + + position259 := position + depth++ + if buffer[position] != rune('|') { + goto l258 + } + position++ + if !rules[Rule_]() { + goto l258 + } + depth-- + add(RuleBar, position259) + } + return true + l258: + position, tokenIndex, depth = position258, tokenIndex258, depth258 + return false + }, + /* 24 And <- <('&' _)> */ + func() bool { + position260, tokenIndex260, depth260 := position, tokenIndex, depth + { + + position261 := position + depth++ + if buffer[position] != rune('&') { + goto l260 + } + position++ + if !rules[Rule_]() { + goto l260 + } + depth-- + add(RuleAnd, position261) + } + return true + l260: + position, tokenIndex, depth = position260, tokenIndex260, depth260 + return false + }, + /* 25 Not <- <('!' _)> */ + nil, + /* 26 Question <- <('?' _)> */ + nil, + /* 27 Star <- <('*' _)> */ + nil, + /* 28 Plus <- <('+' _)> */ + nil, + /* 29 Open <- <('(' _)> */ + nil, + /* 30 Close <- <(')' _)> */ + nil, + /* 31 Dot <- <('.' _)> */ + nil, + /* 32 RPERCENT <- <('%' '}' _)> */ + nil, + /* 33 _ <- <(Space / Comment)*> */ + func() bool { + { + + position271 := position + depth++ + l272: + { + + position273, tokenIndex273, depth273 := position, tokenIndex, depth + { + + position274, tokenIndex274, depth274 := position, tokenIndex, depth + { + + position276 := position + depth++ + { + + switch buffer[position] { + case '\t': + if buffer[position] != rune('\t') { + goto l275 + } + position++ + break + case ' ': + if buffer[position] != rune(' ') { + goto l275 + } + position++ + break + default: + if !rules[RuleEndOfLine]() { + goto l275 + } + break + } + } + + depth-- + add(RuleSpace, position276) + } + goto l274 + l275: + position, tokenIndex, depth = position274, tokenIndex274, depth274 + { + + position278 := position + depth++ + if buffer[position] != rune('#') { + goto l273 + } + position++ + l279: + { + + position280, tokenIndex280, depth280 := position, tokenIndex, depth + { + + position281, tokenIndex281, depth281 := position, tokenIndex, depth + if !rules[RuleEndOfLine]() { + goto l281 + } + goto l280 + l281: + position, tokenIndex, depth = position281, tokenIndex281, depth281 + } + if !matchDot() { + goto l280 + } + goto l279 + l280: + position, tokenIndex, depth = position280, tokenIndex280, depth280 + } + if !rules[RuleEndOfLine]() { + goto l273 + } + depth-- + add(RuleComment, position278) + } + } + l274: + goto l272 + l273: + position, tokenIndex, depth = position273, tokenIndex273, depth273 + } + depth-- + add(Rule_, position271) + } + return true + }, + /* 34 Comment <- <('#' (!EndOfLine .)* EndOfLine)> */ + nil, + /* 35 Space <- <((&('\t') '\t') | (&(' ') ' ') | (&('\n' | '\r') EndOfLine))> */ + nil, + /* 36 EndOfLine <- <(('\r' '\n') / '\n' / '\r')> */ + func() bool { + position284, tokenIndex284, depth284 := position, tokenIndex, depth + { + + position285 := position + depth++ + { + + position286, tokenIndex286, depth286 := position, tokenIndex, depth + if buffer[position] != rune('\r') { + goto l287 + } + position++ + if buffer[position] != rune('\n') { + goto l287 + } + position++ + goto l286 + l287: + position, tokenIndex, depth = position286, tokenIndex286, depth286 + if buffer[position] != rune('\n') { + goto l288 + } + position++ + goto l286 + l288: + position, tokenIndex, depth = position286, tokenIndex286, depth286 + if buffer[position] != rune('\r') { + goto l284 + } + position++ + } + l286: + depth-- + add(RuleEndOfLine, position285) + } + return true + l284: + position, tokenIndex, depth = position284, tokenIndex284, depth284 + return false + }, + /* 37 EndOfFile <- */ + nil, + /* 38 Begin <- <('<' _)> */ + nil, + /* 39 End <- <('>' _)> */ + nil, + /* 41 Action0 <- <{ p.AddPackage(buffer[begin:end]) }> */ + nil, + /* 42 Action1 <- <{ p.AddYYSType(buffer[begin:end]) }> */ + nil, + /* 43 Action2 <- <{ p.AddLeg(buffer[begin:end]) }> */ + nil, + /* 44 Action3 <- <{ p.AddState(buffer[begin:end]) }> */ + nil, + nil, + /* 46 Action4 <- <{ p.AddDeclaration(buffer[begin:end]) }> */ + nil, + /* 47 Action5 <- <{ p.AddTrailer(buffer[begin:end]) }> */ + nil, + /* 48 Action6 <- <{ p.AddRule(buffer[begin:end]) }> */ + nil, + /* 49 Action7 <- <{ p.AddExpression() }> */ + nil, + /* 50 Action8 <- <{ p.AddAlternate() }> */ + nil, + /* 51 Action9 <- <{ p.AddNil(); p.AddAlternate() }> */ + nil, + /* 52 Action10 <- <{ p.AddNil() }> */ + nil, + /* 53 Action11 <- <{ p.AddSequence() }> */ + nil, + /* 54 Action12 <- <{ p.AddPredicate(buffer[begin:end]) }> */ + nil, + /* 55 Action13 <- <{ p.AddPeekFor() }> */ + nil, + /* 56 Action14 <- <{ p.AddPeekNot() }> */ + nil, + /* 57 Action15 <- <{ p.AddQuery() }> */ + nil, + /* 58 Action16 <- <{ p.AddStar() }> */ + nil, + /* 59 Action17 <- <{ p.AddPlus() }> */ + nil, + /* 60 Action18 <- <{ p.AddVariable(buffer[begin:end]) }> */ + nil, + /* 61 Action19 <- <{ p.AddName(buffer[begin:end]) }> */ + nil, + /* 62 Action20 <- <{ p.AddName(buffer[begin:end]) }> */ + nil, + /* 63 Action21 <- <{ p.AddDot() }> */ + nil, + /* 64 Action22 <- <{ p.AddAction(buffer[begin:end]) }> */ + nil, + /* 65 Action23 <- <{ p.AddPush() }> */ + nil, + /* 66 Action24 <- <{ p.AddSequence() }> */ + nil, + /* 67 Action25 <- <{ p.AddSequence() }> */ + nil, + /* 68 Action26 <- <{ p.AddPeekNot(); p.AddDot(); p.AddSequence() }> */ + nil, + /* 69 Action27 <- <{ p.AddPeekNot(); p.AddDot(); p.AddSequence() }> */ + nil, + /* 70 Action28 <- <{ p.AddAlternate() }> */ + nil, + /* 71 Action29 <- <{ p.AddAlternate() }> */ + nil, + /* 72 Action30 <- <{ p.AddRange() }> */ + nil, + /* 73 Action31 <- <{ p.AddDoubleRange() }> */ + nil, + /* 74 Action32 <- <{ p.AddCharacter(buffer[begin:end]) }> */ + nil, + /* 75 Action33 <- <{ p.AddDoubleCharacter(buffer[begin:end]) }> */ + nil, + /* 76 Action34 <- <{ p.AddCharacter(buffer[begin:end]) }> */ + nil, + /* 77 Action35 <- <{ p.AddCharacter("\a") }> */ + nil, + /* 78 Action36 <- <{ p.AddCharacter("\b") }> */ + nil, + /* 79 Action37 <- <{ p.AddCharacter("\x1B") }> */ + nil, + /* 80 Action38 <- <{ p.AddCharacter("\f") }> */ + nil, + /* 81 Action39 <- <{ p.AddCharacter("\n") }> */ + nil, + /* 82 Action40 <- <{ p.AddCharacter("\r") }> */ + nil, + /* 83 Action41 <- <{ p.AddCharacter("\t") }> */ + nil, + /* 84 Action42 <- <{ p.AddCharacter("\v") }> */ + nil, + /* 85 Action43 <- <{ p.AddCharacter("'") }> */ + nil, + /* 86 Action44 <- <{ p.AddCharacter("\"") }> */ + nil, + /* 87 Action45 <- <{ p.AddCharacter("[") }> */ + nil, + /* 88 Action46 <- <{ p.AddCharacter("]") }> */ + nil, + /* 89 Action47 <- <{ p.AddCharacter("-") }> */ + nil, + /* 90 Action48 <- <{ p.AddOctalCharacter(buffer[begin:end]) }> */ + nil, + /* 91 Action49 <- <{ p.AddOctalCharacter(buffer[begin:end]) }> */ + nil, + /* 92 Action50 <- <{ p.AddCharacter("\\") }> */ + nil, + } + p.rules = rules +} diff --git a/leg.go b/src/leg/leg.go similarity index 100% rename from leg.go rename to src/leg/leg.go diff --git a/src/leg/leg.leg b/src/leg/leg.leg new file mode 100644 index 0000000..58a457b --- /dev/null +++ b/src/leg/leg.leg @@ -0,0 +1,117 @@ +# PE Grammar for PE Grammars +# +# Adapted from [1] by Ian Piumarta . +# +# 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 + +# parser declaration + +YYSTYPE uint8 + +type Leg Peg { + *Tree +} + +# Hierarchical syntax +Grammar = - 'package' - Identifier { p.AddPackage(buffer[begin:end]) } + 'YYSTYPE' - Identifier { p.AddYYSType(buffer[begin:end]) } + 'type' - Identifier { p.AddLeg(buffer[begin:end]) } + 'Peg' - Action { p.AddState(buffer[begin:end]) } + (Declaration | Definition)+ Trailer? EndOfFile + +Declaration = '%{' < ( !'%}' . )* > RPERCENT { p.AddDeclaration(buffer[begin:end]) } +Trailer = '%%' < .* > { p.AddTrailer(buffer[begin:end]) } + +Definition = Identifier { p.AddRule(buffer[begin:end]) } + Equal Expression { p.AddExpression() } +Expression = Sequence (Bar Sequence { p.AddAlternate() } + )* (Bar { p.AddNil(); p.AddAlternate() } + )? + | { p.AddNil() } +Sequence = Prefix (Prefix { p.AddSequence() } + )* +Prefix = And Action { p.AddPredicate(buffer[begin:end]) } + | And Suffix { p.AddPeekFor() } + | Not Suffix { p.AddPeekNot() } + | Suffix +Suffix = Primary (Question { p.AddQuery() } + | Star { p.AddStar() } + | Plus { p.AddPlus() } + )? +Primary = Identifier !Equal { p.AddName(buffer[begin:end]) } + | Open Expression Close + | Literal + | Class + | Dot { p.AddDot() } + | Action { p.AddAction(buffer[begin:end]) } + | Begin Expression End { p.AddPush() } + +# Lexical syntax +#PrivateIdentifier = < [a-z_] IdentCont* > - +Identifier = < [-a-zA-Z_][-a-zA-Z_0-9]* > - +Literal = ['] (!['] Char)? (!['] Char { p.AddSequence() } + )* ['] - + | ["] (!["] DoubleChar)? (!["] DoubleChar { p.AddSequence() } + )* ["] - +Class = ( '[[' ( '^' DoubleRanges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } + | DoubleRanges )? + ']]' + | '[' ( '^' Ranges { p.AddPeekNot(); p.AddDot(); p.AddSequence() } + | Ranges )? + ']' ) + - +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(buffer[begin:end]) } +DoubleChar = Escape + | <[a-zA-Z]> { p.AddDoubleCharacter(buffer[begin:end]) } + | !'\\' <.> { p.AddCharacter(buffer[begin:end]) } +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("-") } + | '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(buffer[begin:end]) } + | '\\' <[0-7][0-7]?> { p.AddOctalCharacter(buffer[begin:end]) } + | '\\\\' { p.AddCharacter("\\") } +Action = '{' < Braces* > '}' - +Braces = '{' Braces* '}' | !'}' . +Equal = '=' - +Bar = '|' - +And = '&' - +Not = '!' - +Question = '?' - +Star = '*' - +Plus = '+' - +Open = '(' - +Close = ')' - +Dot = '.' - +RPERCENT = '%}' - + - = (Space | Comment)* +Comment = '#' (!EndOfLine .)* EndOfLine +Space = ' ' | '\t' | EndOfLine +EndOfLine = '\r\n' | '\n' | '\r' +EndOfFile = !. +Begin = '<' - +End = '>' - diff --git a/main.go b/src/leg/main.go similarity index 84% rename from main.go rename to src/leg/main.go index aeae1c0..92e6a7c 100644 --- a/main.go +++ b/src/leg/main.go @@ -18,7 +18,7 @@ var ( _switch = flag.Bool("switch", false, "replace if-else if-else like blocks with switch blocks") syntax = flag.Bool("syntax", false, "print out the syntax tree") highlight = flag.Bool("highlight", false, "test the syntax highlighter") - test = flag.Bool("test", false, "test the PEG parser performance") + test = flag.Bool("test", false, "test the LEG parser performance") print = flag.Bool("print", false, "directly dump the syntax tree") ) @@ -28,7 +28,7 @@ func main() { if flag.NArg() != 1 { flag.Usage() - log.Fatalf("FILE: the peg file to compile") + log.Fatalf("FILE: the leg file to compile") } file := flag.Arg(0) @@ -38,7 +38,7 @@ func main() { } if *test { - iterations, p := 1000, &Peg{Tree: New(*inline, *_switch), Buffer: string(buffer)} + iterations, p := 1000, &Leg{Tree: New(*inline, *_switch), Buffer: string(buffer)} p.Init() start := time.Now() for i := 0; i < iterations; i++ { @@ -50,7 +50,7 @@ func main() { return } - p := &Peg{Tree: New(*inline, *_switch), Buffer: string(buffer)} + p := &Leg{Tree: New(*inline, *_switch), Buffer: string(buffer)} p.Init() if err := p.Parse(); err != nil { log.Fatal(err) diff --git a/src/leg/set.go b/src/leg/set.go new file mode 120000 index 0000000..859a172 --- /dev/null +++ b/src/leg/set.go @@ -0,0 +1 @@ +../set.go \ No newline at end of file diff --git a/set.go b/src/set.go similarity index 100% rename from set.go rename to src/set.go From 9d5e1876bedb4be5442ce2117a002ce25bd6a09c Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Tue, 8 Apr 2014 16:52:21 +0800 Subject: [PATCH 10/13] Add \n to restore code segment to avoid possible syntax error --- src/leg/leg.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/leg/leg.go b/src/leg/leg.go index 8eb1041..0227bac 100644 --- a/src/leg/leg.go +++ b/src/leg/leg.go @@ -1353,7 +1353,7 @@ func (t *Tree) Compile(file string) { print := func(format string, a ...interface{}) { fmt.Fprintf(&buffer, format, a...) } printSave := func(n uint) { print("\n position%d, tokenIndex%d, depth%d := position, tokenIndex, depth", n, n, n) } - printRestore := func(n uint) { print(" position, tokenIndex, depth = position%d, tokenIndex%d, depth%d", n, n, n) } + printRestore := func(n uint) { print("\n position, tokenIndex, depth = position%d, tokenIndex%d, depth%d", n, n, n) } printTemplate := func(s string) { if error := template.Must(template.New("leg").Parse(s)).Execute(&buffer, t); error != nil { panic(error) From 1eceb731acd9661b56fd9dcdb669d289847e09c9 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Wed, 9 Apr 2014 20:59:41 +0800 Subject: [PATCH 11/13] Resembles stack operations of original C version, tested with calculator example --- src/leg/leg.go | 165 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 47 deletions(-) diff --git a/src/leg/leg.go b/src/leg/leg.go index 0227bac..5a3b85b 100644 --- a/src/leg/leg.go +++ b/src/leg/leg.go @@ -43,6 +43,7 @@ const ( {{end}} RuleActionPush RuleActionPop + RuleActionSet RulePre_ Rule_In_ Rule_Suf @@ -54,6 +55,7 @@ var Rul3s = [...]string { {{end}} "RuleActionPush", "RuleActionPop", + "RuleActionSet", "Pre_", "_In_", "_Suf", @@ -393,7 +395,8 @@ func (p *{{.StructName}}) Execute() { buffer, begin, end := p.Buffer, 0, 0 {{if .HasVariable}} var yy YYSTYPE - stack := make([]YYSTYPE, 0) + stack := make([]YYSTYPE, 1024) + stack_idx := 0 {{end}} for token := range p.TokenTree.Tokens() { switch (token.Rule) { @@ -404,9 +407,12 @@ func (p *{{.StructName}}) Execute() { {{end}} {{if .HasVariable}} case RuleActionPush: - stack = append(stack, yy) + stack_idx += 1 case RuleActionPop: - stack = stack[0:len(stack)-1] + stack_idx -= 1 + case RuleActionSet: + stack[stack_idx] = yy + {{end}} } } @@ -571,7 +577,7 @@ type Node interface { GetId() int SetId(id int) - HasVariable() bool + HasVariable() int HasYY() bool Init() @@ -589,7 +595,7 @@ type node struct { Type string id int - hasVariable bool + hasVariable int hasYY bool front *node @@ -632,7 +638,7 @@ func (n *node) SetId(id int) { n.id = id } -func (n *node) HasVariable() bool { +func (n *node) HasVariable() int { return n.hasVariable } @@ -862,6 +868,15 @@ func escape(c string) string { return "" } +func element_exists(list []string, key string) bool{ + for _, val := range list { + if val == key { + return true + } + } + return false +} + func (t *Tree) Compile(file string) { t.EndSymbol = '\u0004' t.RulesCount++ @@ -871,14 +886,15 @@ func (t *Tree) Compile(file string) { counts := [TypeLast]uint{} { var rule *node - var traverse func(node Node) int + var traverse_var_cnt func(node Node) int + var traverse_var_replace func(node Node) var link func(node Node) // Modify actions which use named semantic variables // Use DFS traversal to find TypeVariable and TypeAction var_stack := make([]string, 0) - traverse = func(n Node) int { + traverse_var_cnt = func(n Node) int { variableCount := 0 next_level_count := 0 leaf := n.Front() @@ -889,18 +905,59 @@ func (t *Tree) Compile(file string) { switch leaf.GetType() { case TypeName: if leaf.Front()!=nil && leaf.Front().GetType()==TypeVariable { - hasVariable = true - variableCount++ - var_stack = append(var_stack, leaf.Front().String()) + if element_exists(var_stack, leaf.Front().String()) == false { + hasVariable = true + variableCount++ + var_stack = append(var_stack, leaf.Front().String()) + } } + case TypeAction: + if strings.Contains(leaf.String(), "$$") { + hasYY = true + leaf.SetString(strings.Replace(leaf.String(),"$$","yy",-1)) + } + + // List types + case TypeSequence: + variableCount += traverse_var_cnt(leaf) + case TypeAlternate: + variableCount += traverse_var_cnt(leaf) + + // Fix types + case TypePeekFor: + fallthrough + case TypePeekNot: + fallthrough + case TypeQuery: + fallthrough + case TypeStar: + fallthrough + case TypePlus: + fallthrough + case TypePush: + variableCount += traverse_var_cnt(leaf) + } + + if leaf.Next()==nil { + break + } + leaf = leaf.Next() + } + return variableCount + next_level_count + } + + traverse_var_replace = func(n Node) { + leaf := n.Front() + if leaf == nil { + return + } + + for { + switch leaf.GetType() { case TypeAction: // Use regular expression to extract every variable and replace them re := regexp.MustCompile("[a-zA-Z_][a-zA-Z0-9_]*") str := leaf.String() - if strings.Contains(str, "$$") { - hasYY = true - str = strings.Replace(str,"$$","yy",-1) - } tempStr := make([]string, 0) lastIndex := 0 for _, element := range re.FindAllStringIndex(str, -1) { @@ -910,7 +967,7 @@ func (t *Tree) Compile(file string) { hasReplaced := false for i, var_element := range var_stack { if var_element == varname { - tempStr = append(tempStr,fmt.Sprintf("stack[len(stack)-%d]", len(var_stack)-i)) + tempStr = append(tempStr,fmt.Sprintf("stack[stack_idx-%d]", len(var_stack)-i-1)) hasReplaced = true break } @@ -921,16 +978,14 @@ func (t *Tree) Compile(file string) { } tempStr = append(tempStr, str[lastIndex:]) leaf.SetString(strings.Join(tempStr,"")) + str = leaf.String() rule = leaf // List types case TypeSequence: - next_level_count = traverse(leaf) - if n.GetType()==TypeAlternate && next_level_count > 0{ - var_stack = var_stack[0:(len(var_stack)-next_level_count)] - } + traverse_var_replace(leaf) case TypeAlternate: - traverse(leaf) + traverse_var_replace(leaf) // Fix types case TypePeekFor: @@ -944,16 +999,13 @@ func (t *Tree) Compile(file string) { case TypePlus: fallthrough case TypePush: - variableCount += traverse(leaf) + traverse_var_replace(leaf) } - if leaf.Next()==nil { break } leaf = leaf.Next() } - // fmt.Println("Return ", variableCount, ", Has ", len(var_stack)) - return variableCount + next_level_count } traverse_node := t.Front() @@ -961,9 +1013,10 @@ func (t *Tree) Compile(file string) { hasVariable = false hasYY = false var_stack = make([]string, 0) - traverse(traverse_node) + variableCount := traverse_var_cnt(traverse_node) if hasVariable { - traverse_node.hasVariable = true + traverse_node.hasVariable = variableCount + traverse_var_replace(traverse_node) t.HasVariable = true } if hasYY { @@ -1461,7 +1514,7 @@ func (t *Tree) Compile(file string) { } } printClearStack := func(n Node) { - print("\n for i:=0; i0 { print("\n variableCount := 0") + print("\n variableTotal := ") + print(strconv.Itoa(element.HasVariable())) + // Preserve enough stack space for the rule + print("\n for i:=0; i < variableTotal; i++ {") + print("\n add(RuleActionPush, position)") + print("\n }") hasVariable = true } compile(expression, ko) - if element.HasVariable() { + if element.HasVariable()>0 { printClearStack(element) } - if element.HasYY() { - print("\n add(RuleActionPush, position)") - } + // if element.HasYY() { + // print("\n add(RuleActionPush, position)") + // } print("\n return true") if labels[ko] { printLabel(ko) From 442eba56438509b3bdb796ea698aa7a68d2f5864 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Wed, 16 Apr 2014 01:24:45 +0800 Subject: [PATCH 12/13] Correctly push/pop stack index --- src/leg/leg.go | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/leg/leg.go b/src/leg/leg.go index 5a3b85b..ec8678e 100644 --- a/src/leg/leg.go +++ b/src/leg/leg.go @@ -954,6 +954,16 @@ func (t *Tree) Compile(file string) { for { switch leaf.GetType() { + case TypeName: + // Store relative stack index of variable for later use + if leaf.Front()!=nil && leaf.Front().GetType()==TypeVariable { + for i, var_element := range var_stack { + if var_element == leaf.Front().String() { + leaf.Front().hasVariable = len(var_stack)-i-1 + break + } + } + } case TypeAction: // Use regular expression to extract every variable and replace them re := regexp.MustCompile("[a-zA-Z_][a-zA-Z0-9_]*") @@ -1535,21 +1545,23 @@ func (t *Tree) Compile(file string) { compile(rule.Front(), ko) return } - if n.Front() != nil && n.Front().GetType() == TypeVariable { - print("\n variableCount++") - } + // if n.Front() != nil && n.Front().GetType() == TypeVariable { + // print("\n variableCount++") + // } print("\n if !rules[Rule%v]() {", name /*rule.GetId()*/) printJump(ko) print("}") if n.Front() != nil && n.Front().GetType() == TypeVariable { // Rewind stack index to this variable - print("\n for i:=0; i < variableTotal - variableCount ; i++ {") + print("\n variableIdx = ") + print(strconv.Itoa(n.Front().HasVariable())) + print("\n for i:=0; i < variableIdx ; i++ {") print("\n add(RuleActionPop, position)") print("\n }") - // Set this variable as yy + // Set yy at this position in stack print("\n add(RuleActionSet, position)") // Rewind stack index back to top of stack - print("\n for i:=0; i < variableTotal - variableCount ; i++ {") + print("\n for i:=0; i < variableIdx ; i++ {") print("\n add(RuleActionPush, position)") print("\n }") } @@ -1775,7 +1787,7 @@ func (t *Tree) Compile(file string) { printSave(ko) } if element.HasVariable()>0 { - print("\n variableCount := 0") + print("\n variableIdx := 0") print("\n variableTotal := ") print(strconv.Itoa(element.HasVariable())) // Preserve enough stack space for the rule From 4b3e356e5611e8fc1e98c1771839cf30972d3464 Mon Sep 17 00:00:00 2001 From: "Szu-Kai Hsu (brucehsu)" Date: Wed, 16 Apr 2014 12:07:15 +0800 Subject: [PATCH 13/13] Substitute YYSTYPE instead of use directly Defining YYSTYPE as a new type would cause some function calling issues --- src/leg/leg.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/leg/leg.go b/src/leg/leg.go index ec8678e..0f36d93 100644 --- a/src/leg/leg.go +++ b/src/leg/leg.go @@ -32,8 +32,6 @@ const END_SYMBOL rune = {{.EndSymbol}} {{range .Declarations}}{{.}} {{end}} -type YYSTYPE {{.YYSType}} - /* The rule types inferred from the grammar are below. */ type Rule uint8 @@ -394,8 +392,8 @@ func (p *{{.StructName}}) Highlighter() { func (p *{{.StructName}}) Execute() { buffer, begin, end := p.Buffer, 0, 0 {{if .HasVariable}} - var yy YYSTYPE - stack := make([]YYSTYPE, 1024) + var yy {{.YYSType}} + stack := make([]{{.YYSType}}, 1024) stack_idx := 0 {{end}} for token := range p.TokenTree.Tokens() { @@ -916,6 +914,7 @@ func (t *Tree) Compile(file string) { hasYY = true leaf.SetString(strings.Replace(leaf.String(),"$$","yy",-1)) } + leaf.SetString(strings.Replace(leaf.String(), "YYSTYPE", t.YYSType,-1)) // List types case TypeSequence: