Skip to main content

Scala combinator parser



This is my attempt to get you started with scala combinator parser. It is a very powerful tool that allows you to create your own lexical analysis similar to yacc and other lexer. Area of application includes

a) calculator that accept input string as follow "3+2"

b) match specific text in a given string like finding "fox" in the string "the brown fox jump over the fence"

I'm going to use an example from reference below. Here we are trying to extend our SimpleParser from RegexParser and defined a function called "word" that is basically a regex itself with the purpose of matching a single word.

Simple Parser

This code is taken from https://wiki.scala-lang.org/

import scala.util.parsing.combinator._

class SimpleParser extends RegexParsers {
  def word: Parser[String]    = """[a-z]+""".r ^^ { _.toString }
}

In code above, """ means it is a regex.  

^^ mean if  a match is found, you execute the following code which is { _.toString }

object TestSimpleParser extends SimpleParser {
  def main(args: Array[String]) = println(parse(word, "johnny come lately"))
}

I will call parse method and give it a parsing point called "word".  parse method has the following method signature.

  def parse[T](p: Parser[T], in: Reader[Char]): ParseResult[T] = p(in)

But not important now.

As a result of this execution you get "johnny" after you pass in "johnny come lately",


Word Count Parser

Next we going to look at another example. This time, we will count how many words we have in a string.

class SimpleParser extends RegexParsers {
  def count(a : List[String]):Int = {
    return a.length
  }
  def word: Parser[String]   = """[a-z]+""".r   ^^ { _.toString }
  def freq: Parser[Int] = word.* ^^ { count(_) }
}



object TestSimpleParser extends SimpleParser {
  def main(args: Array[String]) = {
    parse(freq, "johnny and the love of the world") match {
      case Success(matched,_) => println(matched)
      case Failure(msg,_) => println("FAILURE: " + msg)
      case Error(msg,_) => println("ERROR: " + msg)
    }
  }
}


I will call parse method and give it a parsing point called "freq".

When you execute it, you should get 7.

Some symbols of interest. 

p1 ~ p2 - // sequencing: must match p1 followed by p2
p1 |  p2 - // alternation: must match either p1 or p2, with preference given to p1
p1.? - optionally may match p1 or not
p1.* - repetition - matches any number of repetition of p1

Where to go from here, try this site for more examples.


References

To get a better understanding of how it works,  please refer to here and here.

Comments

Popular posts from this blog

Android Programmatically apply style to your view

Applying style to your view (button in this case) dynamically is pretty easy. All you have to do is place the following in your layout folder (res/layout)
Let's call this file : buttonstyle.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" > <shape> <solid android:color="#449def" /> <stroke android:width="1dp" android:color="#2f6699" /> <corners android:radius="3dp" /> <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" /> </shape> </item> <item> <shape> <gradient android:startColor="#449def" a…

OpenCover code coverage for .Net Core

I know there are many post out there getting code coverage for .dotnetcore. I'm using opencover to address this needs.

In case, you do no want to use opencover and wanted to stick with vs2015 code coverage, you can try to copy Microsoft.VisualStudio.CodeCoverage.Shim.dll from C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Dynamic Code Coverage Tools\coreclr\ and drop it into your project "bin\Debug\netcoreapp1.0" folder.  Please note : you need to be on VS2015 Enterprise to do this. 

To get started, I guess we need to add OpenCover and ReportGenerator for our test projects, as shown in diagram below :-



When nuget packge gets restored, we will have some binaries downloaded to our machine and we going to use this to generate some statistics. I think the biggest issue is to getting those command lines work.

In dotnetcore, we run test project using "dotnet test" (assuming you are in the test project folder - if not please go there)  So we add this …

DataTable does not have AsEnumerable

I have problem locating my AsEnumerable extension method in my DataTabe (System.Data). Thank god for this post by Angel
(http://blogs.msdn.com/angelsb/archive/2007/02/23/does-not-contain-a-definition-for.aspx)

I was able to find this method once i have added reference to the following assembly.

C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll

Try to do a dummy Build and you should be able to get it.