@top Problem { statement* } statement { ProblemDeclaration { kw<"problem"> QualifiedName "." } | ClassDefinition { kw<"abstract">? kw<"class"> RelationName (ClassBody { "{" ReferenceDeclaration* "}" } | ".") } | EnumDefinition { kw<"enum"> RelationName (EnumBody { "{" sep<",", UniqueNodeName> "}" } | ".") } | PredicateDefinition { (kw<"error"> kw<"pred">? | kw<"pred">) RelationName ParameterList? PredicateBody { ("<->" sep)? "." } } | Assertion { kw<"default">? (NotOp | UnknownOp)? RelationName ParameterList (":" LogicValue)? "." } | UniqueDeclaration { kw<"unique"> sep<",", UniqueNodeName> "." } | ScopeDeclaration { kw<"scope"> sep<",", ScopeElement> "." } } ReferenceDeclaration { (kw<"refers"> | kw<"contains">)? RelationName RelationName ( "[" Multiplicity? "]" )? (kw<"opposite"> RelationName)? ";"? } Parameter { RelationName? VariableName } Conjunction { sep1<",", Literal> } OrOp { ";" } Literal { NotOp? Atom } Atom { RelationName ParameterList? } Argument { VariableName | Real } AssertionArgument { NodeName | StarArgument | Real } LogicValue { kw<"true"> | kw<"false"> | kw<"unknown"> | kw<"error"> } ScopeElement { RelationName ("=" | "+=") Multiplicity } Multiplicity { (IntMult "..")? (IntMult | StarMult)} RelationName { QualifiedName } UniqueNodeName { QualifiedName } VariableName { QualifiedName } NodeName { QualifiedName } QualifiedName { identifier ("::" identifier)* } kw { @specialize[@name={term}] } ParameterList { "(" sep<",", content> ")" } sep { sep1? } sep1 { content (separator content?)* } @skip { LineComment | BlockComment | whitespace } @tokens { whitespace { std.whitespace+ } LineComment { ("//" | "%") ![\n]* } BlockComment { "/*" blockCommentRest } blockCommentRest { ![*] blockCommentRest | "*" blockCommentAfterStar } blockCommentAfterStar { "/" | "*" blockCommentAfterStar | ![/*] blockCommentRest } @precedence { BlockComment, LineComment } identifier { $[A-Za-z_] $[a-zA-Z0-9_]* } int { $[0-9]+ } IntMult { int } StarMult { "*" } Real { "-"? (exponential | int ("." (int | exponential))?) } exponential { int ("e" | "E") ("+" | "-")? int } NotOp { "!" } UnknownOp { "?" } StarArgument { "*" } "{" "}" "(" ")" "[" "]" "." ".." "," ":" "<->" } @detectDelim