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.
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
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