lunedì 12 agosto 2013

Yacc/Lex Tools v0.2

In un precedete post (Linguaggi e Traduttori con Visual Studio) ho illustrato come aggiungere un parser al proprio progetto C# utilizzando i tools GPPG e GPLEX per compilare i files YACC e LEX per generare rispettivamente il parser ed il relativo scanner.

Nel post precedente veniva illustrato come modificare a mano il file di progetto dopo aver installato il NuGet package YaccLexTools.

Il package "YaccLexTools" è stato aggiornato e dalla versione 0.2 non è più necessario modificare manualmente i tag XML del file di progetto. Con questa nuova versione è possibile gestire il tutto grazie a nuovi Cmd-Let PowerShell azionabili dal "Package Manager Console" di Visual Studio.

Ad esempio, per aggiungere un parser al tuo progetto sarà necessario eseguire il comando:

 PM> Add-Parser MyLanguage 

Con questo comando verrano creati tutti i files ed i settings necessari per la compilazione dei files YACC e LEX.


Se si vuole specificare un namespace personalizzato si potrà eseguire il seguente comando il cui secondo parametro è proprio il namespace:

 PM> Add-Parser MyLanguage Sample.NameSpace 

Per rimuovere i settings di un parser creato nel progetto si potrà utilizzare il seguente comando:

 PM> Remove-Parser MyLanguage 

Con questo comando non verranno rimossi i files, ma solo i settings per il parser specificato. I files dovranno essere rimossi manualmente.

Infine nel package è incluso un esempio funzionante per interpretare delle espressioni di calcolo. Per aggiungere al progetto questo esempio è sufficiente utilizzare il comando

 PM> Add-CalculatorExample 


Conclusioni.
In questo post sono state illustrate le semplificazioni implementate nella nuova versione del NuGet package YaccLexTools per la gestione di parsers all'interno di progetti C#.

Con la speranza che questi aggiornamenti siano utili a chi già usa il package e tutti coloro che lo utilizzeranno,

Ernesto

sabato 25 maggio 2013

Linguaggi e Traduttori con Visual Studio

Attenzione, il NuGet package YaccLexTools è stato aggiornato. Leggi il post relativo all'aggiornamento ed alle semplificazioni introdotte: Yacc/Lex Tools v0.2
A volte è bello dare un senso a ciò che si ha studiato in passato e questo è il caso dell'esame di Linguaggi e Traduttori.

Mi è venuto in mente di potenziare la funzionalità di ricerca veloce di una applicazione web. Normalmente questa ricerca veloce prende tutte le parole inserite e fa una ricerca Full-Text su tutti i dati.
Quindi, mi sono detto, perché non dare la possibilità agli utenti di inserire delle piccole espressioni per definire in modo semplice dei filtri sulla ricerca?

Come ad esempio:

anno: 2000
anno: >= 2000
anno: 2000..2010 mese: > 6

Detto fatto! Quello di cui abbiamo bisogno in questo caso sono un analizzatore sintattico ed un parser.

Ad oggi non è molto pratico creare a mano questi strumenti, ma ci si avvale di generatori automatici. Quelli che io ho preso in considerazione sono GPPG per generare il parser e GPLEX per generare l'analizzatore sintattico, entrambi creati dal QUT, università australiana, in collaborazione con Microsoft.
GPPG genera un parser in linguaggio C# partendo da una descrizione formale della grammatica scritta in YACC, menrte GPLEX genera un analizzatore sintattico a partire dalla descrizione in LEX della sintassi del linguaggio.

Premesso che il lettore abbia già una consocenza di come scrivere una grammatica in YACC ed un analizzatore sintattico in LEX, l'obbiettivo di questo post è di guidare alla configurazione del progetto in Visual Studio per poter generare il parser e lo scanner durante il build del progetto stesso.

Prima di tutto si deve aggiungere il NuGet package "YACC/LEX tools" con il comando

 PM> Install-Package YaccLexTools 

Adesso supponiamo di voler creare il parser per le query di ricerca come descritte sopra.

