module Why { language Why { syntax Main = t:TypeDef => t; syntax TypeDef = "class" n:Id LCurly def:PropertyDefList RCurly => TypeDef { Name {n}, TypeDefinitions { def } }; syntax PropertyDefList = p1:PropertyDef1 p2:PropertyDef2 => [p1, p2]; //Variant 1 syntax PropertyDef1 = t:TypeRef name:Id Semi => PropertyDef{Type {t}, Name{name}}; //Variant 2 (Note the different tree output for Name!!!) syntax PropertyDef2 = t:PrimitiveType name:Id Semi => PropertyDef{Type {t}, Name{name}}; syntax TypeRef = t:PrimitiveType => PrimitiveType { Name {t} }; @{Classification["Identifier"]} token Id = Letter (Alphanumeric | "_")*; token Letter = "A".."Z" | "a".."z"; token Digit = "0".."9"; token Alphanumeric = Letter | Digit; @{Classification["Keyword"]} token Class = "class"; @{Classification["Keyword"]} token PrimitiveType = "int" | "string"; @{Classification["Keyword"]} token LCurly = "{"; @{Classification["Keyword"]} token RCurly = "}"; token Semi = ";"; interleave WhiteSpace = " " | "\t" | "\n" | "\r"; } }