{ package ast } Program <- _ vals:(Stmt (ws Stmt)*)? _ EOF { return makeProgram(c, vals) } Stmt <- val:(Package / Import / Rules / Body / Comment) { return val, nil } Package <- "package" ws val:(Ref / Var) { return makePackage(currentLocation(c), val) } Import <- "import" ws path:(Ref / Var) alias:(ws "as" ws Var)? { return makeImport(currentLocation(c), path, alias) } Rules <- DefaultRules / NormalRules DefaultRules <- "default" ws name:Var _ operator:( ":=" / "=" ) _ value:Term { return makeDefaultRule(currentLocation(c), name, operator, value) } NormalRules <- head:(PartialRuleHead / RuleHead) _ rest:(NonEmptyBraceEnclosedBody ( _ RuleExt)* ) { return makeRule(currentLocation(c), head, rest) } PartialRuleHead <- name:Var args:( _ "(" _ Args _ ")" _ ) value:( _ ( ":=" / "=" ) _ ExprTerm )? { return makeRuleHead(currentLocation(c), name, args, nil, value) } RuleHead <- name:Var key:( _ "[" _ ExprTerm _ "]" _ )? value:( _ ( ":=" / "=" ) _ ExprTerm )? { return makeRuleHead(currentLocation(c), name, nil, key, value) } Args <- list:ExprTermList { return makeArgs(list) } Else <- "else" value:( _ "=" _ Term )? body:( _ NonEmptyBraceEnclosedBody ) { return makeRuleExt(currentLocation(c), value, body) } RuleDup <- b:NonEmptyBraceEnclosedBody { return ruleExt{loc: currentLocation(c), body: b.(Body)}, nil } RuleExt <- Else / RuleDup Body <- NonWhitespaceBody / BraceEnclosedBody NonEmptyBraceEnclosedBody <- "{" _ val:WhitespaceBody? _ "}" { if val == nil { return NewBody(), fmt.Errorf("found empty body") } return val, nil } BraceEnclosedBody <- "{" _ val:WhitespaceBody? _ "}" { return makeBraceEnclosedBody(currentLocation(c), val) } WhitespaceBody <- head:Literal tail:(WhitespaceLiteralSeparator _ Literal)* { return makeBody(head, tail, 2) } NonWhitespaceBody <- head:Literal tail:( _ NonWhitespaceLiteralSeparator _ Literal)* { return makeBody(head, tail, 3) } WhitespaceLiteralSeparator <- [ \t]* ((NonWhitespaceLiteralSeparator Comment?) / (Comment? [\r\n])) NonWhitespaceLiteralSeparator <- ";" Literal <- TermExpr / SomeDecl SomeDecl <- "some" ws symbols:SomeDeclList { return makeSomeDeclLiteral(currentLocation(c), symbols) } SomeDeclList <- head:Var rest:( _ ',' _ Var)* { return makeSomeDeclSymbols(head, rest) } TermExpr <- negated:NotKeyword? value:LiteralExpr with:WithKeywordList? { return makeLiteral(negated, value, with) } LiteralExpr <- lhs:ExprTerm rest:( _ LiteralExprOperator _ ExprTerm)? { return makeLiteralExpr(currentLocation(c), lhs, rest) } LiteralExprOperator <- val:( ":=" / "=" ) { return makeInfixOperator(currentLocation(c), c.text) } NotKeyword <- val:("not" ws)? { return val != nil, nil } WithKeywordList <- ws head:WithKeyword rest:( ws WithKeyword )* { return makeWithKeywordList(head, rest) } WithKeyword <- "with" ws target:ExprTerm ws "as" ws value:ExprTerm { return makeWithKeyword(currentLocation(c), target, value) } ExprTerm <- lhs:RelationExpr rest:( _ RelationOperator _ RelationExpr )* { return makeExprTerm(currentLocation(c), lhs, rest) } ExprTermPairList <- head:ExprTermPair? tail:( _ ',' _ ExprTermPair )* _ ","? { return makeExprTermPairList(head, tail) } ExprTermList <- head:ExprTerm? tail:( _ ',' _ ExprTerm )* _ ","? { return makeExprTermList(head, tail) } ExprTermPair <- key:ExprTerm _ ':' _ value:ExprTerm { return makeExprTermPair(key, value) } RelationOperator <- val:("==" / "!=" / "<=" / ">=" / ">" / "<") { return makeInfixOperator(currentLocation(c), c.text) } RelationExpr <- lhs:BitwiseOrExpr rest:( _ BitwiseOrOperator _ BitwiseOrExpr)* { return makeExprTerm(currentLocation(c), lhs, rest) } BitwiseOrOperator <- val:"|" { return makeInfixOperator(currentLocation(c), c.text) } BitwiseOrExpr <- lhs:BitwiseAndExpr rest:( _ BitwiseAndOperator _ BitwiseAndExpr)* { return makeExprTerm(currentLocation(c), lhs, rest) } BitwiseAndOperator <- val:"&" { return makeInfixOperator(currentLocation(c), c.text) } BitwiseAndExpr <- lhs:ArithExpr rest:( _ ArithOperator _ ArithExpr)* { return makeExprTerm(currentLocation(c), lhs, rest) } ArithOperator <- val:("+" / "-") { return makeInfixOperator(currentLocation(c), c.text) } ArithExpr <- lhs:FactorExpr rest:( _ FactorOperator _ FactorExpr )* { return makeExprTerm(currentLocation(c), lhs, rest) } FactorOperator <- val:("*" / "/" / "%"){ return makeInfixOperator(currentLocation(c), c.text) } FactorExpr <- ( "(" _ expr:ExprTerm _ ")" ) { return expr, nil } / term:Term { return term, nil } Call <- operator:(Ref / Var) "(" _ args:ExprTermList _ ")" { return makeCall(currentLocation(c), operator, args) } Term <- val:( Comprehension / Composite / Scalar / Call / Var ) refs:RefOperand* { return makeRef(currentLocation(c), val, refs) } TermPair <- key:Term _ ":" _ value:Term { return makeExprTermPair(key, value) } Comprehension <- ArrayComprehension / ObjectComprehension / SetComprehension ArrayComprehension <- "[" _ head:Term _ "|" _ body:WhitespaceBody _ "]" { return makeArrayComprehension(currentLocation(c), head, body) } ObjectComprehension <- "{" _ head:TermPair _ "|" _ body:WhitespaceBody _ "}" { return makeObjectComprehension(currentLocation(c), head, body) } SetComprehension <- "{" _ head:Term _ "|" _ body:WhitespaceBody _ "}" { return makeSetComprehension(currentLocation(c), head, body) } Composite <- Object / Array / Set Scalar <- Number / String / Bool / Null Object <- '{' _ list:ExprTermPairList _ '}' { return makeObject(currentLocation(c), list) } Array <- '[' _ list:ExprTermList _ ']' { return makeArray(currentLocation(c), list) } Set <- SetEmpty / SetNonEmpty SetEmpty <- "set(" _ ")" { var empty []*Term return makeSet(currentLocation(c), empty) } SetNonEmpty <- '{' _ list:ExprTermList _ '}' { return makeSet(currentLocation(c), list) } Ref <- head:(Composite / Var) rest:RefOperand+ { return makeRef(currentLocation(c), head, rest) } RefOperand <- RefOperandDot / RefOperandCanonical RefOperandDot <- "." val:Var { return makeRefOperandDot(currentLocation(c), val) } RefOperandCanonical <- "[" val:ExprTerm "]" { return val, nil } Var <- val:VarChecked { return val.([]interface{})[0], nil } VarChecked <- val:VarUnchecked !{ return IsKeyword(string(val.(*Term).Value.(Var))), nil } VarUnchecked <- VarStart VarChar* { return makeVar(currentLocation(c), c.text) } Number <- '-'? ( Float / Integer ) { return makeNumber(currentLocation(c), c.text) } Float <- ExponentFloat / PointFloat ExponentFloat <- ( PointFloat / Integer ) Exponent PointFloat <- Integer? Fraction Fraction <- '.' DecimalDigit+ Exponent <- 'e'i [+-]? DecimalDigit+ Integer <- '0' / ( NonZeroDecimalDigit DecimalDigit* ) String <- QuotedString / RawString QuotedString <- '"' Char* '"' { return makeString(currentLocation(c), c.text) } / '"' Char* !'"' { return makeNonterminatedString(currentLocation(c), string(c.text)) } RawString <- '`' [^`]* '`' { return makeRawString(currentLocation(c), c.text) } Bool <- val:("true" / "false") !VarChar { return makeBool(currentLocation(c), c.text) } Null <- "null" !VarChar { return makeNull(currentLocation(c)) } VarStart <- AsciiLetter VarChar <- AsciiLetter / DecimalDigit AsciiLetter <- [A-Za-z_] Char <- ( !EscapedChar . ) / ( '\\' EscapeSequence ) EscapedChar <- [\x00-\x1f"\\] EscapeSequence <- SingleCharEscape / UnicodeEscape SingleCharEscape <- [ " \\ / b f n r t ] UnicodeEscape <- 'u' HexDigit HexDigit HexDigit HexDigit DecimalDigit <- [0-9] NonZeroDecimalDigit <- [1-9] HexDigit <- [0-9a-fA-F] ws "whitespace" <- [ \t\r\n]+ _ "whitespace" <- ( [ \t\r\n] / Comment )* Comment <- [ \t]* "#" text:[^\r\n]* { return makeComments(c, text) } EOF <- !.