diff options
Diffstat (limited to 'scalatexApi/src/main/scala')
-rw-r--r-- | scalatexApi/src/main/scala/scalatex/stages/Parser.scala | 6 | ||||
-rw-r--r-- | scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala | 189 |
2 files changed, 101 insertions, 94 deletions
diff --git a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala index 1b67446..8647264 100644 --- a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala +++ b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala @@ -41,7 +41,7 @@ class Parser(input: ParserInput, indent: Int = 0, offset: Int = 0) extends Scala "@" ~ capture(Id | BlockExpr2 | ('(' ~ optional(Exprs) ~ ')')) } def Header = rule { - "@" ~ capture(Def | Import) + "@" ~ capture(Def(false) | Import) } def HeaderBlock: Rule1[Ast.Header] = rule{ @@ -65,7 +65,7 @@ class Parser(input: ParserInput, indent: Int = 0, offset: Int = 0) extends Scala test(cursorNextIndent() > indent) ~ runSubParser(new Parser(_, cursorNextIndent(), cursor).Body) } - def IfHead = rule{ "@" ~ capture("if" ~ "(" ~ Expr ~ ")") } + def IfHead = rule{ "@" ~ capture("if" ~ "(" ~ Expr() ~ ")") } def IfElse1 = rule{ push(offsetCursor) ~ IfHead ~ BraceBlock ~ optional("else" ~ (BraceBlock | IndentBlock)) } @@ -104,7 +104,7 @@ class Parser(input: ParserInput, indent: Int = 0, offset: Int = 0) extends Scala def TypeArgs2 = rule { '[' ~ Ws ~ Types ~ ']' } def ArgumentExprs2 = rule { '(' ~ Ws ~ - (optional(Exprs ~ ',' ~ Ws) ~ PostfixExpr ~ ':' ~ Ws ~ '_' ~ Ws ~ '*' ~ Ws | optional(Exprs) ) ~ + (optional(Exprs ~ ',' ~ Ws) ~ PostfixExpr() ~ ':' ~ Ws ~ '_' ~ Ws ~ '*' ~ Ws | optional(Exprs) ) ~ ')' } def BlockExpr2: Rule0 = rule { '{' ~ Ws ~ (CaseClauses | Block) ~ '}' } diff --git a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala index af8495c..4fdef16 100644 --- a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala +++ b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala @@ -7,16 +7,24 @@ import org.parboiled2._ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identifiers with Literals { def Whitespace = rule { zeroOrMore(WhitespaceChar | Comment) } + def WhiteLines = rule{ zeroOrMore(WhitespaceChar | Comment | Newline) } + def White(greedy: Boolean = true) = + if (greedy) WhiteLines + else Whitespace /** * Every token handles space at the end. * Don't let it propagate to mixins */ implicit private[this] def wspStr(s: String): Rule0 = rule { - str(s) ~ Whitespace + str(s) ~ WhiteLines } + def wspStrG(s: String, greedy: Boolean): Rule0 = rule { + str(s) ~ White(greedy) + } + implicit private[this] def wspChar(s: Char): Rule0 = rule { - ch(s) ~ Whitespace + ch(s) ~ WhiteLines } def pos = cursor -> cursorChar @@ -33,27 +41,27 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif // only capture super.rule and not the whitespace ////////////////////////////////////////////////// - def IdS = rule { super.Id ~ Whitespace } - def VarIdS = rule { super.VarId ~ Whitespace } - def LiteralS = rule { super.Literal ~ Whitespace } - def SemiS = rule { super.Semi ~ Whitespace } - def NewlineS = rule { super.Newline ~ Whitespace } + def IdS(greedy: Boolean = true) = rule { super.Id ~ White(greedy)} + def VarIdS(greedy: Boolean = true) = rule { super.VarId ~ White(greedy) } + def LiteralS(greedy: Boolean = true) = rule { super.Literal ~ White(greedy) } + def SemiS = rule { super.Semi ~ WhiteLines } + def NewlineS = rule { super.Newline ~ WhiteLines } /////////////////////////////////////////// // Qualifiers and Ids /////////////////////////////////////////// - def QualId = rule { oneOrMore(IdS) separatedBy '.' } - def Ids = rule { oneOrMore(IdS) separatedBy ',' } + def QualId = rule { oneOrMore(IdS()) separatedBy '.' } + def Ids = rule { oneOrMore(IdS()) separatedBy ',' } //path and stableId were refactored (wrt spec) to avoid recursiveness and be more specific - def Path: Rule0 = rule { zeroOrMore(IdS ~ '.') ~ "this" ~ zeroOrMore(IdS).separatedBy('.') | StableId } + def Path: Rule0 = rule { zeroOrMore(IdS() ~ '.') ~ "this" ~ zeroOrMore(IdS()).separatedBy('.') | StableId } def StableId: Rule0 = rule { - zeroOrMore(IdS ~ '.') ~ ("this" | "super" ~ optional(ClassQualifier)) ~ '.' ~ oneOrMore(IdS).separatedBy('.') | - IdS ~ zeroOrMore('.' ~ IdS) + zeroOrMore(IdS() ~ '.') ~ ("this" | "super" ~ optional(ClassQualifier)) ~ '.' ~ oneOrMore(IdS()).separatedBy('.') | + IdS() ~ zeroOrMore('.' ~ IdS()) } // def StableId: Rule0 = rule { zeroOrMore(Id ~ '.') ~ optional("this" | "super" ~ optional(ClassQualifier)) ~ oneOrMore(Id).separatedBy('.') } - def ClassQualifier = rule { '[' ~ IdS ~ ']' } + def ClassQualifier = rule { '[' ~ IdS() ~ ']' } /////////////////////////////////////////// // Types and more Types @@ -65,11 +73,11 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif def ExistentialClause = rule { "forSome" ~ '{' ~ oneOrMore(ExistentialDcl).separatedBy(SemiS) } def ExistentialDcl = rule { "type" ~ TypeDcl | "val" ~ ValDcl } - def InfixType = rule { CompoundType ~ zeroOrMore(IdS ~ optional(NewlineS) ~ CompoundType) } + def InfixType = rule { CompoundType ~ zeroOrMore(IdS() ~ optional(NewlineS) ~ CompoundType) } def CompoundType = rule { oneOrMore(AnnotType).separatedBy("with") ~ optional(Refinement) } def AnnotType = rule { SimpleType ~ zeroOrMore(Annotation) } def SimpleType: Rule0 = rule { - BasicType ~ optional('#' ~ IdS) ~ optional(TypeArgs) + BasicType ~ optional('#' ~ IdS()) ~ optional(TypeArgs) } def BasicType: Rule0 = rule { '(' ~ Types ~ ')' | @@ -89,73 +97,73 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif // Declarations, Expressions and Pattern Matching ///////////////////////////////////////////////// - def Expr: Rule0 = rule { (Bindings | optional("implicit") ~ IdS | "_") ~ "=>" ~ Expr | Expr1 } - def Expr1: Rule0 = rule { - IfCFlow | - WhileCFlow | - TryCFlow | - DoWhileCFlow | - ForCFlow | - "throw" ~ Expr | - "return" ~ optional(Expr) | - SimpleExpr ~ ArgumentExprs ~ '=' ~ Expr | - optional(SimpleExpr ~ '.') ~ IdS ~ '=' ~ Expr | - PostfixExpr ~ optional("match" ~ '{' ~ CaseClauses ~ '}' | Ascription) + def Expr(greedy: Boolean = true): Rule0 = rule { (Bindings | optional("implicit") ~ IdS() | "_") ~ "=>" ~ Expr(greedy) | Expr1(greedy) } + def Expr1(greedy: Boolean = true): Rule0 = rule { + IfCFlow(greedy) | + WhileCFlow(greedy) | + TryCFlow(greedy) | + DoWhileCFlow(greedy) | + ForCFlow(greedy) | + "throw" ~ Expr(greedy) | + "return" ~ optional(Expr(greedy)) | + SimpleExpr() ~ ArgumentExprs() ~ '=' ~ Expr(greedy) | + optional(SimpleExpr() ~ '.') ~ IdS() ~ '=' ~ Expr(greedy) | + PostfixExpr(greedy) ~ optional("match" ~ '{' ~ CaseClauses ~ '}' | Ascription) } - def IfCFlow = rule { "if" ~ '(' ~ Expr ~ ')' ~ zeroOrMore(NewlineS) ~ Expr ~ optional(optional(SemiS) ~ "else" ~ Expr) } - def WhileCFlow = rule { "while" ~ '(' ~ Expr ~ ')' ~ zeroOrMore(NewlineS) ~ Expr } - def TryCFlow = rule { "try" ~ '{' ~ Block ~ '}' ~ optional("catch" ~ '{' ~ CaseClauses ~ '}') ~ optional("finally" ~ Expr) } - def DoWhileCFlow = rule { "do" ~ Expr ~ optional(SemiS) ~ "while" ~ '(' ~ Expr ~ ')' } - def ForCFlow = rule { "for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}') ~ zeroOrMore(NewlineS) ~ optional("yield") ~ Expr } - def PostfixExpr: Rule0 = rule { InfixExpr ~ optional(IdS ~ optional(NewlineS)) } - def InfixExpr: Rule0 = rule { PrefixExpr ~ zeroOrMore(IdS ~ optional(NewlineS) ~ PrefixExpr) } - def PrefixExpr = rule { optional(anyOf("-+~!")) ~ SimpleExpr } - - def SimpleExpr: Rule0 = rule { - SimpleExpr1 ~ zeroOrMore('.' ~ IdS | TypeArgs | ArgumentExprs) ~ optional('_') + def IfCFlow(greedy: Boolean = true) = rule { "if" ~ '(' ~ Expr() ~ ')' ~ zeroOrMore(NewlineS) ~ Expr(greedy) ~ optional(optional(SemiS) ~ "else" ~ Expr(greedy)) } + def WhileCFlow(greedy: Boolean = true) = rule { "while" ~ '(' ~ Expr() ~ ')' ~ zeroOrMore(NewlineS) ~ Expr(greedy) } + def TryCFlow(greedy: Boolean = true) = rule { "try" ~ '{' ~ Block ~ wspStrG("}", greedy) ~ optional("catch" ~ '{' ~ CaseClauses ~ wspStrG("}", greedy)) ~ optional("finally" ~ Expr(greedy)) } + def DoWhileCFlow(greedy: Boolean = true) = rule { "do" ~ Expr() ~ optional(SemiS) ~ "while" ~ '(' ~ Expr() ~ wspStrG(")", greedy) } + def ForCFlow(greedy: Boolean = true) = rule { "for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}') ~ zeroOrMore(NewlineS) ~ optional("yield") ~ Expr(greedy) } + def PostfixExpr(greedy: Boolean = true): Rule0 = rule { InfixExpr(greedy) ~ optional(IdS() ~ optional(NewlineS)) } + def InfixExpr(greedy: Boolean = true): Rule0 = rule { PrefixExpr(greedy) ~ zeroOrMore(IdS() ~ optional(NewlineS) ~ PrefixExpr(greedy)) } + def PrefixExpr(greedy: Boolean = true) = rule { optional(anyOf("-+~!")) ~ SimpleExpr(greedy) } + + def SimpleExpr(greedy: Boolean = true): Rule0 = rule { + SimpleExpr1(greedy) ~ zeroOrMore('.' ~ IdS() | TypeArgs | ArgumentExprs(greedy)) ~ optional('_') } - def SimpleExpr1 = rule{ + def SimpleExpr1(greedy: Boolean = true) = rule{ "new" ~ (ClassTemplate | TemplateBody) | - BlockExpr | - LiteralS ~ drop[String] | + BlockExpr(greedy) | + LiteralS() ~ drop[String] | Path | '_' | - '(' ~ optional(Exprs) ~ ')' + '(' ~ optional(Exprs) ~ wspStrG(")", greedy) } - def Exprs: Rule0 = rule { oneOrMore(Expr).separatedBy(',') } - def ArgumentExprs: Rule0 = rule { - '(' ~ (optional(Exprs ~ ',') ~ PostfixExpr ~ ':' ~ '_' ~ '*' | optional(Exprs)) ~ ')' | - optional(NewlineS) ~ BlockExpr + def Exprs: Rule0 = rule { oneOrMore(Expr()).separatedBy(',') } + def ArgumentExprs(greedy: Boolean = true): Rule0 = rule { + '(' ~ (optional(Exprs ~ ',') ~ PostfixExpr() ~ ':' ~ '_' ~ '*' | optional(Exprs)) ~ ')' | + optional(NewlineS) ~ BlockExpr(greedy) } - def BlockExpr: Rule0 = rule { '{' ~ (CaseClauses | Block) ~ '}' } - def Block: Rule0 = rule { zeroOrMore(BlockStat ~ SemiS) ~ optional(ResultExpr) } + def BlockExpr(greedy: Boolean = true): Rule0 = rule { '{' ~ (CaseClauses | Block) ~ wspStrG("}", greedy) } + def Block: Rule0 = rule { zeroOrMore(BlockStat ~ SemiS) ~ optional(ResultExpr()) } def BlockStat: Rule0 = rule { &(SemiS) ~ MATCH | //shortcircuit when Semi is found Import | - zeroOrMore(Annotation) ~ (optional("implicit" | "lazy") ~ Def | zeroOrMore(LocalModifier) ~ TmplDef) | - Expr1 + zeroOrMore(Annotation) ~ (optional("implicit" | "lazy") ~ Def(false) | zeroOrMore(LocalModifier) ~ TmplDef) | + Expr1(false) } - def ResultExpr: Rule0 = rule { (Bindings | optional("implicit") ~ IdS | "_") ~ "=>" ~ Block | Expr1 } + def ResultExpr(greedy: Boolean = true): Rule0 = rule { (Bindings | optional("implicit") ~ IdS() | "_") ~ "=>" ~ Block | Expr1(true) } def Enumerators: Rule0 = rule { Generator ~ zeroOrMore(SemiS ~ Enumerator) } - def Enumerator: Rule0 = rule { Generator | Guard | Pattern1 ~ '=' ~ Expr } - def Generator: Rule0 = rule { Pattern1 ~ "<-" ~ Expr ~ optional(Guard) } + def Enumerator: Rule0 = rule { Generator | Guard | Pattern1 ~ '=' ~ Expr() } + def Generator: Rule0 = rule { Pattern1 ~ "<-" ~ Expr() ~ optional(Guard) } def CaseClauses: Rule0 = rule { oneOrMore(CaseClause) } def CaseClause: Rule0 = rule { "case" ~ Pattern ~ optional(Guard) ~ "=>" ~ Block } - def Guard: Rule0 = rule { "if" ~ PostfixExpr } + def Guard: Rule0 = rule { "if" ~ PostfixExpr() } def Pattern: Rule0 = rule { oneOrMore(Pattern1) separatedBy '|' } - def Pattern1: Rule0 = rule { '_' ~ ':' ~ TypePat | VarIdS ~ ':' ~ TypePat | Pattern2 } - def Pattern2: Rule0 = rule { VarIdS ~ optional("@" ~ Pattern3) | Pattern3 } - def Pattern3: Rule0 = rule { SimplePattern ~ zeroOrMore(IdS ~ optional(NewlineS) ~ SimplePattern) } // this pattern doesn't make sense to me... + def Pattern1: Rule0 = rule { '_' ~ ':' ~ TypePat | VarIdS() ~ ':' ~ TypePat | Pattern2 } + def Pattern2: Rule0 = rule { VarIdS() ~ optional("@" ~ Pattern3) | Pattern3 } + def Pattern3: Rule0 = rule { SimplePattern ~ zeroOrMore(IdS() ~ optional(NewlineS) ~ SimplePattern) } // this pattern doesn't make sense to me... def SimplePattern: Rule0 = rule { '_' | - LiteralS ~ drop[String] | //literal currently captures, so it can be used outside. but since all our rules lack AST, we drop its value in order to be able to compose them + LiteralS() ~ drop[String] | //literal currently captures, so it can be used outside. but since all our rules lack AST, we drop its value in order to be able to compose them '(' ~ optional(Patterns) ~ ')' | - StableId ~ '(' ~ (optional(Patterns ~ ',') ~ optional(VarIdS ~ '@') ~ '_' ~ '*' | optional(Patterns)) ~ ')' | - VarIdS /*| + StableId ~ '(' ~ (optional(Patterns ~ ',') ~ optional(VarIdS() ~ '@') ~ '_' ~ '*' | optional(Patterns)) ~ ')' | + VarIdS() /*| XmlPattern*/ } def Patterns: Rule0 = rule { '_' ~ '*' | oneOrMore(Pattern).separatedBy(',') } @@ -163,44 +171,43 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif def TypeParamClause: Rule0 = rule { '[' ~ oneOrMore(VariantTypeParam).separatedBy(',') ~ ']' } def FunTypeParamClause: Rule0 = rule { '[' ~ oneOrMore(TypeParam).separatedBy(',') ~ ']' } def VariantTypeParam: Rule0 = rule { zeroOrMore(Annotation) ~ optional(anyOf("+-")) ~ TypeParam } - def TypeParam: Rule0 = rule { (IdS | '_') ~ optional(TypeParamClause) ~ optional(">:" ~ Type) ~ optional("<:" ~ Type) ~ zeroOrMore("<%" ~ Type) ~ zeroOrMore(':' ~ Type) } + def TypeParam: Rule0 = rule { (IdS() | '_') ~ optional(TypeParamClause) ~ optional(">:" ~ Type) ~ optional("<:" ~ Type) ~ zeroOrMore("<%" ~ Type) ~ zeroOrMore(':' ~ Type) } def ParamClauses: Rule0 = rule { zeroOrMore(ParamClause) ~ optional(optional(NewlineS) ~ '(' ~ "implicit" ~ Params ~ ')') } def ParamClause: Rule0 = rule { optional(NewlineS) ~ '(' ~ optional(Params) ~ ')' } def Params: Rule0 = rule { zeroOrMore(Param).separatedBy(',') } - def Param: Rule0 = rule { zeroOrMore(Annotation) ~ IdS ~ optional(':' ~ ParamType) ~ optional('=' ~ Expr) } + def Param: Rule0 = rule { zeroOrMore(Annotation) ~ IdS() ~ optional(':' ~ ParamType) ~ optional('=' ~ Expr()) } def ClassParamClauses: Rule0 = rule { zeroOrMore(ClassParamClause) ~ optional(optional(NewlineS) ~ '(' ~ "implicit" ~ ClassParam ~ ')') } def ClassParamClause: Rule0 = rule { optional(NewlineS) ~ '(' ~ optional(ClassParams) ~ ')' } def ClassParams: Rule0 = rule { oneOrMore(ClassParam).separatedBy(',') } - def ClassParam: Rule0 = rule { zeroOrMore(Annotation) ~ optional(zeroOrMore(Modifier) ~ ("val" | "var")) ~ IdS ~ ":" ~ ParamType ~ optional("=" ~ Expr) } + def ClassParam: Rule0 = rule { zeroOrMore(Annotation) ~ optional(zeroOrMore(Modifier) ~ ("val" | "var")) ~ IdS() ~ ":" ~ ParamType ~ optional("=" ~ Expr()) } def Bindings: Rule0 = rule { '(' ~ oneOrMore(Binding).separatedBy(',') ~ ')' } - def Binding: Rule0 = rule { (IdS | '_') ~ optional(':' ~ Type) } + def Binding: Rule0 = rule { (IdS() | '_') ~ optional(':' ~ Type) } def Modifier: Rule0 = rule { LocalModifier | AccessModifier | "override" } def LocalModifier: Rule0 = rule { "abstract" | "final" | "sealed" | "implicit" | "lazy" } def AccessModifier: Rule0 = rule { ("private" | "protected") ~ optional(AccessQualifier) } - def AccessQualifier: Rule0 = rule { '[' ~ ("this" ~ IdS) ~ ']' } + def AccessQualifier: Rule0 = rule { '[' ~ ("this" ~ IdS()) ~ ']' } - def Annotation: Rule0 = rule { '@' ~ SimpleType ~ zeroOrMore(ArgumentExprs) } - def ConstrAnnotation: Rule0 = rule { '@' ~ SimpleType ~ ArgumentExprs } - def NameValuePair: Rule0 = rule { "val" ~ IdS ~ '=' ~ PrefixExpr } + def Annotation: Rule0 = rule { '@' ~ SimpleType ~ zeroOrMore(ArgumentExprs()) } + def ConstrAnnotation: Rule0 = rule { '@' ~ SimpleType ~ ArgumentExprs() } - def TemplateBody: Rule0 = rule { optional(NewlineS) ~ '{' ~ optional(SelfType) ~ TemplateStat ~ zeroOrMore(SemiS ~ TemplateStat) ~ '}' } - def TemplateStat: Rule0 = rule { + def TemplateBody: Rule0 = rule { optional(NewlineS) ~ '{' ~ optional(SelfType) ~ TemplateStat(false) ~ zeroOrMore(SemiS ~ TemplateStat(false)) ~ '}' } + def TemplateStat(greedy: Boolean = true): Rule0 = rule { Import | - zeroOrMore(Annotation ~ optional(NewlineS)) ~ zeroOrMore(Modifier) ~ (Def | Dcl) | - Expr | - MATCH + zeroOrMore(Annotation ~ optional(NewlineS)) ~ zeroOrMore(Modifier) ~ (Def(greedy) | Dcl) | + Expr(false) | + MATCH } - def SelfType: Rule0 = rule { "this" ~ ':' ~ Type ~ "=>" | IdS ~ optional(':' ~ Type) ~ "=>" } + def SelfType: Rule0 = rule { "this" ~ ':' ~ Type ~ "=>" | IdS() ~ optional(':' ~ Type) ~ "=>" } def Import: Rule0 = rule { "import" ~ oneOrMore(ImportExpr).separatedBy(',') } //ImportExpr is slightly changed wrt spec because StableId always consumes all the Ids possible, so there is no need to one at the end def ImportExpr: Rule0 = rule { StableId ~ optional('.' ~ ('_' | ImportSelectors)) } def ImportSelectors: Rule0 = rule { '{' ~ zeroOrMore(ImportSelector ~ ',') ~ (ImportSelector | '_') ~ '}' } - def ImportSelector: Rule0 = rule { IdS ~ optional("=>" ~ (IdS | '_')) } + def ImportSelector: Rule0 = rule { IdS() ~ optional("=>" ~ (IdS() | '_')) } def Dcl: Rule0 = rule { "val" ~ ValDcl | @@ -211,35 +218,35 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif def ValDcl: Rule0 = rule { Ids ~ ':' ~ Type } def VarDcl: Rule0 = rule { Ids ~ ':' ~ Type } def FunDcl: Rule0 = rule { FunSig ~ optional(':' ~ Type) } - def FunSig: Rule0 = rule { IdS ~ optional(FunTypeParamClause) ~ ParamClauses } - def TypeDcl: Rule0 = rule { IdS ~ optional(TypeParamClause) ~ optional(">:" ~ Type) ~ optional("<:" ~ Type) } - - def PatVarDef: Rule0 = rule { "val" ~ PatDef | "var" ~ VarDef } - def Def: Rule0 = rule { "def" ~ FunDef | "type" ~ zeroOrMore(NewlineS) ~ TypeDef | PatVarDef | TmplDef } - def PatDef: Rule0 = rule { oneOrMore(Pattern2).separatedBy(',') ~ optional(':' ~ Type) ~ '=' ~ Expr } - def VarDef: Rule0 = rule { Ids ~ ':' ~ Type ~ '=' ~ '_' | PatDef } - def FunDef: Rule0 = rule { + def FunSig: Rule0 = rule { IdS() ~ optional(FunTypeParamClause) ~ ParamClauses } + def TypeDcl: Rule0 = rule { IdS() ~ optional(TypeParamClause) ~ optional(">:" ~ Type) ~ optional("<:" ~ Type) } + + def PatVarDef(greedy: Boolean = true): Rule0 = rule { "val" ~ PatDef(greedy) | "var" ~ VarDef(greedy) } + def Def(greedy: Boolean = true): Rule0 = rule { "def" ~ FunDef(greedy) | "type" ~ zeroOrMore(NewlineS) ~ TypeDef | PatVarDef(greedy) | TmplDef } + def PatDef(greedy: Boolean = true): Rule0 = rule { oneOrMore(Pattern2).separatedBy(',') ~ optional(':' ~ Type) ~ '=' ~ Expr(greedy) } + def VarDef(greedy: Boolean = true): Rule0 = rule { Ids ~ ':' ~ Type ~ '=' ~ '_' | PatDef(greedy) } + def FunDef(greedy: Boolean = true): Rule0 = rule { "this" ~ ParamClause ~ ParamClauses ~ ('=' ~ ConstrExpr | optional(NewlineS) ~ ConstrBlock) | - FunSig ~ (optional(':' ~ Type) ~ '=' ~ Expr | optional(NewlineS) ~ '{' ~ Block ~ '}') + FunSig ~ (optional(':' ~ Type) ~ '=' ~ Expr(greedy) | optional(NewlineS) ~ '{' ~ Block ~ '}') } - def TypeDef: Rule0 = rule { IdS ~ optional(TypeParamClause) ~ '=' ~ Type } + def TypeDef: Rule0 = rule { IdS() ~ optional(TypeParamClause) ~ '=' ~ Type } def TmplDef: Rule0 = rule { "trait" ~ TraitDef | optional("case") ~ ("class" ~ ClassDef | "object" ~ ObjectDef) } - def ClassDef: Rule0 = rule { IdS ~ optional(TypeParamClause) ~ zeroOrMore(ConstrAnnotation) ~ optional(AccessModifier) ~ ClassParamClauses ~ ClassTemplateOpt } - def TraitDef: Rule0 = rule { IdS ~ optional(TypeParamClause) ~ TraitTemplateOpt } - def ObjectDef: Rule0 = rule { IdS ~ ClassTemplateOpt } + def ClassDef: Rule0 = rule { IdS() ~ optional(TypeParamClause) ~ zeroOrMore(ConstrAnnotation) ~ optional(AccessModifier) ~ ClassParamClauses ~ ClassTemplateOpt } + def TraitDef: Rule0 = rule { IdS() ~ optional(TypeParamClause) ~ TraitTemplateOpt } + def ObjectDef: Rule0 = rule { IdS() ~ ClassTemplateOpt } def ClassTemplateOpt: Rule0 = rule { "extends" ~ ClassTemplate | optional(optional("extends") ~ TemplateBody) } def TraitTemplateOpt: Rule0 = rule { "extends" ~ TraitTemplate | optional(optional("extends") ~ TemplateBody) } def ClassTemplate: Rule0 = rule { optional(EarlyDefs) ~ ClassParents ~ optional(TemplateBody) } def TraitTemplate: Rule0 = rule { optional(EarlyDefs) ~ TraitParents ~ optional(TemplateBody) } def ClassParents: Rule0 = rule { Constr ~ zeroOrMore("with" ~ AnnotType) } def TraitParents: Rule0 = rule { AnnotType ~ zeroOrMore("with" ~ AnnotType) } - def Constr: Rule0 = rule { AnnotType ~ zeroOrMore(ArgumentExprs) } + def Constr: Rule0 = rule { AnnotType ~ zeroOrMore(ArgumentExprs()) } def EarlyDefs: Rule0 = rule { '{' ~ optional(oneOrMore(EarlyDef).separatedBy(SemiS)) ~ '}' ~ "with" } - def EarlyDef: Rule0 = rule { zeroOrMore(Annotation ~ optional(NewlineS)) ~ zeroOrMore(Modifier) ~ PatVarDef } + def EarlyDef: Rule0 = rule { zeroOrMore(Annotation ~ optional(NewlineS)) ~ zeroOrMore(Modifier) ~ PatVarDef(false) } def ConstrExpr: Rule0 = rule { ConstrBlock | SelfInvocation } def ConstrBlock: Rule0 = rule { '{' ~ SelfInvocation ~ zeroOrMore(SemiS ~ BlockStat) ~ '}' } - def SelfInvocation: Rule0 = rule { "this" ~ oneOrMore(ArgumentExprs) } + def SelfInvocation: Rule0 = rule { "this" ~ oneOrMore(ArgumentExprs()) } def TopStatSeq: Rule0 = rule { oneOrMore(TopStat).separatedBy(SemiS) } def TopStat: Rule0 = rule { Packaging | PackageObject | Import | zeroOrMore(Annotation ~ optional(NewlineS)) ~ zeroOrMore(Modifier) ~ TmplDef | MATCH } |