Building ODataURI Parser with Scala Parser Combinators

Objective

Open Data Protocol (ODATA) facilitates end-users to access the data-model via REST-based data services by utilizing Uniform Resource Identifiers (URIs). In this post, we present the result of our recent experiment to build an abstraction on ODATA URIs to generate AST (Abstract Syntax Tree).

Note that this experiment is in its initial stage; hence, the implementation does not support complete feature-set of ODATA URI specification outlined at odata.org. It states a set of recommendations to construct these URIs to effectively identify data and metadata exposed by ODATA services.

To give an example of ODATA URI, consider following URI:

http://odata.org/service.svc/Products?$filter=Price ge 10

It in essence refers to a service request to return all the Product entities that satisfies the following predicate: Price greater than or equal to 10.

Motivation

Primary motivation of building such abstraction is to promote separation-of-concern and consequently, to allow the underlying layers of ODATA service implementation to process query expression tree and yield the result-set in a more efficient manner.

Approach

To implement this parser, we use Parser Combinators, which is in essence a higher-order function that accepts a set of parsers as input and composes them, applies transformations and generates more complex parser. By employing theoretical foundations of function composition, it allows constructing complex parser in an incremental manner.

Scala facilitates such libraries in its standard distribution (see scala.util.parsing). In this implementation, we in particular, use JavaTokenParsers along with PackratParser.

class ODataUriParser extends JavaTokenParsers with PackratParsers {
//...
}

Implementation

ODATA URI contains three fundamental parts, namely Service Root URI, Resource Path and Query Options as below and as per the documentations at [1].

If we consider the ODATA URI mentioned previously, following illustrates the stated three parts of ODATA request:

odata-uri-parts

Hence, we can construct this parser by building combinators for the three sub-parts in a bottom-up manner and then compose them to construct the complete parser as listed below.

To gets started with an example, lets consider following URI:

http://odata.io/odata.svc/Schema(231)/Customer?$top=2&$filter=concat(City, Country) eq 'Berlin, Germany'

and we are expecting an expression tree based on a pre-defined model as follows:

Building a parser combinator for Service Root and Resource Path are considerably simpler compared to that of Query Options (the third part). Let’s build them first.

We are using this convention (see ODATA specification) that a ODATA service root should always be ended by .svc. The following snippet can parse for instance http://odata.io/odata.svc to URL("http://odata.io/odata.svc").

Next we are defining a resource path which can parse for instance Schema(231) to ResourcePath("Schema",Number("231"),ResourcePath("Customer",EmptyExp(),EmptyExp())) expressions. A compound resource path can be augmented with multiple resources.

After that we have reached to the crux of the problem: to build a parser that can handle the query operators defined in the OData specification. To solve it, we apply bottom up approach in conjunction with top-down realization.

First we define a basic parser that can parse arithmetic expressions as follows.

Then we incrementally augment support for handling relational operators, and thus can handle logical and, or and similar operation.

The above two code listings form the basis to provide support for the query operations such as $filter and $select. See below.

Thus, it allows to parse the URI to expression tree as shown below.

Or, as follows:

Conclusion

The complete source of this project is available at github repository. Please feel free to browse and if there is any question, please post.

See More:

  1. OData URI Specification
  2. External DSLs made easy with Scala Parser Combinators
  3. DSLs in Action
Advertisements

Internal DSL Development with F# | via @tomaspetricek

Recently, Tomas Petricek gave a talk on the topic of internal DSL development with F#. In particular, he discussed the motivation behind DSL development, and demonstrated a number of example DSLs using F#. If you are interested, please check it out —

x += x++

Hi, I’m back. I’ve finally sorted out the guidelines for blogging in Credit Suisse.

Here is something I have been playing around with in the spare time between one meeting and the next one.  It is a Scheme interpreter that includes a REPL window. The full code is here.

All the smarts for it come from this Wiki Book. I just ported the code to F# (and modified it a bit). I thought the comparison might be interesting, so here we go. Thanks to Tobias and Jose for reviewing the code, find one bug and suggest improvements.

Before we start looking at the real code, here is what we are trying to accomplish in form of test cases. If you are a bit rusty on LISP syntax, you might want to try and see if you understand what it does.

Our goal is to make all this XUnit…

View original post 501 more words

Semantics with Application by Hanne Riis Nielson & Flemming Nielson

“Semantics with Applications: A Formal Introduction” – by Hanne Riis Nielson and Flemming Nielson presents the fundamental ideas behind the major three approaches to operational, denotational and axiomatic semantics. This book also addresses the relationship by formulating and proving the relevant theorems. In addition, it provides several illustrations of the applicability of formal semantics in various field of computer science as a prominent tool.

“Semantics with Applications: A Formal Introduction” – by Hanne Riis Nielson and Flemming Nielson presents the fundamental ideas behind the major three approaches to operational, denotational and axiomatic semantics. This book also addresses the relationship by formulating and proving the relevant theorems. In addition, it provides several illustrations of the applicability of formal semantics in various field of computer science as a prominent tool.

Course Notes are available at: http://www.daimi.au.dk/~bra8130/Wiley_book/wiley.html

 

 

 

 

TUDelft | Lectures of Model-Driven Software Development Course

The following lectures on Model-Driven Software Development(MDSD) are given by Dr. Eelco Visser at Tudelft in IN4308 course. To get the basic idea of MDSD and motivation behind it , please go through these lectures .

The following lectures on Model-Driven Software Development(MDSD) are given by Dr. Eelco Visser at Tudelft  in IN4308 course.   To get the basic idea of MDSD and motivation behind it , please go through these lectures .

Lecture 1 : MDSD : Introduction and Overview

Lecture 2 : Domain Analysis & Data Modeling

Lecture 3 & 4 : Web Abstraction

In these lectures, WebDSL , a DSL for Web Application is introduced.  Continuing from the previous discussion on Domain Analysis, these lectures address the design issues and motivation behind abstracting the domain of Web Application using this DSL.

Lecture 5 : Web Abstraction to actual Implementation