How to create a DSL style to describe a dataset?

I would like to have a dataset description in the format of data driven specifications:

'Key' | 'Value' | 'Comments' 1 | 'foo' | 'something' 2 | 'bar' | 'something else' 

This should be converted to something like a 2D array (or something that can be implemented).

Any ideas how to implement this data description?

ps The biggest problem is line detection, the rest can be implemented by overloading the or metaClass object.

+4
source share
1 answer

Operator | left associative, so the row in this table will be parsed as follows:

 ('Key' | 'Value') | 'Comments' 

What you can do to determine where each line begins and ends is to do | opeator return a list with its operands, and then for each | ask if the left operand (i.e. this ) is a list. If so, then this is a continuation of the line; if it is not a list, it means that it is a new line.

Here is a complete DSL example for parsing these datasets using Category to avoid overriding objects in the object's metaclass:

 @Category(Object) class DatasetCategory { // A static property for holding the results of the DSL. static results def or(other) { if (this instanceof List) { // Already in a row. Add the value to the row. return this << other } else { // A new row. def row = [this, other] results << row return row } } } // This is the method that receives a closure with the DSL and returns the // parsed result. def dataset(Closure cl) { // Initialize results and execute closure using the DatasetCategory. DatasetCategory.results = [] use (DatasetCategory) { cl() } // Convert the 2D results array into a list of objects: def table = DatasetCategory.results def header = table.head() def rows = table.tail() rows.collect { row -> [header, row].transpose().collectEntries { it } } } // Example usage. def data = dataset { 'Key' | 'Value' | 'Comments' 1 | 'foo' | 'something' 2 | 'bar' | 'something else' } // Correcness test :) assert data == [ [Key: 1, Value: 'foo', Comments: 'something'], [Key: 2, Value: 'bar', Comments: 'something else'] ] 

In this example, I analyzed the table as a list of maps, but after the DSL closes, you can do whatever you want with the results of the DatasetCategory.

+5
source

All Articles