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

A proposed new interface for skipping characters automatically#464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
peteraldous wants to merge1 commit intoscala:main
base:main
Choose a base branch
Loading
frompeteraldous:skips
Draft
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -104,7 +104,7 @@ trait PackratParsers extends Parsers {
overridedefphrase[T](p:Parser[T]):PackratParser[T]= {
valq=super.phrase(p)
newPackratParser[T] {
defapply(in:Input)= inmatch {
defparse(in:Input)= inmatch {
casein:PackratReader[_]=> q(in)
case in=> q(newPackratReader(in))
}
Expand DownExpand Up@@ -231,7 +231,7 @@ to update each parser involved in the recursion.
*/
defmemo[T](p:super.Parser[T]):PackratParser[T]= {
newPackratParser[T] {
defapply(in:Input)= {
defparse(in:Input)= {
/*
* transformed reader
*/
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,7 @@
packagescala
packageutil.parsing.combinator

importscala.util.DynamicVariable
importscala.util.parsing.input._
importscala.collection.mutable.ListBuffer
importscala.annotation.tailrec
Expand DownExpand Up@@ -221,7 +222,7 @@ trait Parsers {
}

defParser[T](f:Input=>ParseResult[T]):Parser[T]
=newParser[T]{defapply(in:Input)= f(in) }
=newParser[T]{defparse(in:Input)= f(in) }

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

valskipParser:DynamicVariable[Option[Parser[Any]]]=newDynamicVariable(None);

finaldefskip(in:Input):Input= {
skipParser.valuematch {
caseNone=> in
caseSome(parser)=> {
skipParser.withValue(None) {
parser(in)match {
caseSuccess(_,next)=> {
next
}
// A parser whose purpose is to skip shouldn't fail; it should just not skip stuff
case _=> in
}
}
}
}
}

defOnceParser[T](f:Input=>ParseResult[T]):Parser[T]withOnceParser[T]
=newParser[T]withOnceParser[T] {defapply(in:Input)= f(in) }
=newParser[T]withOnceParser[T] {defparse(in:Input)= f(in) }

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

/** An unspecified method that defines the behaviour of this parser.*/
defapply(in:Input):ParseResult[T]
defparse(in:Input):ParseResult[T]
defapply(in:Input):ParseResult[T]= {
parse(skip(in))
}

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

/** A parser combinator that changes skipping behavior
*/
def<< (toSkip:=>Option[Parser[Any]]):Parser[T]= {
valoriginalParse:Input=>ParseResult[T]= parse
newParser[T] {
overridedefapply(in:Input):ParseResult[T]= {
skipParser.withValue(toSkip) {
parse(skip(in))
}
}
defparse(in:Input):ParseResult[T]= originalParse(in)
}.named(name)
}

// the operator formerly known as +++, ++, &, but now, behold the venerable ~
// it's short, light (looks like whitespace), has few overloaded meaning (thanks to the recent change from ~ to unary_~)
// and we love it! (or do we like `,` better?)
Expand DownExpand Up@@ -324,7 +361,7 @@ trait Parsers {

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

/** A parser combinator for non-back-tracking sequential composition.
Expand DownExpand Up@@ -391,7 +428,7 @@ trait Parsers {
*/
def||| [U>:T](q0:=>Parser[U]):Parser[U]=newParser[U] {
lazyvalq= q0// lazy argument
defapply(in:Input)= {
defparse(in:Input)= {
valres1=Parser.this(in)
valres2= q(in)

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

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

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

applyp(in, failure)
parsep(in, failure)
}

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

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

applyp(in,None)
parsep(in,None)
}

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

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

applyp(in)
parsep(in)
}

mandatory(in)match {
Expand DownExpand Up@@ -973,7 +1010,7 @@ trait Parsers {
* if `p` consumed all the input.
*/
defphrase[T](p:Parser[T])=newParser[T] {
defapply(in:Input)= p(in)match {
defparse(in:Input)= p(in)match {
case s@Success(out, in1)=>
if (in1.atEnd) s
else s.lastFailurematch {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,7 @@ import scala.language.implicitConversions
* }
* }
*
* defapply(input: String): Double = parseAll(expr, input) match {
* defparse(input: String): Double = parseAll(expr, input) match {
* case Success(result, _) => result
* case failure : NoSuccess => scala.sys.error(failure.msg)
* }
Expand DownExpand Up@@ -83,7 +83,7 @@ trait RegexParsers extends Parsers {

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

/** A parser that matches a regex string*/
implicitdefregex(r:Regex):Parser[String]=newParser[String] {
defapply(in:Input)= {
defparse(in:Input)= {
valsource= in.source
valoffset= in.offset
valstart= handleWhiteSpace(source, offset)
Expand All@@ -131,7 +131,7 @@ trait RegexParsers extends Parsers {
overridedefpositioned[T<:Positional](p:=>Parser[T]):Parser[T]= {
valpp=super.positioned(p)
newParser[T] {
defapply(in:Input)= {
defparse(in:Input)= {
valoffset= in.offset
valstart= handleWhiteSpace(in.source, offset)
pp(in.drop (start- offset))
Expand All@@ -141,7 +141,7 @@ trait RegexParsers extends Parsers {

// we might want to make it public/protected in a future version
privatedefws[T](p:Parser[T]):Parser[T]=newParser[T] {
defapply(in:Input)= {
defparse(in:Input)= {
valoffset= in.offset
valstart= handleWhiteSpace(in.source, offset)
p(in.drop (start- offset))
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,9 +32,6 @@ trait Scanners extends Parsers {
/** A parser that produces a token (from a stream of characters).*/
deftoken:Parser[Token]

/** A parser for white-space -- its result will be discarded.*/
defwhitespace:Parser[Any]

/** `Scanner` is essentially¹ a parser that produces `Token`s
* from a stream of characters. The tokens it produces are typically
* passed to parsers in `TokenParsers`.
Expand All@@ -44,21 +41,18 @@ trait Scanners extends Parsers {
classScanner(in:Reader[Char])extendsReader[Token] {
/** Convenience constructor (makes a character reader out of the given string)*/
defthis(in:String)=this(newCharArrayReader(in.toCharArray))
privateval (tok, rest1, rest2)= whitespace(in)match {
caseSuccess(_, in1)=>
token(in1)match {
caseSuccess(tok, in2)=> (tok, in1, in2)
casens:NoSuccess=> (errorToken(ns.msg), ns.next, skip(ns.next))
}
casens:NoSuccess=> (errorToken(ns.msg), ns.next, skip(ns.next))
privatevalin1= skip(in)
privateval (tok, rest1, rest2)= token(in1)match {
caseSuccess(tok, in2)=> (tok, in1, in2)
casens:NoSuccess=> (errorToken(ns.msg), ns.next, skipChar(ns.next))
}
privatedefskip(in:Reader[Char])=if (in.atEnd) inelse in.rest
privatedefskipChar(in:Reader[Char])=if (in.atEnd) inelse in.rest

overridedefsource: java.lang.CharSequence= in.source
overridedefoffset:Int= in.offset
deffirst= tok
defrest=newScanner(rest2)
defpos= rest1.pos
defatEnd= in.atEnd||(whitespace(in)match {caseSuccess(_, in1)=> in1.atEndcase _=>false })
defatEnd= in.atEnd||skip(in).atEnd
}
}

[8]ページ先頭

©2009-2025 Movatter.jp