So,i think whether it's better to change loop.
unicode escape = "\", "u", { "u" }, hex digit, hex digit, hex digit, hex digit;
hex digit = "0" | "1" | "2" | "3" | "4" | "5" | "6"| "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" ;
(*
Lexical Syntax
================================
*)
white space = "\u0020" | "\u0009" | "\u000D" | "\u000A" ;
upper = "A" | "B" | "C" | "D" | "E" | "F" | "G"
| "H" | "I" | "J" | "K" | "L" | "M" | "N"
| "O" | "P" | "Q" | "R" | "S" | "T" | "U"
| "V" | "W" | "X" | "Y" | "Z" | "$" | "_" ;
(*
>upper δΉε
ε« Unicode category Lu
*)
lower = "a" | "b"
| "c" | "d" | "e" | "f" | "g" | "h" | "i"
| "j" | "k" | "l" | "m" | "n" | "o" | "p"
| "q" | "r" | "s" | "t" | "u" | "v" | "w"
| "x" | "y" | "z" ;
(*
>lower δΉε
ε« Unicode category Ll
*)
letter = upper | lower;
(*
>letter ε
ε« Unicode categories Lo, Lt, Nl ;
*)
paren = "(" | ")" | "[" | "]" | "{" | "}" ;
delim = "`" | "'" | '"' | "." | ";" | "," ;
opchar = white space | upper | lower | letter | digit | paren | delim | opchar | "Unicode_Sm" | "Unicode_So";
printable char = "all characters in [\u0020, \u007F] inclusive";
char escape seq = "\", ("b" | "t" | "n" | "f" | "r" | '"' | "'" | "\") ;
op = opchar, {opchar} ;
varid = lower, idrest ;
plainid = upper, idrest | varid | op ;
id = plainid | "`" , { "char no back quote or newline" | unicode escape | char escape seq } ,"`" ;
idrest = {letter | digit} ,["_" , op] ;
integer literal = (decimal numeral | hex numeral) ,["L" | "l"] ;
decimal numeral = "0" | non zero digit ,{digit} ;
hex numeral = "0" ,("x" | "X"), hex digit ,{hex digit} ;
digit = "0" | non zero digit ;
non zero digit = "1" | "2" | "3" | "4" | "5" | "6"| "7" | "8" | "9" ;
floating point literal = digit ,{digit} ,"." ,digit ,{digit} ,[exponent part], [float type]
| "." ,digit, {digit}, [exponent part], [float type]
| digit, {digit} ,exponent part, [float type]
| digit ,{digit}, [exponent part], float type ;
exponent part = ("E" | "e") ,["+" | "-"], digit, {digit} ;
float type = "F" | "f" | "D" | "d" ;
boolean literal = "true" | "false" ;
character literal = "'", ("char no quote or newline" | unicode escape | char escape seq) ,"'" ;
string literal = '"', {string element} ,'"'
| '"""' ,multi line chars, '"""' ;
string element = "char no double quote or newline"
| unicode escape
| char escape seq ;
multi line chars = {['"'], ['"'], "char no double quote"}, {'"'} ;
symbol literal = "'", plainid ;
comment = "/*", "any sequence of characters; nested comments are allowed", "*/"
| "//" ,"any sequence of characters up to end of line" ;
nl = "newlinecharacter" ;
semi = ";" | nl, {nl} ;
(*
Context-free Syntax
================================
*)
literal = ['-'], integer literal
| ['-'], floating point literal
| boolean literal
| character literal
| string literal
| symbol literal
| "null" ;
qual id = id ,{'.', id} ;
ids = id ,{',', id} ;
path = stable id
| [id ,'.'] ,'this' ;
stable id = id
| path ,'.', id
| [id, '.'] ,'super', [class qualifier], '.', id ;
class qualifier = '[', id ,']' ;
type = function arg types ,"=>", type
| infix type ,[existential clause] ;
function arg types = infix type
| "(", [ param type, {"," ,param type } ] ,")" ;
existential clause = "forSome", "{", existential dcl, {semi ,existential dcl} ,"}" ;
existential dcl = "type", type dcl
| "val" ,val dcl ;
infix type = compound type ,{id ,[nl], compound type} ;
compound type = annot type ,{"with" ,annot type}, [refinement]
| refinement ;
annot type = simple type, {annotation} ;
simple type = simple type, type args
| simple type, "#", id
| stable id
| path ,"." ,"type"
| "(", types ,")" ;
type args = "[", types ,"]" ;
types = type, {"," ,type} ;
refinement = [nl], "{", refine stat, {semi ,refine stat} ,"}" ;
refine stat = dcl | "type" ,type def ;
type pat = type ;
ascription = ":", infix type
| ":", annotation, {annotation}
| ":", "_", "*" ;
expr = (bindings | ["implicit"], id | "_") ,"=>", expr
| expr1 ;
expr1 = "if", "(", expr ,")" ,{nl} ,expr ,[[semi] ,"else", expr]
| "while", "(" ,expr ,")", {nl}, expr
| "try" ,("{", block, "}" | expr), ["catch", "{", case clauses ,"}"] ,["finally" ,expr]
| "do", expr ,[semi] ,"while", "(", expr ,")"
| "for", ("(", enumerators ,")" | "{", enumerators ,"}") ,{nl} ,["yield"] ,expr
| "throw", expr
| "return" ,[expr]
| [simple expr, "."] ,id ,"=" ,expr
| simple expr1, argument exprs, "=", expr
| postfix expr
| postfix expr ,ascription
| postfix expr ,"match" ,"{" ,case clauses ,"}" ;
postfix expr = infix expr ,[id ,[nl]] ;
infix expr = prefix expr
| infix expr ,id ,[nl] ,infix expr ;
prefix expr = ["-" | "+" | "~" | "!"] ,simple expr ;
simple expr = "new" ,(class template | template body)
| block expr
| simple expr1 ,["_"] ;
simple expr1 = literal
| path
| "_"
| "(" ,[exprs] ,")"
| simple expr ,"." ,id
| simple expr ,type args
| simple expr1 ,argument exprs
| "xml expr" ;
exprs = expr ,{"," ,expr} ;
argument exprs = "(" ,[exprs] ,")"
| "(" ,[exprs ,","] ,postfix expr ,":" ,"_" ,"*" ,")"
| [nl] ,block expr ;
block expr = "{" ,case clauses ,"}"
| "{" ,block ,"}" ;
block = block stat ,{semi ,block stat}, [result expr] ;
block stat = import
| {annotation} ,["implicit" | "lazy"] ,def
| {annotation} ,{local modifier} ,tmpl def
| expr1 ;
result expr = expr1
| (bindings | (["implicit"], id | "_"), ":", compound type) ,"=>", block ;
enumerators = generator ,{semi ,generator} ;
generator = pattern1 ,"<-", expr ,{[semi] ,guard | semi ,pattern1 ,"=" ,expr} ;
case clauses = case clause ,{ case clause } ;
case clause = "case" ,pattern ,[guard] ,"=>" ,block ;
guard = "if", postfix expr ;
pattern = pattern1 ,{ "|", pattern1 } ;
pattern1 = varid ,":", type pat
| "_" ,":" ,type pat
| pattern2 ;
pattern2 = varid ,["@", pattern3]
| pattern3 ;
pattern3 = simple pattern
| simple pattern ,{ id ,[nl] ,simple pattern } ;
simple pattern = "_"
| varid
| literal
| stable id
| stable id ,"(" ,[patterns] ,")"
| stable id ,"(" ,[patterns ,","], [varid ,"@"] ,"_" ,"*" ,")"
| "(" ,[patterns] ,")"
| "xml pattern" ;
patterns = pattern ,["," ,patterns]
| "_" ,"*" ;
type param clause = "[", variant type param ,{",", variant type param} ,"]" ;
funtype param clause= "[" ,type param ,{"," ,type param} ,"]" ;
variant type param = {annotation} ,["+" | "-"] ,type param ;
type param = (id | "_"), [type param clause] ,[">:", type], ["<:" ,type] ,{"<%" ,type}, {":", type} ;
param clauses = {param clause} ,[[nl] ,"(", "implicit", params ,")"] ;
param clause = [nl], "(" ,[params] ,")" ;
params = param ,{",", param} ;
param = {annotation} ,id ,[":", param type] ,["=" ,expr] ;
param type = type
| "=>", type
| type ,"*" ;
class param clauses = {class param clause} , [[nl] ,"(" ,"implicit" ,class params ,")"] ;
class param clause = [nl] ,"(", [class params] ,")" ;
class params = class param ,{"," ,class param} ;
class param = {annotation} ,{modifier} , [("val" | "var")] , id ,":" ,param type ,["=" ,expr];
bindings = "(" ,binding ,{"," ,binding} ,")" ;
binding = (id | "_") ,[":" ,type] ;
modifier = local modifier
| access modifier
| "override" ;
local modifier = "abstract"
| "final"
| "sealed"
| "implicit"
| "lazy" ;
access modifier = ("private" | "protected") ,[access qualifier] ;
access qualifier = "[" ,(id | "this") ,"]" ;
annotation = "@" ,simple type ,{argument exprs} ;
constrannotation = "@" ,simple type ,argument exprs ;
template body = [nl] ,"{" ,[self type] ,template stat, {semi ,template stat} ,"}" ;
template stat = import
| {annotation ,[nl]} ,{modifier} ,def
| {annotation ,[nl]} ,{modifier} ,dcl
| expr ;
self type = id ,[":" ,type] ,"=>"
| "this" ,":" ,type ,"=>" ;
import = "import", import expr ,{"," ,import expr} ;
import expr = stable id ,"." ,(id | "_" | import selectors) ;
import selectors = "{" ,{import selector ,","} ,(import selector | "_") ,"}" ;
import selector = id ,["=>" ,id | "=>" ,"_"] ;
dcl = "val" ,val dcl
| "var" ,var dcl
| "def" ,fun dcl
| "type" ,{nl} ,type dcl ;
val dcl = ids ,":" ,type ;
var dcl = ids ,":" ,type ;
fun dcl = fun sig ,[":" ,type] ;
fun sig = id ,[funtype param clause] ,param clauses ;
type dcl = id ,[type param clause] ,[">:" ,type] ,["<:" ,type] ;
pat var def = "val" ,pat def
| "var" ,var def ;
def = pat var def
| "def" ,fun def
| "type" ,{nl} ,type def
| tmpl def ;
pat def = pattern2 ,{"," ,pattern2} ,[":" ,type] ,"=" ,expr ;
var def = pat def
| ids ,":" ,type ,"=" ,"_" ;
fun def = fun sig ,[":" ,type] ,"=" ,expr
| fun sig ,[nl] ,"{" ,block ,"}"
| "this" ,param clause ,param clauses ,("=" ,constr expr | [nl] ,constr block) ;
type def = id ,[type param clause] ,"=" ,type ;
tmpl def = ["case"] ,"class" ,class def
| ["case"] ,"object" ,object def
| "trait" ,trait def ;
class def = id ,[type param clause] ,{constrannotation}, [access modifier] ,class param clauses ,class template opt ;
trait def = id ,[type param clause] ,trait template opt ;
object def = id ,class template opt ;
class template opt = "extends" ,class template | [["extends"] ,template body] ;
trait template opt = "extends" ,trait template | [["extends"] ,template body] ;
class template = [early defs], class parents, [template body] ;
trait template = [early defs], trait parents ,[template body] ;
class parents = constr ,{"with" ,annot type} ;
trait parents = annot type ,{"with" ,annot type} ;
constr = annot type ,{argument exprs} ;
early defs = "{" ,[early def ,{semi ,early def}] ,"}" ,"with" ;
early def = {annotation ,[nl]} ,{modifier} ,pat var def ;
constr expr = self invocation
| constr block ;
constr block = "{" ,self invocation ,{semi ,block stat} ,"}" ;
self invocation = "this" ,argument exprs ,{argument exprs} ;
top stat seq = top stat, {semi ,top stat} ;
top stat = {annotation ,[nl]} ,{modifier} ,tmpl def
| import
| packaging
| package object ;
packaging = "package" ,qual id ,[nl] ,"{" ,top stat seq ,"}" ;
package object = "package" ,"object" ,object def ;
compilation unit = {"package" ,qual id ,semi} ,top stat seq ;