1) Clicca con il tasto destro sul progetto e seleziona "Scarica Progetto"
2) Clicca con il tasto destro sul progetto e seleziona "Modifica "
3) Aggiungi il seguente frammento alla fine del file, prima della chiusura del tag </Project>
e salva.

  <Target Name="BeforeBuild" DependsOnTargets="BuildGen">
  </Target>
  <!-- Build generated file target -->
  <Target Name="BuildGen" DependsOnTargets="GenerateMyLanguageParser">
  </Target>
  <!-- Parser items -->
  <PropertyGroup>
    <ToolsDir>$(SolutionDir)packages\YaccLexTools.0.1.2\tools\</ToolsDir>
    <GplexTool>"$(ToolsDir)gplex.exe"</GplexTool>
    <GppgTool>"$(ToolsDir)gppg.exe"</GppgTool>
    <MyLanguageParser>$(ProjectDir)MyLanguage</MyLanguageParser>
  </PropertyGroup>
  <ItemGroup>
    <None Include="MyLanguage.parser" />
    <Compile Include="MyLanguage.Parser.cs">
      <DependentUpon>MyLanguage.parser</DependentUpon>
    </Compile>
    <Compile Include="MyLanguage.Scanner.cs">
      <DependentUpon>MyLanguage.parser</DependentUpon>
    </Compile>
    <None Include="MyLanguage.Language.grammar.y">
      <DependentUpon>MyLanguage.parser</DependentUpon>
    </None>
    <Compile Include="MyLanguage.Parser.Generated.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>MyLanguage.Language.grammar.y</DependentUpon>
    </Compile>
    <None Include="MyLanguage.Language.analyzer.lex">
      <DependentUpon>MyLanguage.parser</DependentUpon>
    </None>
    <Compile Include="MyLanguage.Scanner.Generated.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>MyLanguage.Language.analyzer.lex</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup />
  <!--  Generate the parsers -->
  <Target Name="GenerateMyLanguageParser"
          Inputs="$(MyLanguageParser).Language.analyzer.lex;$(MyLanguageParser).Language.grammar.y" 
          Outputs="$(MyLanguageParser).Scanner.Generated.cs;$(MyLanguageParser).Parser.Generated.cs">
    <Message Text="Generating scanner for $(MyLanguageParser) ..." />
    <Exec Command="$(GplexTool) &quot;/out:$(MyLanguageParser).Scanner.Generated.cs&quot; &quot;$(MyLanguageParser).Language.analyzer.lex&quot;" 
          WorkingDirectory="$(ProjectDir)" 
          Outputs="$(GenDir)Scanner.cs">
      <Output TaskParameter="Outputs" ItemName="MyLanguageScanner" />
    </Exec>
    <Message Text="Generating parser for $(MyLanguageParser) ..." />
    <Exec Command="$(GppgTool) /no-lines /gplex &quot;$(MyLanguageParser).Language.grammar.y&quot; > &quot;$(MyLanguageParser).Parser.Generated.cs&quot;" 
          WorkingDirectory="$(ProjectDir)" 
          Outputs="$(MyLanguageParser).Parser.Generated.cs">
      <Output TaskParameter="Outputs" ItemName="MyLanguageParser" />
    </Exec>
  </Target>

4) Copia i files contenuti nella cartella "packages\YaccLexTools.0.1.2\src" nella cartella del progetto.
5) Clicca con il tasto destro sul progetto e seleziona "Ricarica Progetto".

Quando il progetto sarà ricaricato, questo è quello che sarà presente nel Solution Explorer di Visual Studio:



Nella figura qui sopra ci sono tutti i files che compongono il parser.
  • MyLanguage.parser è solo un segna posto e non contiene nulla di interessante. Serve solo per raggruppare in un unico nodo tutti i files del parser.
  • MyLanguage.Language.analyzer.lex è il sorgente in LEX dell'analizzatore sintattico.
  • MyLanguage.Scanner.Generated.cs è il file C# generato dal sorgente LEX "MyLanguage.Language.analyzer.lex".
  • MyLanguage.Language.grammar.y è il sorgente in YACC del parser. In esso viene descritta la grammatica.
  • MyLanguage.Parser.Generated.cs è il file C# generato dal sorgente YACC "MyLanguage.Language.grammar.y".

Infine i files MyLanguage.Parser.cs e MyLanguage.Scanner.cs sono classi parziali C# che vanno ad estendere rispettivamente il parser e lo scanner generato dai files YACC e LEX per aggiungervi i metodi chiamati nelle azioni delle regole grammaticali e sintattiche.


