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

Commit 7f86709

Browse files
Merge pull request #370 from ilya-klyuchnikov/phrase
2 parents 55a539d + 1e703fe commit 7f86709

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ trait PackratParsers extends Parsers {
101101
* Overridden to make sure any input passed to the argument parser
102102
* is wrapped in a `PackratReader`.
103103
*/
104-
override def phrase[T](p: Parser[T]) = {
104+
override def phrase[T](p: Parser[T]):PackratParser[T] = {
105105
val q = super.phrase(p)
106106
new PackratParser[T] {
107107
def apply(in: Input) = in match {

‎shared/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,35 @@ class PackratParsersTest {
133133
assertFailure("end of input", "a a a a b b b b c c c")
134134
}
135135

136+
@Test
137+
def test4: Unit = {
138+
import grammars4._
139+
import grammars4.parser._
140+
141+
def extractResult(r: ParseResult[Res]): Res = r match {
142+
case Success(a,_) => a
143+
case NoSuccess(a,_) => sys.error(a)
144+
case Failure(a, _) => sys.error(a)
145+
case Error(a, _) => sys.error(a)
146+
}
147+
def check(expected: Term, input: String, ctx: Ctx): Unit = {
148+
val parseResult = phraseTerm(new lexical.Scanner(input))
149+
val result = extractResult(parseResult)
150+
val term = result(ctx)
151+
assertEquals(expected, term)
152+
}
153+
154+
check(Var(-1, 0), "x", Nil)
155+
check(Var(0, 3), "x", List("x", "y", "z"))
156+
check(Var(1, 3), "y", List("x", "y", "z"))
157+
check(Var(2, 3), "z", List("x", "y", "z"))
158+
159+
check(App(Var(0, 2), Var(1, 2)), "x y", List("x", "y"))
160+
check(App(App(Var(0, 2), Var(1, 2)), Var(0, 2)), "x y x", List("x", "y"))
161+
check(App(App(Var(0, 2), Var(1, 2)), Var(0, 2)), "(x y) x", List("x", "y"))
162+
check(Abs(App(App(Var(0, 1), Var(0, 1)), Var(0, 1))), """\x. x x x""", List())
163+
}
164+
136165
}
137166

138167
private object grammars1 extends StandardTokenParsers with PackratParsers {
@@ -195,3 +224,26 @@ private object grammars3 extends StandardTokenParsers with PackratParsers {
195224
p~opt(repMany(p,q))~q ^^ {case x~Some(xs)~y => x::xs:::(y::Nil)}
196225

197226
}
227+
228+
private object grammars4 {
229+
// untyped lambda calculus with named vars -> de brujin indices conversion on the fly
230+
// Adapted from https://github.com/ilya-klyuchnikov/tapl-scala/blob/master/src/main/scala/tapl/untyped/parser.scala
231+
sealed trait Term
232+
case class Var(i: Int, cl: Int) extends Term
233+
case class Abs(t: Term) extends Term
234+
case class App(t1: Term, t2: Term) extends Term
235+
236+
object parser extends StandardTokenParsers with PackratParsers {
237+
lexical.delimiters ++= List("(", ")", ".", "\\")
238+
239+
type Res = Ctx => Term
240+
type Ctx = List[String]
241+
242+
private val term: PackratParser[Res] = app | atom | abs
243+
private val atom: PackratParser[Res] = "(" ~> term <~ ")" | id
244+
private val id : PackratParser[Res] = ident ^^ { n => (c: Ctx) => Var(c.indexOf(n), c.length) }
245+
private val app : PackratParser[Res] = (app ~ atom) ^^ {case t1 ~ t2 => (c: Ctx) => App(t1(c), t2(c)) } | atom
246+
private val abs : PackratParser[Res] = "\\" ~> ident ~ ("." ~> term) ^^ {case v ~ t => (c: Ctx) => Abs(t(v::c))}
247+
val phraseTerm : PackratParser[Res] = phrase(term)
248+
}
249+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /