Promessa do TechEd – código do exemplo do Oslo

Prometi na palestra sobre MDD e Oslo neste TechEd colocar neste blog o código do exemplo de como usar uma gramática Mgrammar no .Net. Pois aqui vai....

A gramática que mostrei na demo é simples. Ela lê textos da forma “X tem Y anos.”. Um exemplo seria:

“Otavio tem 50 anos.

Paula tem 29 anos.”

Para isto, preciso declarar a gramática de reconhecimento em uma variável da forma:

static private string contactGrammar = @"
module lingContato {
language Contatos {
syntax Main = c:Contato * => Contatos { valuesof(c) };
syntax Contato =
n:Nome ""tem"" i:Idade ""anos."" => { Nome = n, Idade=i };
token Nome = ('A'.. 'Z' | 'a'..'z')+;
token Idade = '0'..'9'+;
interleave espaco = ' ' | '\r' | '\n' | '\r\n';
}
}";

O passo 2 é compilar a gramática e criar o “parser”:

CompilationResults resultsContatos = Compiler.Compile(
new CompilerOptions
{
Sources = {
new TextItem {
Reader = new StringReader(contactGrammar),
ContentType = TextItemType.MGrammar
}
}
}
);

DynamicParser parserContatos = resultsContatos.ParserFactories["lingContato.Contatos"].Create();

parserContatos.GraphBuilder = new NodeGraphBuilder();

O passo 3 é fazer o “parsing”do texto de entrada (na variável inText), gerando um grafo que representa a AST (Abstract Syntax Tree).

Node nContato = (Node)parserContatos.Parse(new StringTextStream(inText), null);

Por fim, estamos prontos para navegar o texto e preencher uma lista do tipo Contato:

Contato c = new Contato();

foreach (Node record in tree.ViewAllNodes() )
{
foreach (var member in record.Edges )
{
string s = member.Label + ": " + member.Node;

        if (member.Label == "Idade")
{
c.Idade = member.Node.ToString();
lc.Add(c);
c = new Contato();
saida += s + " \r\n";
}
else
{
c.Nome = member.Node.ToString();
saida += s + " ";
}

    }
}

onde Contato é dado pela classe:

publicclassContato {

     publicstring Nome { get ; set ; }

     publicstring Idade { get ; set ; }

}

Você vai precisar destas declarações de namespaces do Oslo (no diretório bin da instalação do SDK dele):

using Microsoft.M;
using Microsoft.M.Parser;
using Microsoft.M.Grammar;
using System.Dataflow;

Aqui abaixo vocês podem ver como fica esta exemplo no Intellipad do Oslo.

clip_image002

Na esquerda desta figura temos exemplos de frases de entrada. No meio, a gramática que consegue analisar sintaticamente este texto de entrada. Na esquerda vocês vêem a saida depois da análise. É um texto com chaves que representa uma AST (ou grafo).

Para quem não viu, temos um webCast similar em: https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=pt-BR&EventID=1032416175&CountryCode=BR

Vale a pena também ler os artigos:

Textual Domain Specific Languages for Developers - Part 1

Textual Domain Specific Languages for Developers - Part 2

Textual Domain Specific Languages for Developers - Part 3

Creio que com isto você consegue criar o seu parser, não consegue?

Promessa é divida. Com isto acabei de pagar a minha!

Abraços,

Otavio