Note finali.
Per la realizzazione di tutto questo è stato molto utile poter vedere il codice Open Source di progetti di compilatori come per esempio IronRuby. Se non avessi potuto guardare dentro al codice di IronRuby non avrei mai fatto una cosa del genere. Quello che voglio dire è che si può imparare molto, ma anche trovare ispirazione, confrontandosi con altri ;)


mercoledì 14 settembre 2011

Windows 8 Developer Preview

La data per la versione Beta non è ancora nota, ma da oggi è disponibile per il download la Developer Preview di Window 8.

Una delle novità più importanti che coinvolgerà gli sviluppatori è la nuova API nativa WinRT che va a sostituire la Win32 introdotta con Windows NT nel 1993. Mentre Win32 è stata realizzata avendo il C in mente, WinRT è una libreria completamente Object Oriented. Non si tratta quindi di un nuovo layer costruito su Win32, ma di una nuova API nativa che permette di accedere direttamente a tutte le funzionalità del sistema operativo tramite i linguaggi C++, C#, VB ed anche JavaScript. Ovviamente Win32 non è stato rimosso e quindi tutte le vecchie applicazioni continueranno a funzionare correttamente.

Mentre Win32 è stato scritto in C, WinRT è stato scritto in C++ e tutti gli oggetti della libreria supportano la reflection che può quindi essere utilizzata dai linguaggi dinamici come il JavaScript. Questa infatti è un'altra novità, la promozione di JavaScript a linguaggio possibile per la creazione di applicazioni Windows poiché potrà accedere alle funzionalità native attraverso WinRT.

Le interfacce utente verranno realizzate con XAML per applicazioni C, C++, C# e VB. XAML non sarà eseguito sul .NET, ma sarà eseguito in modo nativo poiché le librerie che lavorano con XAML sono state riscritte in C++ e quindi compilate in codice nativo x86. Questo significa che le applicazioni scritte in C++ e XAML saranno compilate ed eseguite in codice nativo x86 esattamente come tutte le altre applicazioni C++.
Per le applicazioni Javascript, invece, si dovrà continuare ad utilizzare HTML/CSS per creare le interfacce utente ed il motore di rendering sarà lo stesso di Internet Explorer 10, anche se non gireranno effettivamente in un browser. Questo non toglie che saranno comunque disponibili tutti i controlli utente disponibili anche in C# e VB. In più sarà possibile creare nuovi controlli utente di tipo <div> al pari di quelli creati nelle applicazioni web tramite jQuery o altre librerie simili.

Ma non ci sono solo novità in aggiunta. Ci sono anche dei tagli. Spariscono le librerie GDI e pare che non saranno più supportate le Dialog Boxes. Quindi se qualcuno volesse continuare a seguire questo pattern di interfaccia utente, dovrà inventarsi qualcosa di nuovo.

Infine, sembra che la memoria di base di Windows 8 sia stata tagliata da 540 MB a 281 MB.
Nella preview scaricabile su http://dev.windows.com/ saranno inclusi anche Visual Studio 11 Express ed Expression Blend 5.

Buon divertimento!

jQuery plugin .clickout()

Chi già conosce jQuery (www.jquery.com) sicuramente conoscerà e apprezzerà le sue qualità. Per chi non lo conosce, jQuery è una libreria JavaScript veloce e concisa che semplifica la programmazione di pagine HTML dinamiche ed in particolare operazioni di manipolazione degli oggetti del DOM, interazioni Ajax, animazioni e gestione di eventi.

Proprio nella gestione degli eventi, forse l'evento più utilizzato è il "click" che si attiva quando appunto clicchiamo su un oggetto.

In alcuni casi, però, c'è la necessità di attivare un evento quando si clicca fuori dall'area di un determinato oggetto della pagina. Mentre l'evento "onclick" è un evento nativo del JavaScript e quindi è supportato da jQuery tramite la funzione ".click()" (vedi API), non esiste nessun evento nativo che permette di attivare un codice JavaScript quando si clicca fuori da un determinato oggetto.

Per risolvere questo problema ho scritto, quindi, il plugin ".clickout()" che è possibile scaricare da  http://github.com/ernstc/clickout.

Il funzionamento è simile al complementare ".click()" e di seguito ecco un semplice esempio dimostrativo:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>.clickout() Test Page</title>
 
