This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Fwd: Re: parsing incomplete expressions

No replies
Victor Mateus O...
Joined: 2009-02-09,
User offline. Last seen 42 years 45 weeks ago.
(fwd... i forgot reply-all)


Ishaaq,

I have made a ugly but fast way to tab completion. It was made for just a prototype and is very very simple. All work is done by overriding the implicit function keyword of StdTokenParsers.
Look this example:


import scala.util.parsing.combinator._
import scala.util.parsing.combinator.syntactical._

import scala.collection.mutable._

object AutoComplete extends StandardTokenParsers with ImplicitConversions
{
  lexical.reserved ++= List("victor", "victoria", "come", "compra", "roberta", "ronildo")

  val tried_keywords: ListBuffer[String] = new ListBuffer[String]
  var matched: String = ""

  def matchKeyword(expect: String)(e: Elem): Boolean = {
    println("matching: " e.chars + " - expect: " + expect)
    if (expect == e.chars) {
      matched = expect
      true
    }
    else if (expect.startsWith(e.chars)) {
      println("---> " + expect + " startsWith " + e)
      //keep only matched words in list tried_keywords
      for(val v <- tried_keywords if !v.startsWith(e.chars)) tried_keywords -= v
      tried_words += expect
      matched = ""
      false
    }
    else
      false
  }

  def errReport(e: Elem): String = {
    "Err: " + e + " found."
  }

  override implicit def keyword(chars: String): Parser[String] =
    acceptIf(m(chars))(e) ^^ (_.chars)

//the keywords *must* to be ordened to auto-complete works properly!!!  major -> minor
  def cmd: Parser[String] =
    "victoria" | "victor" | "roberta" | "ronildo"

//the keywords *must* to be ordened to auto-complete works properly!!!  major -> minor
  def args: Parser[String] =
    "comprar" | "come"

  def line: Parser[String] =
    cmd ~ args ^^ { case cmd ~ args => cmd + " " + args }

  def parse(r: String) : ParseResult[Any] = {
    tried_words.clear
    matched = ""
    val ret = phrase(line)(new lexical.Scanner(r))
    ret match {
      case Success(_, _) => tried_words.clear; matched = ""
      case _ =>
    }
    ret
  }

}

object Main extends Application
{
  var line: String = ""
  while (true) {
    val c = readLine
    line += c
    println(AutoComplete.parse(line))

    println(AutoComplete.tried_words + AutoComplete.matched)
  }
}


When running, you enter part of the command, hit enter, and it will print the list of matched keywords, then hit the rest of the command.


Feel free to improve this. I think that a better way is to improve the scala combinators parsers library, but it works for while :-)

[]s
Victor


On Mon, Feb 23, 2009 at 7:05 PM, Ishaaq Chandy <ishaaq@gmail.com> wrote:
Yes, I agree writing a parser is relatively easy and I have been able to achieve quite a bit of complexity relatively easily using scala's parser library. Before this I would have had to whip out ANTLR to do what I needed. I do wonder though about how performant writing a parser combinator in scala is when compared to something like a parser compiled from something like ANTLR. Has anyone done any profiling on this?

What I meant in my earlier post was I should read up on how parser combinators are implemented and see if I can come up with my own library (or at least an extension to the scala one) to be able to do all the funky tab-completion and line-completion detection stuff I want to do - but this is pie in the sky stuff - doubt I'll be able to get to that stage any time soon!!! Baby steps first! :)

Ishaaq

2009/2/24 Harshad <harshad.rj@gmail.com>
Ishaaq Chandy wrote:

> Thanks but this is a small side-app that I am writing that may or may not
> be used internally by my team if I am successful with it - I'm doing this
> on my own time more for my own enjoyment and self-improvement rather than
> as part of my day job so I can't really justify buying licenses for third
> party dependencies for it at this point.
>
> But your answer does tell me something - this obviously isn't possible
> with the current parser combinator API in scala or you wouldn't have
> rolled your own. Maybe I should read up on parser combinators and write
> something myself - though that may be a bit more than I can chew at this
> point being a newbie to scala.

IMO, writing the parser combinators in Scala is the easy part. See this link
for a nice exposition on the topic:
http://www.cs.kuleuven.be/publicaties/rapporten/cw/CW491.abs.html

The challenging part is designing the combinator library to do things you
want it to do.

Cheers,
Harshad





--
GNU/Linux user #5f5f5f - http://counter.li.org



--
GNU/Linux user #5f5f5f - http://counter.li.org

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland