func main() { parser := peg.NewParser() start := parser.NonTerminal("Start") expr := parser.NonTerminal("Expression") paren := parser.NonTerminal("Parentheses") number := parser.NonTerminal("Number") start.Expression = expr expr.Expression = parser.Sequence( parser.OrderedChoice( paren, number, ), parser.Optional( parser.Sequence( parser.OrderedChoice( parser.Terminal('-'), parser.Terminal('+'), parser.Terminal('*'), parser.Terminal('/'), ), expr, ), ), ) paren.Expression = parser.Sequence( parser.Terminal('('), expr, parser.Terminal(')'), ) number.Expression = parser.ZeroOrMore( parser.Range('0', '9'), ) tree := parser.Parse("1+1+3*11-5+(2+3)*2/20") fmt.Println(tree) fmt.Println(reduce(tree)) }
func parseQuery(input string) *peg.ExpressionTree { parser := peg.NewParser() start := parser.NonTerminal("Start") whitespace := parser.NonTerminal("Whitespace") quotedString := parser.NonTerminal("QuotedString") rootConstraint := parser.NonTerminal("RootConstraint") constraint := parser.NonTerminal("Constraint") colonIdentifier := parser.NonTerminal("ColonIdentifier") variable := parser.NonTerminal("Variable") identifier := parser.NonTerminal("Identifier") fixedNode := parser.NonTerminal("FixedNode") nodeIdent := parser.NonTerminal("NodeIdentifier") predIdent := parser.NonTerminal("PredIdentifier") reverse := parser.NonTerminal("Reverse") predKeyword := parser.NonTerminal("PredicateKeyword") optional := parser.NonTerminal("OptionalKeyword") start.Expression = rootConstraint whitespace.Expression = parser.OneOrMore( parser.OrderedChoice( parser.Terminal(' '), parser.Terminal('\t'), parser.Terminal('\n'), parser.Terminal('\r'), ), ) quotedString.Expression = parser.Sequence( parser.Terminal('"'), parser.OneOrMore( parser.OrderedChoice( parser.Range('0', '9'), parser.Range('a', 'z'), parser.Range('A', 'Z'), parser.Terminal('_'), parser.Terminal('/'), parser.Terminal(':'), parser.Terminal(' '), parser.Terminal('\''), ), ), parser.Terminal('"'), ) predKeyword.Expression = parser.OrderedChoice( optional, ) optional.Expression = parser.Sequence( parser.Terminal('o'), parser.Terminal('p'), parser.Terminal('t'), parser.Terminal('i'), parser.Terminal('o'), parser.Terminal('n'), parser.Terminal('a'), parser.Terminal('l'), ) identifier.Expression = parser.OneOrMore( parser.OrderedChoice( parser.Range('0', '9'), parser.Range('a', 'z'), parser.Range('A', 'Z'), parser.Terminal('_'), parser.Terminal('.'), parser.Terminal('/'), parser.Terminal(':'), parser.Terminal('#'), ), ) reverse.Expression = parser.Terminal('!') variable.Expression = parser.Sequence( parser.Terminal('$'), identifier, ) colonIdentifier.Expression = parser.Sequence( parser.Terminal(':'), identifier, ) fixedNode.Expression = parser.OrderedChoice( colonIdentifier, quotedString, ) nodeIdent.Expression = parser.OrderedChoice( variable, fixedNode, ) predIdent.Expression = parser.Sequence( parser.Optional(reverse), parser.OrderedChoice( nodeIdent, constraint, ), ) constraint.Expression = parser.Sequence( parser.Terminal('('), parser.Optional(whitespace), predIdent, parser.Optional(whitespace), parser.Optional(predKeyword), parser.Optional(whitespace), parser.OrderedChoice( nodeIdent, rootConstraint, ), parser.Optional(whitespace), parser.Terminal(')'), ) rootConstraint.Expression = parser.Sequence( parser.Terminal('('), parser.Optional(whitespace), nodeIdent, parser.Optional(whitespace), parser.ZeroOrMore(parser.Sequence( constraint, parser.Optional(whitespace), )), parser.Terminal(')'), ) tree := parser.Parse(input) return tree }