<script src="http://code.jquery.com/jquery-1.6.3.min.js"
        type="text/javascript"></script>
<script src="jquery.clickout.js" type="text/javascript"></script>
 
<script type="text/javascript">
 
  $(document).ready(function ()
  {
    $('#divTest')
      .click(function ()
      {
        $('#message').html('.click()<br/>hai cliccato dentro');
      })
      .clickout(function ()
      {
        $('#message').html('.clickout()<br/>hai cliccato fuori');
      });
  });
 
</script>
</head>
<body>
  <div id="divTest" style="padding: 5px; width:100px; height: 100px; 
       background: Blue; color: White;">
    Clicca dentro o fuori da questo quadrato.
  </div>
  <div id="message"></div>
</body>
</html>

martedì 13 luglio 2010

Raphaël: grafica vettoriale sul web

La grafica sul web diventa sempre più complessa. Molti si appoggiano a tecnologie come Flash e Silverlight per ottenere effetti grafici sofisticati o anche più semplicemente per fare grafica vettoriale sul web. Eppure è possibile fare grafica vettoriale sul web utilizzando solamente le capacità del browser. Le tecnologie da utilizzare sono VML (Vector Markup Language) su Internet Explorer fino alla versione 8 e SVG (Scalable Vector Graphics) su tutti gli altri browsers. L'esistenza di due tecnologie, equivalenti, ma diverse, complica la vita per chi deve sviluppare grafica vettoriale per tutti i browsers :(

Ma non tutto è perduto!
Dmitry Baranovskiy è arrivato in aiuto e ha creato una fantastica libreria JavaScript che fa da ponte tra le due tecnologie. Questa libreria si chiama Raphaël.
Si tratta di un adapter che con una semplice API dona all'arte del disegno vettoriale la compatibilità cross-browser, poiché questa libreria renderizzerà il nostro disegno vettoriale in VML o SVG a seconda del browser.

Ma perché utilizzare una libreria che usa SVG/VML quando invece per il disegno si fa sempre più diffusa la tecnologia <canvas> dell'HTML 5?

Il motivo sta nel fatto che tutti gli oggetti SVG/VML fanno parte del DOM della pagina web e questo significa che possono essere modificati via script, ovvero è possibile aggangiare a tali oggetti degli event handler come il click, il drag, ecc...

Infine, un altro aspetto interessante di questa libreria è che è stata sviluppata sullo stesso principio di jQuery sia per il modo di accesso all'API che per l'estendibilità tramite plug-ins. Questo rende la libreria immediatamente familiare agli sviluppatori jQuery. Le due librerie possono ovviamente convivere.

giovedì 28 gennaio 2010

Software multilingua

Dato che ho intenzione di rendere un mio software multilingua, è oramai un bel po' di tempo che inciampo nella sigla "i18n" come parola magica da prendere in considerazione per rendere il software internazionale.
Stavo cercando di capire di che cosa si trattasse: protocollo? pattern? libreria?

Nulla di tutto ciò, non ho trovato nulla. Ognuno implementa i18n sempre in modi diversi a loro modo creativi. Quindi???

Grazie a Wikipedia finalmente ho trovato! La soluzione del mio dilemma è di una banalità sconcertante! (http://it.wikipedia.org/wiki/I18n)
i18n altro non è che la parola "internazionalization" !!!! Cioè il numero 18 indica il numero di lettere omesse tra la prima lettera e l'ultima.
E quindi ho scoperto che esistono altre sigle simili:
L10n: localization;
g11n: globalization;
a11y: accessibility;
p13n: personalization;
r3h: reach.

Il motivo di quest'ultima veramente mi sfugge.
Quindi ora che lo sapete, state attenti se il vostro capo vi chiede un p13n sul software :D E ricordatevi di considerare anche l'a11y.

Credo che comincerò a scrive gli SMS con questo protocollo di comunicazione....

Etichette

ajax (1) C# (3) C++ (1) click (1) clickout (1) compilatori (2) gplex (2) gppg (2) html (1) i18n (1) internazionalization (1) javascript (2) jquery (1) lex (2) object oriented (1) plugin (1) programmazione (3) software (4) svg (1) VB (1) vector graphics (1) visual studio (2) vrml (1) web (1) Win32 (1) windows 8 (1) WinRT (1) XAML (1) yacc (2) yacclextools (1)