Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit03a73d0

Browse files
committed
A proposed new interface for skipping characters automatically - implemented for Scanners but not yet for RegexParsers
1 parenta7ffec9 commit03a73d0

File tree

4 files changed

+66
-35
lines changed

4 files changed

+66
-35
lines changed

‎shared/src/main/scala/scala/util/parsing/combinator/PackratParsers.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ trait PackratParsers extends Parsers {
104104
overridedefphrase[T](p:Parser[T]):PackratParser[T]= {
105105
valq=super.phrase(p)
106106
newPackratParser[T] {
107-
defapply(in:Input)= inmatch {
107+
defparse(in:Input)= inmatch {
108108
casein:PackratReader[_]=> q(in)
109109
case in=> q(newPackratReader(in))
110110
}
@@ -231,7 +231,7 @@ to update each parser involved in the recursion.
231231
*/
232232
defmemo[T](p:super.Parser[T]):PackratParser[T]= {
233233
newPackratParser[T] {
234-
defapply(in:Input)= {
234+
defparse(in:Input)= {
235235
/*
236236
* transformed reader
237237
*/

‎shared/src/main/scala/scala/util/parsing/combinator/Parsers.scala

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
packagescala
1414
packageutil.parsing.combinator
1515

16+
importscala.util.DynamicVariable
1617
importscala.util.parsing.input._
1718
importscala.collection.mutable.ListBuffer
1819
importscala.annotation.tailrec
@@ -221,7 +222,7 @@ trait Parsers {
221222
}
222223

223224
defParser[T](f:Input=>ParseResult[T]):Parser[T]
224-
=newParser[T]{defapply(in:Input)= f(in) }
225+
=newParser[T]{defparse(in:Input)= f(in) }
225226

226227
private[combinator]defSuccess[U](res:U,next:Input,failure:Option[Failure]):ParseResult[U]=
227228
newSuccess(res, next) {overridevallastFailure:Option[Failure]= failure }
@@ -236,8 +237,27 @@ trait Parsers {
236237
case _=>None
237238
}
238239

240+
valskipParser:DynamicVariable[Option[Parser[Any]]]=newDynamicVariable(None);
241+
242+
finaldefskip(in:Input):Input= {
243+
skipParser.valuematch {
244+
caseNone=> in
245+
caseSome(parser)=> {
246+
skipParser.withValue(None) {
247+
parser(in)match {
248+
caseSuccess(_,next)=> {
249+
next
250+
}
251+
// A parser whose purpose is to skip shouldn't fail; it should just not skip stuff
252+
case _=> in
253+
}
254+
}
255+
}
256+
}
257+
}
258+
239259
defOnceParser[T](f:Input=>ParseResult[T]):Parser[T]withOnceParser[T]
240-
=newParser[T]withOnceParser[T] {defapply(in:Input)= f(in) }
260+
=newParser[T]withOnceParser[T] {defparse(in:Input)= f(in) }
241261

242262
/** The root class of parsers.
243263
* Parsers are functions from the Input type to ParseResult.
@@ -248,7 +268,10 @@ trait Parsers {
248268
overridedeftoString=s"Parser ($name)"
249269

250270
/** An unspecified method that defines the behaviour of this parser.*/
251-
defapply(in:Input):ParseResult[T]
271+
defparse(in:Input):ParseResult[T]
272+
defapply(in:Input):ParseResult[T]= {
273+
parse(skip(in))
274+
}
252275

253276
defflatMap[U](f:T=>Parser[U]):Parser[U]
254277
=Parser{ in=>this(in) flatMapWithNext(f)}
@@ -268,6 +291,20 @@ trait Parsers {
268291
Parser{ in=>this(in) append p(in)}
269292
}
270293

294+
/** A parser combinator that changes skipping behavior
295+
*/
296+
def<< (toSkip:=>Option[Parser[Any]]):Parser[T]= {
297+
valoriginalParse:Input=>ParseResult[T]= parse
298+
newParser[T] {
299+
overridedefapply(in:Input):ParseResult[T]= {
300+
skipParser.withValue(toSkip) {
301+
parse(skip(in))
302+
}
303+
}
304+
defparse(in:Input):ParseResult[T]= originalParse(in)
305+
}.named(name)
306+
}
307+
271308
// the operator formerly known as +++, ++, &, but now, behold the venerable ~
272309
// it's short, light (looks like whitespace), has few overloaded meaning (thanks to the recent change from ~ to unary_~)
273310
// and we love it! (or do we like `,` better?)
@@ -324,7 +361,7 @@ trait Parsers {
324361

325362
/* not really useful: V cannot be inferred because Parser is covariant in first type parameter (V is always trivially Nothing)
326363
def ~~ [U, V](q: => Parser[U])(implicit combine: (T, U) => V): Parser[V] = new Parser[V] {
327-
defapply(in: Input) = seq(Parser.this, q)((x, y) => combine(x,y))(in)
364+
defparse(in: Input) = seq(Parser.this, q)((x, y) => combine(x,y))(in)
328365
}*/
329366

330367
/** A parser combinator for non-back-tracking sequential composition.
@@ -391,7 +428,7 @@ trait Parsers {
391428
*/
392429
def||| [U>:T](q0:=>Parser[U]):Parser[U]=newParser[U] {
393430
lazyvalq= q0// lazy argument
394-
defapply(in:Input)= {
431+
defparse(in:Input)= {
395432
valres1=Parser.this(in)
396433
valres2= q(in)
397434

@@ -427,7 +464,7 @@ trait Parsers {
427464
*/
428465
def^^^ [U](v:=>U):Parser[U]=newParser[U] {
429466
lazyvalv0= v// lazy argument
430-
defapply(in:Input)=Parser.this(in) map (x=> v0)
467+
defparse(in:Input)=Parser.this(in) map (x=> v0)
431468
}.named(toString+"^^^")
432469

433470
/** A parser combinator for partial function application.
@@ -769,18 +806,18 @@ trait Parsers {
769806

770807
defcontinue(in:Input,failure:Option[Failure]):ParseResult[List[T]]= {
771808
valp0= p// avoid repeatedly re-evaluating by-name parser
772-
@tailrecdefapplyp(in0:Input,failure:Option[Failure]):ParseResult[List[T]]= p0(in0)match {
809+
@tailrecdefparsep(in0:Input,failure:Option[Failure]):ParseResult[List[T]]= p0(in0)match {
773810
case s@Success(x, rest)=>
774811
valselectedFailure= selectLastFailure(s.lastFailure, failure)
775812
elems+= x
776-
applyp(rest, selectedFailure)
813+
parsep(rest, selectedFailure)
777814
case e@Error(_, _)=> e// still have to propagate error
778815
casef:Failure=>
779816
valselectedFailure= selectLastFailure(failure,Some(f))
780817
Success(elems.toList, in0, selectedFailure)
781818
}
782819

783-
applyp(in, failure)
820+
parsep(in, failure)
784821
}
785822

786823
first(in)match {
@@ -804,14 +841,14 @@ trait Parsers {
804841
valelems=newListBuffer[T]
805842
valp0= p// avoid repeatedly re-evaluating by-name parser
806843

807-
@tailrecdefapplyp(in0:Input,failure:Option[Failure]):ParseResult[List[T]]=
844+
@tailrecdefparsep(in0:Input,failure:Option[Failure]):ParseResult[List[T]]=
808845
if (elems.length== num)Success(elems.toList, in0, failure)
809846
else p0(in0)match {
810-
case s@Success(x, rest)=> elems+= x ;applyp(rest, s.lastFailure)
847+
case s@Success(x, rest)=> elems+= x ;parsep(rest, s.lastFailure)
811848
casens:NoSuccess=> ns
812849
}
813850

814-
applyp(in,None)
851+
parsep(in,None)
815852
}
816853

817854
/** A parser generator for a specified range of repetitions interleaved by a
@@ -835,13 +872,13 @@ trait Parsers {
835872

836873
defcontinue(in:Input):ParseResult[List[T]]= {
837874
valp0= sep~> p// avoid repeatedly re-evaluating by-name parser
838-
@tailrecdefapplyp(in0:Input):ParseResult[List[T]]= p0(in0)match {
839-
caseSuccess(x, rest)=> elems+= x;if (elems.length== m)Success(elems.toList, rest,None)elseapplyp(rest)
875+
@tailrecdefparsep(in0:Input):ParseResult[List[T]]= p0(in0)match {
876+
caseSuccess(x, rest)=> elems+= x;if (elems.length== m)Success(elems.toList, rest,None)elseparsep(rest)
840877
case e@Error(_, _)=> e// still have to propagate error
841878
case _=>Success(elems.toList, in0,None)
842879
}
843880

844-
applyp(in)
881+
parsep(in)
845882
}
846883

847884
mandatory(in)match {
@@ -973,7 +1010,7 @@ trait Parsers {
9731010
* if `p` consumed all the input.
9741011
*/
9751012
defphrase[T](p:Parser[T])=newParser[T] {
976-
defapply(in:Input)= p(in)match {
1013+
defparse(in:Input)= p(in)match {
9771014
case s@Success(out, in1)=>
9781015
if (in1.atEnd) s
9791016
else s.lastFailurematch {

‎shared/src/main/scala/scala/util/parsing/combinator/RegexParsers.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import scala.language.implicitConversions
4848
* }
4949
* }
5050
*
51-
* defapply(input: String): Double = parseAll(expr, input) match {
51+
* defparse(input: String): Double = parseAll(expr, input) match {
5252
* case Success(result, _) => result
5353
* case failure : NoSuccess => scala.sys.error(failure.msg)
5454
* }
@@ -83,7 +83,7 @@ trait RegexParsers extends Parsers {
8383

8484
/** A parser that matches a literal string*/
8585
implicitdefliteral(s:String):Parser[String]=newParser[String] {
86-
defapply(in:Input)= {
86+
defparse(in:Input)= {
8787
valsource= in.source
8888
valoffset= in.offset
8989
valstart= handleWhiteSpace(source, offset)
@@ -104,7 +104,7 @@ trait RegexParsers extends Parsers {
104104

105105
/** A parser that matches a regex string*/
106106
implicitdefregex(r:Regex):Parser[String]=newParser[String] {
107-
defapply(in:Input)= {
107+
defparse(in:Input)= {
108108
valsource= in.source
109109
valoffset= in.offset
110110
valstart= handleWhiteSpace(source, offset)
@@ -131,7 +131,7 @@ trait RegexParsers extends Parsers {
131131
overridedefpositioned[T<:Positional](p:=>Parser[T]):Parser[T]= {
132132
valpp=super.positioned(p)
133133
newParser[T] {
134-
defapply(in:Input)= {
134+
defparse(in:Input)= {
135135
valoffset= in.offset
136136
valstart= handleWhiteSpace(in.source, offset)
137137
pp(in.drop (start- offset))
@@ -141,7 +141,7 @@ trait RegexParsers extends Parsers {
141141

142142
// we might want to make it public/protected in a future version
143143
privatedefws[T](p:Parser[T]):Parser[T]=newParser[T] {
144-
defapply(in:Input)= {
144+
defparse(in:Input)= {
145145
valoffset= in.offset
146146
valstart= handleWhiteSpace(in.source, offset)
147147
p(in.drop (start- offset))

‎shared/src/main/scala/scala/util/parsing/combinator/lexical/Scanners.scala

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ trait Scanners extends Parsers {
3232
/** A parser that produces a token (from a stream of characters).*/
3333
deftoken:Parser[Token]
3434

35-
/** A parser for white-space -- its result will be discarded.*/
36-
defwhitespace:Parser[Any]
37-
3835
/** `Scanner` is essentially¹ a parser that produces `Token`s
3936
* from a stream of characters. The tokens it produces are typically
4037
* passed to parsers in `TokenParsers`.
@@ -44,21 +41,18 @@ trait Scanners extends Parsers {
4441
classScanner(in:Reader[Char])extendsReader[Token] {
4542
/** Convenience constructor (makes a character reader out of the given string)*/
4643
defthis(in:String)=this(newCharArrayReader(in.toCharArray))
47-
privateval (tok, rest1, rest2)= whitespace(in)match {
48-
caseSuccess(_, in1)=>
49-
token(in1)match {
50-
caseSuccess(tok, in2)=> (tok, in1, in2)
51-
casens:NoSuccess=> (errorToken(ns.msg), ns.next, skip(ns.next))
52-
}
53-
casens:NoSuccess=> (errorToken(ns.msg), ns.next, skip(ns.next))
44+
privatevalin1= skip(in)
45+
privateval (tok, rest1, rest2)= token(in1)match {
46+
caseSuccess(tok, in2)=> (tok, in1, in2)
47+
casens:NoSuccess=> (errorToken(ns.msg), ns.next, skipChar(ns.next))
5448
}
55-
privatedefskip(in:Reader[Char])=if (in.atEnd) inelse in.rest
49+
privatedefskipChar(in:Reader[Char])=if (in.atEnd) inelse in.rest
5650

5751
overridedefsource: java.lang.CharSequence= in.source
5852
overridedefoffset:Int= in.offset
5953
deffirst= tok
6054
defrest=newScanner(rest2)
6155
defpos= rest1.pos
62-
defatEnd= in.atEnd||(whitespace(in)match {caseSuccess(_, in1)=> in1.atEndcase _=>false })
56+
defatEnd= in.atEnd||skip(in).atEnd
6357
}
6458
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp