module WebLayer hiddens context-free start-symbols WebLayer exports sorts Id UpperId QualifiedId FreeText lexical syntax [a-z][a-zA-Z0-9\_]* -> Id [A-Z][a-zA-Z0-9\_]* -> UpperId [a-zA-Z]* -> Text {Id "."}+ -> QualifiedId [\ \t\n] -> LAYOUT "//" ~[\n]* [\n] -> LAYOUT lexical restrictions Id -/- [a-zA-Z0-9\_] UpperId -/- [a-zA-Z0-9\_] exports sorts WebLayer context-free syntax "weblayer" UpperId PageDecl* -> WebLayer {cons("WebLayer")} InitialPage? "page" UpperId "(" {Param ","}* ")" "{" PageElement+ "}" -> PageDecl {cons("PageDecl")} "initial" -> InitialPage {cons("InitialKeyword")} UpperId Id -> Param {cons("PageParameter")} "for" Param "in" Selector "(" IterElem* ")" -> PageElement {cons("Iterator")} "header(" QualifiedId ")" -> PageElement {cons("Header")} "header(" "\"" Text "\"" ")" "\"" Text "\"" "->" QualifiedId -> IterElem {cons("SimpleIterElem")} QualifiedId -> Selector {cons("QualIdSelector")} "all" -> Selector {cons("AllSelector")} Sample input: weblayer Blog initial page UserList() { header(u.name) for User u in all( //"name" -> u.name a.b ) } page NewBlogEntry(User u){ header("Creating new entry for ") }