<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkQFRXg5eCp7ImA9WxJUEk4.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800</id><updated>2009-07-10T12:05:14.620-03:00</updated><title>Leniel Macaferi's blog</title><subtitle type="html">Everything software engineering with a strong background in computer engineering and computer science.&lt;p align="right"&gt;&lt;a href="http://www.leniel.net/2008/03/papers.html"&gt;Papers&lt;/a&gt; | &lt;a href="http://leniel.googlepages.com/LenielMacaferiResumeEnglish.pdf"&gt;&lt;b&gt;Resume&lt;/b&gt;&lt;/a&gt; | &lt;a href="http://www.proz.com/translator/849397"&gt;Translator&lt;/a&gt; | &lt;a href="http://www.leniel.net/2007/12/contact.html"&gt;Email&lt;/a&gt;&lt;/p&gt;</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.leniel.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.leniel.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default?start-index=21&amp;max-results=20&amp;redirect=false&amp;v=2" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>63</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>20</openSearch:itemsPerPage><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/3.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><link rel="self" href="http://feeds.feedburner.com/leniel" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;A0cFQ3o8fip7ImA9WxJVFUQ.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-5526964141051054546</id><published>2009-07-02T19:51:00.001-03:00</published><updated>2009-07-03T02:30:12.476-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-03T02:30:12.476-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="thread safety" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="OOXML" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft Excel" /><category scheme="http://www.blogger.com/atom/ns#" term="XLSX" /><category scheme="http://www.blogger.com/atom/ns#" term="spreadsheet" /><category scheme="http://www.blogger.com/atom/ns#" term="NPOI" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="XLS" /><category scheme="http://www.blogger.com/atom/ns#" term="COM automation" /><category scheme="http://www.blogger.com/atom/ns#" term="ExcelPackage" /><title>Creating Excel spreadsheets .XLS and .XLSX in C#</title><content type="html">&lt;p&gt;Recently I had to implement some code to create an Excel spreadsheet/report using C#.&lt;/p&gt;  &lt;p&gt;The task was: given an Excel spreadsheet template - a .XLS file (with formulas, pivot tables, macros, etc) I had to fill some data in one of the sheets of the spreadsheet and send this modified spreadsheet back to the user requesting such an operation (Excel report).&lt;/p&gt;  &lt;p&gt;The following attests the need for Excel nowadays:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="right"&gt;Excel has long been recognized as the de facto standard when it comes to presenting management reports. The unique combination of great calculation engine, excellent charting facilities, pivot tables and the possibility to perform “what if” analysis, make it the “must have” business intelligence tool.      &lt;br /&gt;by &lt;a href="http://www.codeplex.com/site/users/view/JohnTunnicliffe" target="_blank"&gt;John Tunnicliffe&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I had a great time while studying the possible ways of doing what the task asks for.&lt;/p&gt;  &lt;p&gt;It appears to be a simple task at first but as the time passes by you get to know that this is not the case, well, till the moment this blog post was written at least, I think. &lt;strong&gt;:-)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Firstly I tried automating Excel through &lt;a href="http://en.wikipedia.org/wiki/COM_automation" target="_blank"&gt;COM automation&lt;/a&gt;, but as the application was meant to be used in a web context it is not recommended to use automation. Why? Because COM automation for Excel is not &lt;a href="http://en.wikipedia.org/wiki/Thread_safety" target="_blank"&gt;thread safe&lt;/a&gt;, that is, EXCEL.EXE was not constructed to be used by concurrent users accessing the same process, in this case EXCEL.EXE; besides, Microsoft Excel must be installed on the server what is not always possible.&lt;/p&gt;  &lt;p&gt;For more details on why you shouldn’t use Excel on the server, read this article on Microsoft Help and Support site: &lt;a href="http://support.microsoft.com/kb/257757" target="_blank"&gt;Considerations for server-side Automation of Office&lt;/a&gt;. The key part is this:&lt;/p&gt;  &lt;p align="center"&gt;&lt;em&gt;Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I’ve just experienced the above. EXCEL.EXE insisted in being alive in &lt;a href="http://en.wikipedia.org/wiki/Windows_Task_Manager" target="_blank"&gt;task manager&lt;/a&gt; even after processing the data and being closed in code. Each call to process a spreadsheet opens an EXCEL.EXE process on the server. With such EXCEL.EXE processes don’t being closed as they should you get lots of those processes on memory which could overload the server.&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;Don not use COM automation if you’re developing server-side code&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;After struggling with COM automation I finally got to know &lt;a href="http://excelpackage.codeplex.com/" target="_blank"&gt;ExcelPackage&lt;/a&gt; which works with &lt;a href="http://en.wikipedia.org/wiki/Office_Open_XML" target="_blank"&gt;Office Open Document Format&lt;/a&gt; (OOXML). It can read an .XLSX (Microsoft Excel 2007) template and create another .XLSX file based on such template, giving you lots of possibilities to work with the template copy.&lt;/p&gt;  &lt;p&gt;I’ve gotten really happy because I had found a way of doing what the task was asking for but with a minor detail: ExcelPackage works only with .XLSX file format letting the .XLS (Microsoft Excel 2003) format out of the game. Well it turned out to be a big impediment because the client (software buyer) wouldn’t allow us to install the famous &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=941B3470-3AE9-4AEE-8F43-C6BB74CD1466&amp;amp;displaylang=en" target="_blank"&gt;Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats&lt;/a&gt; on user machines so that users could open and save OOXML file formats even using Microsoft Office 2003 suite.&lt;/p&gt;  &lt;p&gt;Discovering ExcelPackage was good but it didn’t do the trick that implies the use of an .XLS template.&lt;/p&gt;  &lt;p&gt;I got back &lt;a href="http://en.wikipedia.org/wiki/Google_%28verb%29" target="_blank"&gt;Googling&lt;/a&gt; again and strived to find an open source library that would allow me to do what I wanted. After some time I finally discovered &lt;a href="http://npoi.codeplex.com/" target="_blank"&gt;NPOI&lt;/a&gt;. Wow, it could read the .XLS template and generate the end result I wanted. Great. I downloaded the binaries immediately and started playing with it to see what it could really do.&lt;/p&gt;  &lt;p&gt;OK, after this short story, I’ll show you how to use both open source projects (&lt;a href="http://excelpackage.codeplex.com/" target="_blank"&gt;ExcelPackage&lt;/a&gt; and &lt;a href="http://npoi.codeplex.com/" target="_blank"&gt;NPOI&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;I’ve created a new &lt;a href="http://www.asp.net/mvc/whatisaspmvc/" target="_blank"&gt;ASP.NET MVC&lt;/a&gt; project as can be seen in this picture:&lt;/p&gt;  &lt;p align="center"&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Excel Writer Solution Explorer" border="0" alt="Excel Writer Solution Explorer" src="http://lh4.ggpht.com/_W1dLiLjFqdw/Sk05vrJYl0I/AAAAAAAAAkg/AkO7OYyF-6c/ExcelWriterSolutionExplorer%5B9%5D.png?imgmax=800" width="263" height="717" /&gt; &lt;/p&gt;  &lt;p align="left"&gt;In the Content folder I’ve placed the template spreadsheets.    &lt;br /&gt;In the Libs folder I’ve placed the DLLs necessary to use both ExcelPackage and NPOI open source projects.&lt;/p&gt;  &lt;p&gt;The controller that interests us is the one called ExcelWriterController:&lt;/p&gt;  &lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Excel Writer Controller" border="0" alt="Excel Writer Controller" src="http://lh3.ggpht.com/_W1dLiLjFqdw/Sk05wPLpCVI/AAAAAAAAAkM/d3O5qK1NKrc/ExcelWriterController%5B3%5D.png?imgmax=800" width="174" height="176" /&gt; &lt;/p&gt;  &lt;p align="left"&gt;The methods that handle the creation of the spreadsheet are: ExcelPackageCreate and NPOICreate.&lt;/p&gt;  &lt;p align="left"&gt;For each controller action (method) there’s a corresponding view that renders the &lt;a href="http://en.wikipedia.org/wiki/User_interface" target="_blank"&gt;UI&lt;/a&gt; to the user. Those views are the ones shown inside the ExcelWriter folder: ExcelPackage.aspx and NPOI.aspx.&lt;/p&gt;  &lt;p align="left"&gt;This is the Home Page of the Excel Writer MVC Application - take a look at the tabs (ExcelPackage and NPOI) that lead you to the View pages:&lt;/p&gt;  &lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Excel Writer Home Page" border="0" alt="Excel Writer Home Page" src="http://lh6.ggpht.com/_W1dLiLjFqdw/Sk05zrZ-TZI/AAAAAAAAAk8/y2xBzO-AwrY/ExcelWriterHomePage%5B19%5D.png?imgmax=800" width="526" height="524" /&gt;&lt;/p&gt;  &lt;p align="left"&gt;Each view has a button which when clicked calls the corresponding action method on the ExcelWriterController.&lt;/p&gt;  &lt;p align="left"&gt;This is the NPOI view page:&lt;/p&gt;  &lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Excel Writer NPOI View Page" border="0" alt="Excel Writer NPOI View Page" src="http://lh5.ggpht.com/_W1dLiLjFqdw/Sk053Q42KhI/AAAAAAAAAlE/JCMfTekB5ss/ExcelWriterNPOIView%5B5%5D.png?imgmax=800" width="526" height="489" /&gt; &lt;/p&gt;  &lt;p&gt;I’ll play with a simple spreadsheet I filled with the data I got from Excel’s blog post titled &lt;a href="http://blogs.msdn.com/excel/archive/2009/06/30/formula-to-access-a-list-of-values-interspersed-with-zeros-or-blanks.aspx" target="_blank"&gt;Formula to Access a List of Values Interspersed with Zeros or Blanks&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Let’s see the code that goes into the ExcelPackageCreate method:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Creates a new Excel spreadsheet based on a template using the ExcelPackage library.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;A new file is created on the server based on a template.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Excel report&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;[&lt;span style="color: #2b91af"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Post)]
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;ExcelPackageCreate()
{
    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;FileInfo &lt;/span&gt;template = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FileInfo&lt;/span&gt;(Server.MapPath(&lt;span style="color: #a31515"&gt;@&amp;quot;\Content\ExcelPackageTemplate.xlsx&amp;quot;&lt;/span&gt;));

        &lt;span style="color: #2b91af"&gt;FileInfo &lt;/span&gt;newFile = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FileInfo&lt;/span&gt;(Server.MapPath(&lt;span style="color: #a31515"&gt;@&amp;quot;\Content\ExcelPackageNewFile.xlsx&amp;quot;&lt;/span&gt;));

        &lt;span style="color: green"&gt;// Using the template to create the newFile...
        &lt;/span&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ExcelPackage &lt;/span&gt;excelPackage = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ExcelPackage&lt;/span&gt;(newFile, template))
        {
            &lt;span style="color: green"&gt;// Getting the complete workbook...
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ExcelWorkbook &lt;/span&gt;myWorkbook = excelPackage.Workbook;

            &lt;span style="color: green"&gt;// Getting the worksheet by its name...
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ExcelWorksheet &lt;/span&gt;myWorksheet = myWorkbook.Worksheets[&lt;span style="color: #a31515"&gt;&amp;quot;Sheet1&amp;quot;&lt;/span&gt;];

            &lt;span style="color: green"&gt;// Setting the value 77 at row 5 column 1...
            &lt;/span&gt;myWorksheet.Cell(5, 1).Value = 77.ToString();

            &lt;span style="color: green"&gt;// Saving the change...
            &lt;/span&gt;excelPackage.Save();
        }

        TempData[&lt;span style="color: #a31515"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;] = &lt;span style="color: #a31515"&gt;&amp;quot;Excel report created successfully!&amp;quot;&lt;/span&gt;;

        &lt;span style="color: blue"&gt;return &lt;/span&gt;RedirectToAction(&lt;span style="color: #a31515"&gt;&amp;quot;ExcelPackage&amp;quot;&lt;/span&gt;);
    }
    &lt;span style="color: blue"&gt;catch&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Exception &lt;/span&gt;ex)
    {
        TempData[&lt;span style="color: #a31515"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;] = &lt;span style="color: #a31515"&gt;&amp;quot;Oops! Something went wrong.&amp;quot;&lt;/span&gt;;

        &lt;span style="color: blue"&gt;return &lt;/span&gt;RedirectToAction(&lt;span style="color: #a31515"&gt;&amp;quot;ExcelPackage&amp;quot;&lt;/span&gt;);
    }
}&lt;/pre&gt;

&lt;p&gt;Let’s see the code that goes into the NPOICreate method:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Creates a new Excel spreadsheet based on a template using the NPOI library.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;The template is changed in memory and a copy of it is sent to
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;the user computer through a file stream.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Excel report&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;[&lt;span style="color: #2b91af"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Post)]
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;NPOICreate()
{
    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        &lt;span style="color: green"&gt;// Opening the Excel template...
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FileStream &lt;/span&gt;fs =
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FileStream&lt;/span&gt;(Server.MapPath(&lt;span style="color: #a31515"&gt;@&amp;quot;\Content\NPOITemplate.xls&amp;quot;&lt;/span&gt;), &lt;span style="color: #2b91af"&gt;FileMode&lt;/span&gt;.Open, &lt;span style="color: #2b91af"&gt;FileAccess&lt;/span&gt;.Read);

        &lt;span style="color: green"&gt;// Getting the complete workbook...
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HSSFWorkbook &lt;/span&gt;templateWorkbook = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HSSFWorkbook&lt;/span&gt;(fs, &lt;span style="color: blue"&gt;true&lt;/span&gt;);

        &lt;span style="color: green"&gt;// Getting the worksheet by its name...
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HSSFSheet &lt;/span&gt;sheet = templateWorkbook.GetSheet(&lt;span style="color: #a31515"&gt;&amp;quot;Sheet1&amp;quot;&lt;/span&gt;);

        &lt;span style="color: green"&gt;// Getting the row... 0 is the first row.
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HSSFRow &lt;/span&gt;dataRow = sheet.GetRow(4);

        &lt;span style="color: green"&gt;// Setting the value 77 at row 5 column 1
        &lt;/span&gt;dataRow.GetCell(0).SetCellValue(77);

        &lt;span style="color: green"&gt;// Forcing formula recalculation...
        &lt;/span&gt;sheet.ForceFormulaRecalculation = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

        &lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;();

        &lt;span style="color: green"&gt;// Writing the workbook content to the FileStream...
        &lt;/span&gt;templateWorkbook.Write(ms);

        TempData[&lt;span style="color: #a31515"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;] = &lt;span style="color: #a31515"&gt;&amp;quot;Excel report created successfully!&amp;quot;&lt;/span&gt;;

        &lt;span style="color: green"&gt;// Sending the server processed data back to the user computer...
        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;File(ms.ToArray(), &lt;span style="color: #a31515"&gt;&amp;quot;application/vnd.ms-excel&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;NPOINewFile.xls&amp;quot;&lt;/span&gt;);
    }
    &lt;span style="color: blue"&gt;catch&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Exception &lt;/span&gt;ex)
    {
        TempData[&lt;span style="color: #a31515"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;] = &lt;span style="color: #a31515"&gt;&amp;quot;Oops! Something went wrong.&amp;quot;&lt;/span&gt;;

        &lt;span style="color: blue"&gt;return &lt;/span&gt;RedirectToAction(&lt;span style="color: #a31515"&gt;&amp;quot;NPOI&amp;quot;&lt;/span&gt;);
    }
}&lt;/pre&gt;

&lt;p&gt;One drawback of the ExcelPackage library is that it must create a file on the server. There are some modifications to the library that enables you to create the template copy on memory and send it to the user as the NPOI library does. Take a look at the ExcelPackage’s &lt;a href="http://excelpackage.codeplex.com/Thread/List.aspx" target="_blank"&gt;discussion page&lt;/a&gt; at CodePlex and specifically this thread: &lt;a href="http://excelpackage.codeplex.com/Wiki/View.aspx?title=Why%20create%20Excel%20spreadsheets%20on%20the%20server%3f" target="_blank"&gt;Why create Excel spreadsheets on the server?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The great thing about NPOI of course is that it enables you to work with the template in code and the send a copy of the spreadsheet directly to the user. The template remains intact and the user receives a modified copy of the template which contains the data processed by the application.&lt;/p&gt;

&lt;p&gt;With NPOI when you click on the Create Excel report button you get the download dialog window:&lt;/p&gt;

&lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Excel Writer NPOI Download dialog" border="0" alt="Excel Writer NPOI Download dialog" src="http://lh4.ggpht.com/_W1dLiLjFqdw/Sk0_Jl_opVI/AAAAAAAAAk4/VWyddm4FLB4/ExcelWriterNPOISaveFile%5B3%5D.png?imgmax=800" width="414" height="279" /&gt; &lt;/p&gt;

&lt;p align="left"&gt;With ExcelPackage you’d have to get the path of the file created on the server, in this case \Content\ExcelPackageNewFile.xlsx and then send that file to the user. This is an extra step and adds an additional burden to the server. I didn’t implement it and so I let this as an exercise to you.&lt;/p&gt;

&lt;p align="left"&gt;Well, the spreadsheet included in this simple project has only formulas but you can for sure have an Excel template with lots of formulas, pivot tables, macros, etc. This gives you the power of Excel in code in a clean fashion.&lt;/p&gt;

&lt;p align="left"&gt;Hope this helps shed some light on this topic!&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;Note&lt;/strong&gt; 

  &lt;br /&gt;Using the open source libraries presented in this post you won’t need Microsoft Excel installed on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Visual Studio 2008 C# ASP.NET MVC Web Application&lt;/strong&gt; 

    &lt;br /&gt;&lt;/strong&gt;You can get the Microsoft Visual Studio Project at:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://leniel.googlepages.com/ExcelWriterMvcProject.zip" href="http://leniel.googlepages.com/ExcelWriterMvcProject.zip"&gt;http://leniel.googlepages.com/ExcelWriterMvcProject.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To try out the code you can use the free Microsoft Visual Web Developer 2008 Express Edition that you can get at: &lt;a title="http://www.microsoft.com/express/vwd/Default.aspx" href="http://www.microsoft.com/express/vwd/Default.aspx" target="_blank"&gt;http://www.microsoft.com/express/vwd/Default.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References 
    &lt;br /&gt;&lt;/strong&gt;&lt;em&gt;ExcelPackage: Office Open XML Format file creation&lt;/em&gt; 

  &lt;br /&gt;&lt;a title="http://excelpackage.codeplex.com/" href="http://excelpackage.codeplex.com/" target="_blank"&gt;http://excelpackage.codeplex.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ExcelPackage binaries download&lt;/em&gt; 

  &lt;br /&gt;&lt;a title="http://excelpackage.codeplex.com/Release/ProjectReleases.aspx" href="http://excelpackage.codeplex.com/Release/ProjectReleases.aspx" target="_blank"&gt;http://excelpackage.codeplex.com/Release/ProjectReleases.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NPOI&lt;/em&gt; 

  &lt;br /&gt;&lt;a title="http://npoi.codeplex.com/" href="http://npoi.codeplex.com/" target="_blank"&gt;http://npoi.codeplex.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NPOI binaries download&lt;/em&gt; 

  &lt;br /&gt;&lt;a title="http://npoi.codeplex.com/Release/ProjectReleases.aspx" href="http://npoi.codeplex.com/Release/ProjectReleases.aspx" target="_blank"&gt;http://npoi.codeplex.com/Release/ProjectReleases.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Interesting discussion on stackoverflow&lt;/em&gt; 

  &lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/151005/create-excel-xls-and-xlsx-file-from-c" target="_blank"&gt;Create Excel (.XLS and .XLSX) file from C#&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-5526964141051054546?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nSOHdQ2YjecRjJFrvaR4116X9f8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nSOHdQ2YjecRjJFrvaR4116X9f8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nSOHdQ2YjecRjJFrvaR4116X9f8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nSOHdQ2YjecRjJFrvaR4116X9f8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=FZagJN_s27o:-IiUAbi2ifw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=FZagJN_s27o:-IiUAbi2ifw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=FZagJN_s27o:-IiUAbi2ifw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=FZagJN_s27o:-IiUAbi2ifw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=FZagJN_s27o:-IiUAbi2ifw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=FZagJN_s27o:-IiUAbi2ifw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=FZagJN_s27o:-IiUAbi2ifw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=FZagJN_s27o:-IiUAbi2ifw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=FZagJN_s27o:-IiUAbi2ifw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/FZagJN_s27o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/5526964141051054546/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/07/creating-excel-spreadsheets-xls-xlsx-c.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/5526964141051054546?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/5526964141051054546?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/FZagJN_s27o/creating-excel-spreadsheets-xls-xlsx-c.html" title="Creating Excel spreadsheets .XLS and .XLSX in C#" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/07/creating-excel-spreadsheets-xls-xlsx-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkACRXk5fSp7ImA9WxJWFUk.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-5223966581695789663</id><published>2009-06-20T19:07:00.000-03:00</published><updated>2009-06-20T20:32:44.725-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-20T20:32:44.725-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Haversine" /><category scheme="http://www.blogger.com/atom/ns#" term="data structures" /><category scheme="http://www.blogger.com/atom/ns#" term="algorithms" /><category scheme="http://www.blogger.com/atom/ns#" term="geocoder" /><category scheme="http://www.blogger.com/atom/ns#" term="priority queue" /><category scheme="http://www.blogger.com/atom/ns#" term="A*" /><category scheme="http://www.blogger.com/atom/ns#" term="immutable data structures" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="artificial intelligence" /><title>A* pathfinding search in C# - Part 2</title><content type="html">&lt;p&gt;To illustrate the path finding problem and how it can be solved using A* I decided to use the Romania map (with the same Cities I used in &lt;a href="http://www.leniel.net/2008/01/breadth-and-depth-first-search.html" target="_blank"&gt;Breadth and depth first search&lt;/a&gt; series of posts). Now I modified it adding more connections between the cities so that we have more fun while debugging the code.&lt;/p&gt;  &lt;p&gt;This time I decided to get the real values of latitude and longitude for the cities shown in the Romania map. To accomplish this I used this &lt;a href="http://spreadsheets.google.com/ccc?key=r8ffiAqjxNq9mNm-3HQqHKw&amp;amp;hl=en" target="_blank"&gt;Google Spreadsheet&lt;/a&gt; that is a &lt;a href="http://en.wikipedia.org/wiki/Geocoding" target="_blank"&gt;geocoder&lt;/a&gt;. It uses &lt;a href="http://www.google.com/maps" target="_blank"&gt;Google Maps&lt;/a&gt; to get geolocalization data to the address we pass to an URL. For example, to get geodata for Bucharest we’d do the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.google.com/url?q=http://maps.google.com/maps/geo%3Foutput%3Dcsv%26amp%3Bq%3DBucharest,+Romania&amp;amp;usd=2&amp;amp;usg=ALhdy28tq1keifp9E6ihrTWwBmoq3uMVnQ" target="_blank"&gt;http://maps.google.com/maps/geo?output=csv&amp;amp;q=Bucharest, Romania&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The output is:&lt;/p&gt;  &lt;pre&gt;200,4,44.4479237,26.0978790&lt;/pre&gt;

&lt;p&gt;The last two values are the latitude and longitude respectively.&lt;/p&gt;

&lt;p&gt;This is the Map created using the data stored in the spreadsheet with the help of the &lt;a href="http://docs.google.com/support/bin/answer.py?hl=en&amp;amp;answer=91601" target="_blank"&gt;Map gadget&lt;/a&gt; from &lt;a href="http://www.google.com/docs" target="_blank"&gt;Google Docs&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe style="border-bottom: #bbb 1px solid; border-left: #bbb 1px solid; border-top: #bbb 1px solid; border-right: #bbb 1px solid" height="525" marginheight="0" src="http://9tm49u91btpu7le36r63p2sj07eqiv5p.spreadsheets.gmodules.com/gadgets/ifr?up__table_query_url=http%3A%2F%2Fspreadsheets.google.com%2Ftq%3Frange%3DD2%253AE21%26headers%3D-1%26gid%3D0%26key%3Dr8ffiAqjxNq9mNm-3HQqHKw%26pub%3D1&amp;amp;up_title&amp;amp;up_show_tooltip=1&amp;amp;up_enable_wheel=1&amp;amp;up_map_type=normal&amp;amp;up__table_query_refresh_interval=300&amp;amp;url=http%3A%2F%2Fwww.google.com%2Fig%2Fmodules%2Fmap.xml" frameborder="no" width="525" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;You can pass your mouse over each pin to see the name of the city it represents in the map.&lt;/p&gt;

&lt;p&gt;The following picture shows the fictitious connections (paths) between the cities and the cost to move from city to city.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_W1dLiLjFqdw/Sj1j0L2IHKI/AAAAAAAAAj4/exlblLp9_Z8/s1600-h/RomaniaMap%5B33%5D.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Romania Map" border="0" alt="Romania Map" src="http://lh5.ggpht.com/_W1dLiLjFqdw/Sj1dxuN9IgI/AAAAAAAAAj8/qHz2vTDgW_E/RomaniaMap_thumb%5B26%5D.png?imgmax=800" width="525" height="318" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fill the Graph that represents the Romania map above I created a static private method called FillGraphWithEarthMap inside the AStar class that does the job of creating the Nodes and adding them to the graph (bellow I show a shortened version of such a method because it is a really big method given the fact that we have 20 cities and 41 connections (paths) between them:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Fills a Graph with Romania map information.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;The Graph contains Nodes that represents Cities of Romania.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Each Node has as its key the City name and its Latitude and Longitude associated information.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Nodes are vertexes in the Graph. Connections between Nodes are edges.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;graph&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The Graph to be filled&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;distanceType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The DistanceType (KM or Miles) between neighbor cities&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private static void &lt;/span&gt;FillGraphWithEarthMap(&lt;span style="color: #2b91af"&gt;Graph &lt;/span&gt;graph, &lt;span style="color: #2b91af"&gt;DistanceType &lt;/span&gt;distanceType)
{
    &lt;span style="color: green"&gt;// 20 Vertexes in total
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;arad = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Arad&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;, 46.1792414, 21.3150154); &lt;span style="color: green"&gt;// Creating a Node...
    &lt;/span&gt;graph.AddNode(arad); &lt;span style="color: green"&gt;// Adding the Node to the Graph...

    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;bucharest = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Bucharest&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;, 44.4479237, 26.097879);
    graph.AddNode(bucharest);

    &lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;craiova = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Craiova&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;, 44.3182085, 23.8016427);
    graph.AddNode(craiova);

    .&lt;br /&gt;    .&lt;br /&gt;    .&lt;/pre&gt;

&lt;pre class="code"&gt;    &lt;span style="color: green"&gt;// 41 Edges in total
    // Arad &amp;lt;-&amp;gt; Sibiu
    &lt;/span&gt;graph.AddUndirectedEdge(arad, sibiu, &lt;span style="color: #2b91af"&gt;Haversine&lt;/span&gt;.Distance(arad, sibiu, distanceType));
    &lt;span style="color: green"&gt;// Arad &amp;lt;-&amp;gt; Timisoara
    &lt;/span&gt;graph.AddUndirectedEdge(arad, timisoara, &lt;span style="color: #2b91af"&gt;Haversine&lt;/span&gt;.Distance(arad, timisoara, distanceType));
    &lt;span style="color: green"&gt;// Arad &amp;lt;-&amp;gt; Zerind
    &lt;/span&gt;graph.AddUndirectedEdge(arad, zerind, &lt;span style="color: #2b91af"&gt;Haversine&lt;/span&gt;.Distance(arad, zerind, distanceType));&lt;br /&gt;
    .&lt;br /&gt;    .&lt;br /&gt;    .
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;The Vertexes 
    &lt;br /&gt;&lt;/strong&gt;You must create a &lt;a href="http://en.wikipedia.org/wiki/Vertex_%28graph_theory%29" target="_blank"&gt;vertex&lt;/a&gt;/Node for each City of the map, passing to the Node’s class constructor the name of the City and its Latitude and Longitude coordinates. Add each Node to the Graph passed as a parameter to the method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Edges&lt;/strong&gt; 

  &lt;br /&gt;You must create an undirected &lt;a href="http://en.wikipedia.org/wiki/Edge_%28geometry%29" target="_blank"&gt;edge&lt;/a&gt;/path for each connection between two cities, passing to the constructor the first city, the second city and the cost to go from one city to the other. In this case the cost is calculated through the Haversine class discussed in &lt;a href="http://www.leniel.net/2009/06/astar-pathfinding-search-in-csharp.html" target="_blank"&gt;A* pathfinding search in C# - Part 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To help debug the code I created two methods: DistanceBetweenNodes and ViewOtherPaths. Both methods are kept in the AStar class.&lt;/p&gt;

&lt;p&gt;This is the DistanceBetweenNodes method:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Prints on screen the distance from a city to its neighbors.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;graph&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The Graph&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;distanceType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The distance type: KM or Miles&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private static void &lt;/span&gt;DistanceBetweenNodes(&lt;span style="color: #2b91af"&gt;Graph &lt;/span&gt;graph, &lt;span style="color: #2b91af"&gt;DistanceType &lt;/span&gt;distanceType)
{
    &lt;span style="color: green"&gt;// First we cast the Graph.Nodes which is a NodeList to type Node and then we order the list of Nodes by the Node Key
    // so that we get the list of cities in ascending order.
    &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;n &lt;span style="color: blue"&gt;in &lt;/span&gt;graph.Nodes.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;&amp;gt;().OrderBy(n =&amp;gt; n.Key))
    {
        &lt;span style="color: green"&gt;// For each city neighbor we gets its information and print it on screen.
        &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;EdgeToNeighbor &lt;/span&gt;etn &lt;span style="color: blue"&gt;in &lt;/span&gt;n.Neighbors)
        {
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Distance from {0} to {1} is -&amp;gt; {2:#.##} {3}&amp;quot;&lt;/span&gt;, n.Key, etn.Neighbor.Key, etn.Cost, distanceType);
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Inside the FindPath method presented on &lt;a href="http://www.leniel.net/2009/06/astar-pathfinding-search-in-csharp.html" target="_blank"&gt;A* pathfinding search in C# - Part 1&lt;/a&gt;, I call the ViewOtherPaths method (it’s commented out):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;This is the method responsible for finding the shortest path between a Start and Destination cities using the A*
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;search algorithm.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;TNode&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The Node type&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name=&amp;quot;start&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Start city&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;destination&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Destination city&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;distance&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Function which tells us the exact distance between two neighbours.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;estimate&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Function which tells us the estimated distance between the last node on a proposed path and the
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;destination node.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;static public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt; FindPath&amp;lt;TNode&amp;gt;(
    TNode start,
    TNode destination,
    &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;TNode, TNode, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; distance,
    &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;TNode, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; estimate) &lt;span style="color: blue"&gt;where &lt;/span&gt;TNode : &lt;span style="color: #2b91af"&gt;IHasNeighbours&lt;/span&gt;&amp;lt;TNode&amp;gt;
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;closed = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HashSet&lt;/span&gt;&amp;lt;TNode&amp;gt;();

    &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PriorityQueue&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;double&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt;&amp;gt;();

    queue.Enqueue(0, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt;(start));

    &lt;span style="color: blue"&gt;while&lt;/span&gt;(!queue.IsEmpty)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;path = queue.Dequeue();

        &lt;span style="color: blue"&gt;if&lt;/span&gt;(closed.Contains(path.LastStep))
            &lt;span style="color: blue"&gt;continue&lt;/span&gt;;

        &lt;span style="color: blue"&gt;if&lt;/span&gt;(path.LastStep.Equals(destination))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;path;

        closed.Add(path.LastStep);

        &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(TNode n &lt;span style="color: blue"&gt;in &lt;/span&gt;path.LastStep.Neighbours)
        {
            &lt;span style="color: blue"&gt;double &lt;/span&gt;d = distance(path.LastStep, n);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;newPath = path.AddStep(n, d);

            queue.Enqueue(newPath.TotalCost + estimate(n), newPath);
        }

        &lt;span style="color: green"&gt;//ViewOtherPaths(queue, estimate);
    &lt;/span&gt;}

    &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This is the ViewOtherPaths method:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;This method can be used to view the other paths inside the PriorityQueue.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;TNode&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The Node type&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name=&amp;quot;queue&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The priority queue&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;estimate&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Function which tells us the estimated distance between the last node on a proposed path and the
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;destination node.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private static void &lt;/span&gt;ViewOtherPaths&amp;lt;TNode&amp;gt;(&lt;span style="color: #2b91af"&gt;PriorityQueue&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;double&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt;&amp;gt; queue, &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;TNode, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; estimate)
{
    &lt;span style="color: green"&gt;// The priority queue is composed of KeyValuePairs which has as key a double value (the TotalCost) and
    // has as Value a Queue which contains Paths.
    &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;double&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Queue&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt;&amp;gt;&amp;gt; kvp &lt;span style="color: blue"&gt;in &lt;/span&gt;queue)
    {
        &lt;span style="color: green"&gt;// For each path in the Queue...
        &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt; otherPath &lt;span style="color: blue"&gt;in &lt;/span&gt;kvp.Value)
        {
            &lt;span style="color: green"&gt;// Reverse the Path so that we get the order of the cities in a more meaningful way...
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;otherPathReversed = otherPath.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;&amp;gt;().Reverse();

            &lt;span style="color: green"&gt;// Prints on screen the Cities that are part of this path.
            &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;n &lt;span style="color: blue"&gt;in &lt;/span&gt;otherPathReversed)
            {
                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(n.Key);
            }

            &lt;span style="color: green"&gt;// Get the total cost of the other path.
            &lt;/span&gt;&lt;span style="color: blue"&gt;double &lt;/span&gt;otherPathTotalCost = otherPath.TotalCost;
            &lt;span style="color: green"&gt;// Get the estimation cost of the other path.
            &lt;/span&gt;&lt;span style="color: blue"&gt;double &lt;/span&gt;otherPathEstimation = estimate(otherPath.LastStep);

            &lt;span style="color: green"&gt;// Prints on the screen the relevant information so that it gets easier to debug the code and see how
            // the A* search algorithm really does the job...
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Total Cost other path = {0}&amp;quot;&lt;/span&gt;, otherPathTotalCost);
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Estimation other path = {0}&amp;quot;&lt;/span&gt;, otherPathEstimation);
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;@&amp;quot;Priority Queue Cost other path = {0} =
                            Total Cost other path + Estimation other path =
                            {1}&amp;quot;&lt;/span&gt;, kvp.Key, otherPathTotalCost + otherPathEstimation);
        }

        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine();
    }

    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine();
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I also use two additional methods to get the Start and Destination cities entered by the user when s/he runs the code. Both methods keep a loop until the user enters the name of a city that is indeed part of the Graph we’ve just created:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Gets the Destination city.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;graph&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The Graph&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Name of Destination city&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private static string &lt;/span&gt;GetDestinationCity(&lt;span style="color: #2b91af"&gt;Graph &lt;/span&gt;graph)
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;destinationCity;&lt;br /&gt;
    &lt;span style="color: blue"&gt;do
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\nEnter a Destination city: &amp;quot;&lt;/span&gt;);

        destinationCity = &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();
    }
    &lt;span style="color: blue"&gt;while&lt;/span&gt;(!graph.Nodes.ContainsKey(destinationCity));&lt;br /&gt;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;destinationCity;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Gets the Destination city.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;graph&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The Graph&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Name of Destination city&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private static string &lt;/span&gt;GetDestinationCity(&lt;span style="color: #2b91af"&gt;Graph &lt;/span&gt;graph)
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;destinationCity;&lt;br /&gt;
    &lt;span style="color: blue"&gt;do
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\nEnter a Destination city: &amp;quot;&lt;/span&gt;);

        destinationCity = &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();
    }
    &lt;span style="color: blue"&gt;while&lt;/span&gt;(!graph.Nodes.ContainsKey(destinationCity));&lt;br /&gt;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;destinationCity;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This is the main entry point of the Console Application I created:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color: blue"&gt;do
    &lt;/span&gt;{
        &lt;span style="color: green"&gt;// Creating the Graph...
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Graph &lt;/span&gt;graph = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Graph&lt;/span&gt;();

        &lt;span style="color: green"&gt;//FillGraphWithGridMap(graph);

        &lt;/span&gt;FillGraphWithEarthMap(graph, &lt;span style="color: #2b91af"&gt;DistanceType&lt;/span&gt;.Kilometers);

        &lt;span style="color: green"&gt;// Prints on the screen the distance from a city to its neighbors.
        // Used mainly for debug information.
        // DistanceBetweenNodes(graph, DistanceType.Kilometers);

        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;A* Search - Sample implementation by Leniel Macaferi, June 7-20, 2009\n&amp;quot;&lt;/span&gt;);
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;These are the Cities you can choose as Start and Destination in Romania: \n&amp;quot;&lt;/span&gt;);

        &lt;span style="color: green"&gt;// Prints on screen the cities that you can choose as Start and Destination.
        &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;n &lt;span style="color: blue"&gt;in &lt;/span&gt;graph.Nodes.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;&amp;gt;().OrderBy(n =&amp;gt; n.Key))
        {
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(n.Key);
        }

        &lt;span style="color: blue"&gt;string &lt;/span&gt;startCity = GetStartCity(graph);

        &lt;span style="color: blue"&gt;string &lt;/span&gt;destinationCity = GetDestinationCity(graph);

        &lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;start = graph.Nodes[startCity];

        &lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;destination = graph.Nodes[destinationCity];

        &lt;span style="color: green"&gt;// Function which tells us the exact distance between two neighbours.
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; distance = (node1, node2) =&amp;gt; node1.Neighbors.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;EdgeToNeighbor&lt;/span&gt;&amp;gt;().Single(etn =&amp;gt; etn.Neighbor.Key == node2.Key).Cost;

        &lt;span style="color: green"&gt;// Estimation/Heuristic function (Manhattan distance)
        // It tells us the estimated distance between the last node on a proposed path and the destination node.
        //Func&amp;lt;Node, double&amp;gt; manhattanEstimation = n =&amp;gt; Math.Abs(n.X - destination.X) + Math.Abs(n.Y - destination.Y);

        // Estimation/Heuristic function (Haversine distance)
        // It tells us the estimated distance between the last node on a proposed path and the destination node.
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; haversineEstimation = n =&amp;gt; &lt;span style="color: #2b91af"&gt;Haversine&lt;/span&gt;.Distance(n, destination, &lt;span style="color: #2b91af"&gt;DistanceType&lt;/span&gt;.Kilometers);

        &lt;span style="color: green"&gt;//Path&amp;lt;Node&amp;gt; shortestPath = FindPath(start, destination, distance, manhattanEstimation);
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;&amp;gt; shortestPath = FindPath(start, destination, distance, haversineEstimation);

        &lt;span style="color: green"&gt;// Prints the shortest path.
        &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Node &lt;/span&gt;n &lt;span style="color: blue"&gt;in &lt;/span&gt;shortestPath.Reverse())
        {
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(n.Key);
        }

        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\nDo you wanna try A* Search again? Yes or No? &amp;quot;&lt;/span&gt;);
    }
    &lt;span style="color: blue"&gt;while&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine().ToLower() == &lt;span style="color: #a31515"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;

&lt;p&gt;The main entry point above calls all the other methods I showed in this post.&lt;/p&gt;

&lt;p&gt;This is all you need to run the A* pathfinding search algorithm! &lt;strong&gt;:-)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think the code is well documented through comments.&lt;/p&gt;

&lt;p&gt;I wish this helps you understand how to put together the working pieces necessary to run a test case.&lt;/p&gt;

&lt;p&gt;Next time: I’ll run a test case using the Graph we have assembled in this post.&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-5223966581695789663?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PDomSEhHXNK7Z-UCzkw4rEE-2Y8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PDomSEhHXNK7Z-UCzkw4rEE-2Y8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PDomSEhHXNK7Z-UCzkw4rEE-2Y8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PDomSEhHXNK7Z-UCzkw4rEE-2Y8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=sh8ax-Ohj9A:6GPx4-ukdm8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=sh8ax-Ohj9A:6GPx4-ukdm8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=sh8ax-Ohj9A:6GPx4-ukdm8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=sh8ax-Ohj9A:6GPx4-ukdm8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=sh8ax-Ohj9A:6GPx4-ukdm8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=sh8ax-Ohj9A:6GPx4-ukdm8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=sh8ax-Ohj9A:6GPx4-ukdm8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=sh8ax-Ohj9A:6GPx4-ukdm8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=sh8ax-Ohj9A:6GPx4-ukdm8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/sh8ax-Ohj9A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/5223966581695789663/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/06/astar-pathfinding-search-csharp-part-2.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/5223966581695789663?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/5223966581695789663?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/sh8ax-Ohj9A/astar-pathfinding-search-csharp-part-2.html" title="A* pathfinding search in C# - Part 2" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.leniel.net/2009/06/astar-pathfinding-search-csharp-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQMRHw5fyp7ImA9WxJWFUk.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-7211674246453752594</id><published>2009-06-13T22:33:00.005-03:00</published><updated>2009-06-20T20:26:25.227-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-20T20:26:25.227-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Haversine" /><category scheme="http://www.blogger.com/atom/ns#" term="data structures" /><category scheme="http://www.blogger.com/atom/ns#" term="algorithms" /><category scheme="http://www.blogger.com/atom/ns#" term="priority queue" /><category scheme="http://www.blogger.com/atom/ns#" term="A*" /><category scheme="http://www.blogger.com/atom/ns#" term="immutable data structures" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="artificial intelligence" /><title>A* pathfinding search in C# - Part 1</title><content type="html">&lt;p&gt;Last Sunday after I got back from church I read Kirill Osenkov’s post &lt;a href="http://blogs.msdn.com/kirillosenkov/archive/2009/06/07/algorithms-in-c-shortest-path-around-a-polygon-polyline-routing.aspx" target="_blank"&gt;Algorithms in C#: shortest path around a polygon (polyline routing)&lt;/a&gt;. Kirill mentions Eric Lippert’s excellent series of posts titled &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx" target="_blank"&gt;Path Finding Using A* in C# 3.0&lt;/a&gt;. I’ve read that series of posts a long time ago (2007 - I was on the last year of the computer engineering course).&lt;/p&gt;  &lt;p&gt;See you how life is interesting: in 2007 after reading Lippert’s posts I wanted to see a running sample of the code but didn’t try to implement that until the time I read Osenkov’s post. Why did it took so long? I don’t know how to answer this.&lt;/p&gt;  &lt;p&gt;I studied A* in the 9th term of the computer engineering course&amp;#160; (Feb-Jun, 2007). The discipline was Artificial Intelligence. At that time I didn’t implement any code for this specific algorithm (I think this is due the so famous excuse during the classes - we just don’t have enough time to do that. We have lots of topics to see yet.) . Therefore, we’ve just run test cases on sheets of paper. Not so good but a start.&lt;/p&gt;  &lt;p&gt;Well, Eric wrote the base structure of the &lt;a href="http://en.wikipedia.org/wiki/A*" target="_blank"&gt;A* pathfinding algorithm&lt;/a&gt; but didn’t provide a complete running sample. He wrote the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I have a nice example of using A* to find the shortest path around a lake (but not the &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/12/15/whidbey-island-and-bagel-mathematics.aspx" target="_blank"&gt;longest shortest path&lt;/a&gt;!) but I'm not going to post it here until Orcas ships. I'll just put up the whole project file at that time and you can check it out all at once.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Still on Sunday night I took the time to write some code that put up a running A* search.&lt;/p&gt;  &lt;p&gt;I basically merged some code I had already posted on the series of posts titled &lt;a href="http://www.leniel.net/2008/01/breadth-and-depth-first-search.html" target="_blank"&gt;Breadth and depth first search&lt;/a&gt; and created some properties here and there to get the whole thing running. It’s nothing more than &lt;a href="http://en.wikipedia.org/wiki/Code_reuse" target="_blank"&gt;code reuse&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The following is the basic project’s structure I created:&lt;/p&gt;  &lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A* Search Solution Explorer" border="0" alt="A* Search Solution Explorer" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SjRZFys5mCI/AAAAAAAAAjo/iSqYaHvSotg/AStarSearchSolutionExplorer%5B3%5D.png?imgmax=800" width="199" height="293" /&gt; &lt;/p&gt;  &lt;p&gt;In &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx" target="_blank"&gt;Path Finding Using A* in C# 3.0, Part One&lt;/a&gt; the A* algorithm is described.&lt;/p&gt;  &lt;p&gt;In &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx" target="_blank"&gt;Path Finding Using A* in C# 3.0, Part Two&lt;/a&gt; the data structures necessary to implement the A* algorithm are defined.&lt;/p&gt;  &lt;p&gt;In this part Eric writes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Let’s make an immutable stack of nodes which tracks the total cost of the whole path. Later on, we’ll see that we need to enumerate the nodes of this thing, so we’ll do a trivial implementation of IEnumerable while we’re at it. And since we don’t know exactly what a node will look like, let’s make the thing generic.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In part two we are presented to an &lt;a href="http://en.wikipedia.org/wiki/Immutable_object" target="_blank"&gt;immutable&lt;/a&gt; stack that I’ve put inside the Path class.&lt;/p&gt; &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;p&gt;In &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/10/08/path-finding-using-a-in-c-3-0-part-three.aspx" target="_blank"&gt;Path Finding Using A* in C# 3.0, Part Three&lt;/a&gt; we are presented to a &lt;a href="http://en.wikipedia.org/wiki/Priority_queue" target="_blank"&gt;priority queue&lt;/a&gt;. This structure is responsible for putting the best paths so far in priority order, that is, the path with a lesser cost has a major priority.&lt;/p&gt;  &lt;p&gt;In this part Eric writes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;In order to make the A* algorithm work we need to get the lowest-estimated-cost-path-discovered-so-far out of the list of paths under consideration. The standard data structure for doing so is called a “priority queue”. Priority queues are so-called because they are typically used to store a list of jobs where each job has an associated priority.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The PriorityQueue lies within its namesake class.&lt;/p&gt;  &lt;p&gt;In &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx" target="_blank"&gt;Path Finding Using A* in C# 3.0, Part Four&lt;/a&gt; we get the FindPath method that is the one responsible for finding the shortest path possible. This method uses all of the remaining classes shown on the project structure above.&lt;/p&gt;  &lt;p&gt;I put the FindPath method inside the AStar class.&lt;/p&gt;  &lt;p&gt;In this part Eric writes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;What do we need to make the algorithm run? We need a start node, a destination node, a function which tells us the exact distance between two neighbours, and a function which tells us the estimated distance between the last node on a proposed path and the destination node.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is the beautiful PathFind method: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;static public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt; FindPath&amp;lt;TNode&amp;gt;(
    TNode start,
    TNode destination,
    &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;TNode, TNode, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; distance,
    &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;TNode, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; estimate) &lt;span style="color: blue"&gt;where &lt;/span&gt;TNode : &lt;span style="color: #2b91af"&gt;IHasNeighbours&lt;/span&gt;&amp;lt;TNode&amp;gt;
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;closed = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HashSet&lt;/span&gt;&amp;lt;TNode&amp;gt;();

    &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PriorityQueue&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;double&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt;&amp;gt;();

    queue.Enqueue(0, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;&amp;lt;TNode&amp;gt;(start));

    &lt;span style="color: blue"&gt;while&lt;/span&gt;(!queue.IsEmpty)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;path = queue.Dequeue();

        &lt;span style="color: blue"&gt;if&lt;/span&gt;(closed.Contains(path.LastStep))
            &lt;span style="color: blue"&gt;continue&lt;/span&gt;;

        &lt;span style="color: blue"&gt;if&lt;/span&gt;(path.LastStep.Equals(destination))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;path;

        closed.Add(path.LastStep);

        &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(TNode n &lt;span style="color: blue"&gt;in &lt;/span&gt;path.LastStep.Neighbours)
        {
            &lt;span style="color: blue"&gt;double &lt;/span&gt;d = distance(path.LastStep, n);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;newPath = path.AddStep(n, d);

            queue.Enqueue(newPath.TotalCost + estimate(n), newPath);
        }
    }

    &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;font color="#666666"&gt;&lt;/font&gt;

&lt;p&gt;When you get at the fourth part of Eric’s posts you may get thinking: How can I run this thing? That’s what I try to explain in this post.&lt;/p&gt;

&lt;p&gt;The immutable stack implemented in part two of Eric’s posts is a &lt;a href="http://en.wikipedia.org/wiki/Generic_programming" target="_blank"&gt;generic&lt;/a&gt; one, that is, it accepts an object custom made to represent a Node in the path.&lt;/p&gt;

&lt;p&gt;I already had a class Node that I used sometime ago while studying Artificial Intelligence. Take a look at &lt;a href="http://www.leniel.net/2008/01/breadth-and-depth-first-search.html" target="_blank"&gt;Breadth and depth first search&lt;/a&gt; series of posts.&lt;/p&gt;

&lt;p&gt;I also needed a Graph that represents the map formed with the connections between the nodes.&lt;/p&gt;

&lt;p&gt;The Graph has a NodeList that stores all the nodes currently in the graph.&lt;/p&gt;

&lt;p&gt;A node can have neighbors, that is, other nodes connected to it and such connections are represented in the code through the class AdjacencyList. Each node has an AdjacencyList that stores its neighbors.&lt;/p&gt;

&lt;p&gt;A connection (edge) between two nodes (vertexes) is represented by the EdgeToNeighbor class that stores the neighbor of a node and the cost to get to that neighbor.&lt;/p&gt;

&lt;p&gt;The AdjacencyList, EdgeToNeighbor, Graph, Node and NodeList classes are the outcome of an excellent series of articles by Scott Mitchell titled &lt;a href="http://msdn.microsoft.com/en-us/library/ms379570%28VS.80%29.aspx" target="_blank"&gt;An Introduction to Data Structures&lt;/a&gt;. I got those classes and added them to the project.&lt;/p&gt;

&lt;p&gt;This way I had all set to pass in the first two parameters of the PathFind method.&lt;/p&gt;

&lt;p&gt;Now I needed to figure out how to create the distance and estimate functions to pass as the third and fourth parameters.&lt;/p&gt;

&lt;p&gt;For the distance function I did this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Function which tells us the exact distance between two neighbours.
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; distance = (node1, node2) =&amp;gt; node1.Neighbors.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;EdgeToNeighbor&lt;/span&gt;&amp;gt;().Single(etn =&amp;gt; etn.Neighbor.Key == node2.Key).Cost;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The distance function receives two nodes as parameters as can be seen in the PathFind method and returns a double value. I then use a lambda expression to find the Cost, (distance) in this case, between the two nodes. I get the neighbors of node1 and cast those to EdgeToNeighbor and execute a query using a lambda expression again to return the Cost only if the key of one of the neighbors of node1 is equal to the key of node2.&lt;/p&gt;

&lt;p&gt;For the estimation function I did this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Estimation/Heuristic function (Haversine distance)
// It tells us the estimated distance between the last node on a proposed path and the destination node.
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Node&lt;/span&gt;, &lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt; haversineEstimation = n =&amp;gt; &lt;span style="color: #2b91af"&gt;Haversine&lt;/span&gt;.Distance(n, destination, &lt;span style="color: #2b91af"&gt;DistanceType&lt;/span&gt;.Kilometers);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now I’m using as the estimation the &lt;a href="http://en.wikipedia.org/wiki/Haversine_formula" target="_blank"&gt;Haversine formula&lt;/a&gt;. This formula gives the great-circle distances between two points on a sphere (Earth) from their longitudes and latitudes.&lt;/p&gt;

&lt;p&gt;I got the Haversine formula code from the post &lt;a href="http://megocode3.wordpress.com/2008/02/05/haversine-formula-in-c/" target="_blank"&gt;Haversine Formula in C# and in SQL&lt;/a&gt; by Seth Long. I just adapted it a little bit so that I could use it with the Node data structure.&lt;/p&gt;

&lt;p&gt;The haversine generic delegate receives as input a Node and return a double. Using a lambda expression I get the Haversine distance from node n to the destination node and I set that I want the distance in Kilometers.&lt;/p&gt;

&lt;p&gt;With the distance and estimate functions on hand we’re OK to call the PathFind method. 
  &lt;br /&gt;Wait! Don’t we need something before that? Of course we need. We need to populate the graph with nodes. After all we’re after the shortest path between two nodes and we need some nodes to test the A* star pathfinding search. &lt;strong&gt;:-)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.leniel.net/2009/06/astar-pathfinding-search-csharp-part-2.html" target="_blank"&gt;Next time&lt;/a&gt;: I’ll show you how to create a complete scenario using the same Romania map I used in the &lt;a href="http://www.leniel.net/2008/01/breadth-and-depth-first-search.html" target="_blank"&gt;Breadth and depth first search&lt;/a&gt; series of posts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; 

  &lt;br /&gt;[1] Lippert, Eric. &lt;strong&gt;Path Finding Using A* in C# 3.0, Part One&lt;/strong&gt;. 2007. Available at &amp;lt;&lt;a title="http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx" href="http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx" target="_blank"&gt;&lt;strong&gt;http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on June 13, 2009.&lt;/p&gt;

&lt;p&gt;[2] Lippert, Eric. &lt;strong&gt;Path Finding Using A* in C# 3.0, Part Two&lt;/strong&gt;. 2007. Available at &amp;lt;&lt;a title="http://blogs.msdn.com/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx" href="http://blogs.msdn.com/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx" target="_blank"&gt;&lt;strong&gt;http://blogs.msdn.com/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on June 13, 2009.&lt;/p&gt;

&lt;p&gt;[3] Lippert, Eric. &lt;strong&gt;Path Finding Using A* in C# 3.0, Part Three&lt;/strong&gt;. 2007. Available at &amp;lt;&lt;a title="http://blogs.msdn.com/ericlippert/archive/2007/10/08/path-finding-using-a-in-c-3-0-part-three.aspx" href="http://blogs.msdn.com/ericlippert/archive/2007/10/08/path-finding-using-a-in-c-3-0-part-three.aspx" target="_blank"&gt;&lt;strong&gt;http://blogs.msdn.com/ericlippert/archive/2007/10/08/path-finding-using-a-in-c-3-0-part-three.aspx&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on June 13, 2009.&lt;/p&gt;

&lt;p&gt;[4] Lippert, Eric. &lt;strong&gt;Path Finding Using A* in C# 3.0, Part Four&lt;/strong&gt;. 2007. Available at &amp;lt;&lt;a title="http://blogs.msdn.com/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx" href="http://blogs.msdn.com/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx" target="_blank"&gt;&lt;strong&gt;http://blogs.msdn.com/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on June 13, 2009.&lt;/p&gt;

&lt;p&gt;[5] Mitchell, Scott. &lt;strong&gt;An Extensive Examination of Data Structures&lt;/strong&gt;. 2005. Available at &amp;lt;&lt;a title="http://msdn.microsoft.com/en-us/library/ms379570%28VS.80%29.aspx" href="http://msdn.microsoft.com/en-us/library/ms379570%28VS.80%29.aspx" target="_blank"&gt;&lt;strong&gt;http://msdn.microsoft.com/en-us/library/ms379570(VS.80).aspx&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on June 13, 2009.&lt;/p&gt;

&lt;p&gt;[6] Long, Seth. &lt;strong&gt;Haversine Formula in C# and in SQL&lt;/strong&gt;. 2008. Available at &amp;lt;&lt;a href="http://megocode3.wordpress.com/2008/02/05/haversine-formula-in-c/" target="_blank"&gt;&lt;strong&gt;http://megocode3.wordpress.com/2008/02/05/haversine-formula-in-c&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on June 13, 2009.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-7211674246453752594?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TliqFvAFAoUvmRJ5AJ8cME-NFmw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TliqFvAFAoUvmRJ5AJ8cME-NFmw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TliqFvAFAoUvmRJ5AJ8cME-NFmw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TliqFvAFAoUvmRJ5AJ8cME-NFmw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=uOL6HssgFPg:muMesKUGusI:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=uOL6HssgFPg:muMesKUGusI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=uOL6HssgFPg:muMesKUGusI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=uOL6HssgFPg:muMesKUGusI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=uOL6HssgFPg:muMesKUGusI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=uOL6HssgFPg:muMesKUGusI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=uOL6HssgFPg:muMesKUGusI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=uOL6HssgFPg:muMesKUGusI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=uOL6HssgFPg:muMesKUGusI:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/uOL6HssgFPg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/7211674246453752594/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/06/astar-pathfinding-search-in-csharp.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/7211674246453752594?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/7211674246453752594?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/uOL6HssgFPg/astar-pathfinding-search-in-csharp.html" title="A* pathfinding search in C# - Part 1" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/06/astar-pathfinding-search-in-csharp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04GRXo8eyp7ImA9WxJQGE4.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-6277684004242170700</id><published>2009-05-31T03:33:00.000-03:00</published><updated>2009-06-01T04:05:24.473-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-01T04:05:24.473-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="algorithms" /><category scheme="http://www.blogger.com/atom/ns#" term="prime number" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="LINQ" /><title>Calculating prime numbers with LINQ in C#</title><content type="html">    &lt;style type="text/css"&gt;
	
	table.jQuery1
	{
		border: 1px solid #666;
	}
	
	table.jQuery1 tr td
	{
		font-size: 10pt;
		font-family: Arial;
		padding: 3px 8px;
		background: #fff;
	}
	
	table.jQuery1 thead td
	{
		color: #fff;
		background-color: #999999;
		font-weight: bold;
		border-bottom: 1px solid #999;
	}
	
	table.jQuery1 tbody td
	{
			border-left: 1px solid #D9D9D9;
	}
	
	table.jQuery1 tbody td a
	{
		color:#000000;
		text-decoration:underline;
	}
	
	table.jQuery1 tbody td a:hover
	{
		color:#000000;
		text-decoration:none;
	}
	
	table.jQuery1 tbody tr.even td
	{
		background: #eee;
	}
		
	table.jQuery1 tbody tr.highlight td
	{
		color: #000;
		background-color: #C6E3FF; 
		border-color: #3292FC;
	}
	
	/* Opera fix */
	table.jQuery1 head:first-child+body tr.ruled td
	{
		background-color: #C6E3FF; 
	}
&lt;/style&gt;           &lt;script type="text/javascript"&gt;
$(document).ready(function()
{
    //DOM is ready - lets go!

    //Hover function
    $("table.jQuery1 tr").hover(function() {
        //On mouse over apply the class to the item (this = itself)
        $(this).addClass("highlight");

    }, function() {
        //On mouse out remove the class we have added on the mouse over
        $(this).removeClass("highlight");
    });

    //Select the even tr elements within the "TableStripe" ID and add the class "even"
    $("table.jQuery1 tr:even").addClass("even");
}); 
&lt;/script&gt;  &lt;p&gt;To serve as a processing test in a follow up post I’m posting how to calculate prime numbers using a &lt;a href="http://en.wikipedia.org/wiki/LINQ" target="_blank"&gt;LINQ&lt;/a&gt; query expression.&lt;/p&gt;  &lt;p&gt;In mathematics, a &lt;a href="http://en.wikipedia.org/wiki/Prime_number" target="_blank"&gt;prime number&lt;/a&gt; (or a prime) is a &lt;a href="http://en.wikipedia.org/wiki/Natural_number" target="_blank"&gt;natural number&lt;/a&gt; which has exactly two &lt;i&gt;distinct&lt;/i&gt; natural number divisors: 1 and itself. The first twenty-five prime numbers are:&lt;/p&gt;  &lt;p align="center"&gt;2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97&lt;/p&gt;  &lt;p&gt;The following code&lt;sup&gt;&lt;a href="http://www.leniel.net/2009/05/calculating-prime-numbers-linq-csharp.html#perfetti"&gt;[1]&lt;/a&gt;&lt;/sup&gt; shows how to calculate the prime numbers that are less equal ( &lt;font face="Courier New"&gt;&amp;lt;=&lt;/font&gt; ) a given number “max”:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;&amp;gt; primeNumbers = max =&amp;gt;
     &lt;span style="color: blue"&gt;from &lt;/span&gt;i &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(2, max - 1)
     &lt;span style="color: blue"&gt;where &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(2, i - 2).All(j =&amp;gt; i % j != 0)
     &lt;span style="color: blue"&gt;select &lt;/span&gt;i;

&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; result = primeNumbers(10);&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: blue"&gt;int&lt;/span&gt; i &lt;span style="color: blue"&gt;in &lt;/span&gt;result)
{
  &lt;span style="color: green"&gt;&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(i);
}&lt;/pre&gt;

&lt;p&gt;In my final computer engineering assignment I presented &lt;a href="http://www.leniel.net/2008/01/linq-language-integrated-query.html" target="_blank"&gt;LINQ - Language Integrated Query&lt;/a&gt; and its constructs. With such constructs it’s possible to achieve a high degree of &lt;a href="http://en.wikipedia.org/wiki/Method_chaining" target="_blank"&gt;method chaining&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;LINQ is &lt;a href="http://en.wikipedia.org/wiki/Declarative_programming" target="_blank"&gt;declarative&lt;/a&gt;, not &lt;a href="http://en.wikipedia.org/wiki/Imperative_programming" target="_blank"&gt;imperative&lt;/a&gt;. It allows us to simply state what we want to do without worrying about how it is done.&lt;/p&gt;

&lt;p&gt;In the code above we declare a &lt;font size="2" face="Courier New"&gt;&lt;span&gt;Func&amp;lt;(Of &amp;lt;(T, TResult&amp;gt;)&amp;gt;)&lt;/span&gt;&lt;/font&gt; generic &lt;a href="http://en.wikipedia.org/wiki/Delegate_%28.NET%29" target="_blank"&gt;delegate&lt;/a&gt; which has an int as input parameter and an &lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: #006666"&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;font color="#0000ff"&gt;&lt;span&gt;int&lt;/span&gt;&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt; as the result. 

  &lt;br /&gt;Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data.&lt;/p&gt;

&lt;p&gt;Using a &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx" target="_blank"&gt;lambda expression&lt;/a&gt; &lt;font size="2"&gt;( &lt;font face="Courier New"&gt;=&amp;gt;&lt;/font&gt; )&lt;/font&gt; we assign a &lt;a href="http://msdn.microsoft.com/en-us/library/bb397676.aspx" target="_blank"&gt;query expression&lt;/a&gt; to the delegate. 

  &lt;br /&gt;A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.&lt;/p&gt;

&lt;p&gt;The query expression states that &lt;font color="#0000ff" size="2" face="Courier New"&gt;from&lt;/font&gt; each value &lt;font face="Courier New"&gt;i&lt;/font&gt; in the &lt;span style="font-family: courier new; color: #2b91af"&gt;Enumerable&lt;/span&gt;.&lt;font face="Courier New"&gt;Range(2, max - 1)&lt;/font&gt; &lt;font color="#0000ff" face="Courier New"&gt;where&lt;/font&gt; all elements of the range &lt;span style="color: #2b91af"&gt;&lt;font face="Courier New"&gt;Enumerable&lt;/font&gt;&lt;/span&gt;.&lt;font face="Courier New"&gt;Range(2, i – 2)&lt;/font&gt; satisfy the condition &lt;font face="Courier New"&gt;All(j =&amp;gt; i % j != 0)&lt;/font&gt;, we &lt;font color="#0000ff" face="Courier New"&gt;select&lt;/font&gt; &lt;font face="Courier New"&gt;i&lt;/font&gt;.&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span&gt;max&lt;/span&gt;&lt;/font&gt; is the delegate input parameter.&lt;/p&gt;

&lt;p&gt;The &lt;font face="Courier New"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx" target="_blank"&gt;%&lt;/a&gt;&lt;/font&gt; symbol is the &lt;a href="http://en.wikipedia.org/wiki/Modulo_operation" target="_blank"&gt;modulus operator&lt;/a&gt; in C#. It computes the remainder after dividing its first operand by its second.&lt;/p&gt;

&lt;p&gt;For example: considering max = 10 we’d have the following…&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;from&lt;/span&gt;&lt;/font&gt; clause is: { 2, 3, 4, 5, 6, 7, 8, 9, 10 }&lt;/p&gt;

&lt;p&gt;Taking the 1st value out of the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;from&lt;/span&gt;&lt;/font&gt; range, we have i = 2.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 2 - 2) = Range (2 , 0) = {&amp;#160; }.&lt;/p&gt;

&lt;p&gt;Since i = 2 is by default included in the result, what must be evaluated lies where the variable max is used. So, taking the 2nd value and assigning it to i we have i = 3.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 3 - 2) = Range (2 , 1) = { 2 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 3 % 2 = 1, and so, 3 is a prime number.&lt;/p&gt;

&lt;p&gt;Taking the 3rd value and assigning it to i we have i = 4.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2,&amp;#160; 4 - 2) = Range (2, 2) = { 2, 3 }.&lt;/p&gt;

&lt;p&gt;Evaluating&lt;span&gt; &lt;/span&gt;&lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 4 % 2 = 0 and 4 % 3 = 1, and so 4 is not a prime number because all elements of the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; range must yield a result &lt;span style="font-family: &amp;#39;Courier New&amp;#39;"&gt;!= 0&lt;/span&gt; for the expression &lt;font face="Courier New"&gt;&lt;span&gt;i % j != 0&lt;/span&gt;&lt;/font&gt;.&lt;/p&gt;

&lt;p&gt;Now we have i = 5.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 5 - 2) = Range (2 , 3) = { 2, 3, 4 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 5 % 2 = 1, 5 % 3 = 2 and 5 % 4 = 1. From this we have that 5 is a prime number.&lt;/p&gt;

&lt;p&gt;Now we have i = 6.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 6 - 2) = Range (2 , 4) = { 2, 3, 4, 5 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 6 % 2 = 0, 6 % 3 = 0, 6 % 4 = 2 and 6 % 5 = 1. From this we have that 6 is not prime number.&lt;/p&gt;

&lt;p&gt;Now we have i = 7.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 7 - 2) = Range (2 , 5) = { 2, 3, 4, 5, 6 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 7 % 2 = 1, 7 % 3 = 1, 7 % 4 = 3, 7 % 5 = 2 and 7 % 6 = 1. From this we have that 7 is prime number.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_W1dLiLjFqdw/SiIk4Tq96ZI/AAAAAAAAAiw/iw4a0fQvE5w/s1600-h/DebuggingPrimeNumbersLINQQueryExpression%5B7%5D.png" target="_blank"&gt;&lt;font size="2"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="DebuggingPrimeNumbersLINQQueryExpression" border="0" alt="DebuggingPrimeNumbersLINQQueryExpression" src="http://lh6.ggpht.com/_W1dLiLjFqdw/SiIk5UbOQgI/AAAAAAAAAi0/Xa3_j4kFc2s/DebuggingPrimeNumbersLINQQueryExpression_thumb%5B3%5D.png?imgmax=800" width="511" height="493" /&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have i = 8.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 8 - 2) = Range (2 , 6) = { 2, 3, 4, 5, 6, 7 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 8 % 2 = 0, 8 % 3 = 2, 8 % 4 = 0, 8 % 5 = 3, 8 % 6 = 2 and 8 % 7 = 1. 8 isn’t a prime number.&lt;/p&gt;

&lt;p&gt;Now we have i = 9.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 9 - 2) = Range (2 , 7) = { 2, 3, 4, 5, 6, 7, 8 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 9 % 2 = 1, 9 % 3 = 0, 9 % 4 = 1, 9 % 5 = 4, 9 % 6 = 3, 9 % 7 = 2 and 9 % 8 = 1. 9 isn’t a prime number.&lt;/p&gt;

&lt;p&gt;Now we have i = 10.&lt;/p&gt;

&lt;p&gt;The range in the &lt;font color="#0000ff" face="Courier New"&gt;&lt;span&gt;where&lt;/span&gt;&lt;/font&gt; clause is Range (2, 10 - 2) = Range (2 , 8) = { 2, 3, 4, 5, 6, 7, 8, 9 }.&lt;/p&gt;

&lt;p&gt;Evaluating &lt;font face="Courier New"&gt;&lt;span&gt;j =&amp;gt; i % j&lt;/span&gt;&lt;/font&gt; we have 10 % 2 = 0, 10 % 3 = 1, 10 % 4 = 2, 10 % 5 = 0, 10 % 6 = 4, 10 % 7 = 3, 10 % 8 = 2 and 10 % 9 = 1. 10 isn’t a prime number.&lt;/p&gt;

&lt;p&gt;Finally we have 4 prime numbers &lt;font face="Courier New"&gt;&lt;span&gt;&amp;lt;=&lt;/span&gt;&lt;/font&gt; 10; they are: { 2, 3, 5, 7 }.&lt;/p&gt;

&lt;p&gt;The following table illustrates the result:&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="75%" align="center" class="jQuery1"&gt;&lt;thead&gt;
    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;i&lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;&lt;font color="#0000ff" size="2" face="Courier New"&gt;where&lt;/font&gt; Range(2, i - 2)&lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;All(j =&amp;gt; i % j != 0)&lt;/td&gt;
    &lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;2 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;&amp;#160; &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;3 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;3 % 2 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;4 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;4 % 2 = 0 
        &lt;br /&gt;4 % 3 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;5 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3, 4 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;5 % 2 = 1 
        &lt;br /&gt;5 % 3 = 2 

        &lt;br /&gt;5 % 4 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;6 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3, 4, 5 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;6 % 2 = 0 
        &lt;br /&gt;6 % 3 = 0 

        &lt;br /&gt;6 % 4 = 2 

        &lt;br /&gt;6 % 5 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;7 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3, 4, 5, 6 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;7 % 2 = 1 
        &lt;br /&gt;7 % 3 = 1 

        &lt;br /&gt;7 % 4 = 3 

        &lt;br /&gt;7 % 5 = 2 

        &lt;br /&gt;7 % 6 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;8 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3, 4, 5, 6, 7 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;8 % 2 = 0 
        &lt;br /&gt;8 % 3 = 2 

        &lt;br /&gt;8 % 4 = 0 

        &lt;br /&gt;8 % 5 = 3 

        &lt;br /&gt;8 % 6 = 2 

        &lt;br /&gt;8 % 7 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;9 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3, 4, 5, 6, 7, 8 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;9 % 2 = 1 
        &lt;br /&gt;9 % 3 = 0 

        &lt;br /&gt;9 % 4 = 1 

        &lt;br /&gt;9 % 5 = 4 

        &lt;br /&gt;9 % 6 = 3 

        &lt;br /&gt;9 % 7 = 2 

        &lt;br /&gt;9 % 8 = 1 &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="center"&gt;10 &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;{ 2, 3, 4, 5, 6, 7, 8, 9 } &lt;/td&gt;

      &lt;td valign="middle" align="center"&gt;10 % 2 = 0 
        &lt;br /&gt;10 % 3 = 1 

        &lt;br /&gt;10 % 4 = 2 

        &lt;br /&gt;10 % 5 = 0 

        &lt;br /&gt;10 % 6 = 4 

        &lt;br /&gt;10 % 7 = 3 

        &lt;br /&gt;10 % 8 = 2 

        &lt;br /&gt;10 % 9 = 1 &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;I’ll use the primeNumbers delegate in the next post to evaluate &lt;a href="http://msdn.microsoft.com/en-us/library/dd460688%28VS.100%29.aspx" target="_blank"&gt;PLINQ&lt;/a&gt; (Parallel LINQ) and measure the performance gains when the same calculation is done in parallel instead of in sequence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References 
    &lt;br /&gt;&lt;/strong&gt;&lt;a name="perfetti"&gt;[1]&lt;/a&gt; Perfetti, Michel. &lt;strong&gt;LINQ Quiz: The list of prime numbers in 3 clauses?&lt;/strong&gt; 2007. Available at &amp;lt;&lt;a title="http://blogs.developpeur.org/raptorxp/archive/2007/11/26/quizz-linq-la-liste-des-nombres-premiers-en-3-clauses.aspx" href="http://blogs.developpeur.org/raptorxp/archive/2007/11/26/quizz-linq-la-liste-des-nombres-premiers-en-3-clauses.aspx" target="_blank"&gt;&lt;strong&gt;http://blogs.developpeur.org/raptorxp/archive/2007/11/26/quizz-linq-la-liste-des-nombres-premiers-en-3-clauses.aspx&lt;/strong&gt;&lt;/a&gt;&amp;gt;. Accessed on May 31, 2009.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-6277684004242170700?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ScVWiebmfaClPaQVe_E6VJeQlLQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ScVWiebmfaClPaQVe_E6VJeQlLQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ScVWiebmfaClPaQVe_E6VJeQlLQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ScVWiebmfaClPaQVe_E6VJeQlLQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=00aDCe2y3pM:WK7El-DFDjw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=00aDCe2y3pM:WK7El-DFDjw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=00aDCe2y3pM:WK7El-DFDjw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=00aDCe2y3pM:WK7El-DFDjw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=00aDCe2y3pM:WK7El-DFDjw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=00aDCe2y3pM:WK7El-DFDjw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=00aDCe2y3pM:WK7El-DFDjw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=00aDCe2y3pM:WK7El-DFDjw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=00aDCe2y3pM:WK7El-DFDjw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/00aDCe2y3pM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/6277684004242170700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/05/calculating-prime-numbers-linq-csharp.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6277684004242170700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6277684004242170700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/00aDCe2y3pM/calculating-prime-numbers-linq-csharp.html" title="Calculating prime numbers with LINQ in C#" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/05/calculating-prime-numbers-linq-csharp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QEQn09fip7ImA9WxJQEU0.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-4467567757632460427</id><published>2009-05-23T15:59:00.001-03:00</published><updated>2009-05-23T17:08:23.366-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-23T17:08:23.366-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="logging" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="HQL" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="log4net" /><title>Logging NHibernate SQL with log4net in ASP.NET</title><content type="html">&lt;p&gt;Have you ever wondered how to log the &lt;a href="http://en.wikipedia.org/wiki/SQL" target="_blank"&gt;SQL&lt;/a&gt; generated by &lt;a href="https://www.hibernate.org/343.html" target="_blank"&gt;NHibernate&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;This post tries to exemplify just that.&lt;/p&gt;  &lt;p&gt;NHibernate uses &lt;a href="https://www.hibernate.org/hib_docs/nhibernate/html/queryhql.html" target="_blank"&gt;HQL&lt;/a&gt; to leverage its expressiveness to the developer, but behind the scenes there is an engine that transforms the HQL into pure SQL that is executed against the database. This SQL can be logged so that you can see its structure and get a snapshot of what the database engine receives.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Apache_Log4net" target="_blank"&gt;log4net&lt;/a&gt; is a logging tool that helps the developer see what SQL NHibernate is generating under the covers.&lt;/p&gt;  &lt;p&gt;This is a brief description of log4net taken from its homepage:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;log4net is a tool to help the programmer output log statements to a variety of output targets.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First and foremost you need to enable NHibernate logging in its &lt;a href="http://www.leniel.net/2008/11/nhibernate-query-analyzer-activerecord.html" target="_blank"&gt;configuration file&lt;/a&gt;. The property that sets this is &lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;hibernate.show_sql&lt;/font&gt;&lt;/span&gt;.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;hibernate.show_sql&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The following piece of code shows how to configure an appender and a logger that makes use of the appender. This code is kept inside the Web.config file in the log4net configuration section:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernateRollingFileAppender&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;log4net.Appender.RollingFileAppender&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;file &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;LogNHibernate.txt&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appendToFile &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;rollingStyle &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Size&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;datePattern &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;yyyyMMdd&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;maxSizeRollBackups &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;10&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;maximumFileSize &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;10MB&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;layout &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;log4net.Layout.PatternLayout&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;conversionPattern &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;%date - %message%newline&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;layout&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;logger &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernateLogger&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;additivity&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;level &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;font color="#0000ff"&gt;DEBUG&lt;/font&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;ALL, DEBUG, INFO, WARN, ERROR, FATAL or OFF –&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender-ref &lt;/span&gt;&lt;span style="color: red"&gt;ref&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernateRollingFileAppender&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;logger&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I’ll describe each part of the above code.&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernateRollingFileAppender&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;log4net.Appender.RollingFileAppender&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="2" face="Courier New"&gt;&amp;gt;&lt;/font&gt; &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Appender is an output destination. In this case its a RollingFileAppender. It writes logging events to a file in the file system.&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;file &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;L&lt;span style="color: blue"&gt;ogNHibernate.txt&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="2" face="Courier New"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The file property specifies the name of the file that’ll store the logs.&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appendToFile &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The appendToFile property is set to true so that the appender will overwrite existing files.&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;rollingStyle &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Size&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The rollingStyle property set how to roll log files. In this case the appender will roll log files based on the file size.&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;datePattern &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;yyyyMMdd&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;To change the rolling period we need to set the datePattern property. It would be used if we adopted a rollingStyle based on Date instead of Size.&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;maxSizeRollBackups &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;10&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;/&amp;gt; 
        &lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;maximumFileSize &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;10MB&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="2" face="Courier New"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Up to 10 old files of 10MB each will be kept. These rolled files will be named: LogNHibernate.txt.1, LogNHibernate.txt.2, LogNHibernate.txt.3, etc...&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;layout &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;log4net.Layout.PatternLayout&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;gt; 
        &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;conversionPattern &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;%date - %message%newline&lt;/span&gt;&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;/&amp;gt; 
        &lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;layout&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="2" face="Courier New"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;A layout enables us to customize the output format. This is accomplished by associating a layout with an appender.&lt;/p&gt;

&lt;p&gt;The PatternLayout, lets the user specify the output format according to conversion patterns similar to the C language printf function.&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;logger &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernateLogger&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;additivity&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;This is the logger and its additivity property controls appender accumulation, that is, how the logs are printed in the hierarchy of loggers.&lt;/p&gt;

&lt;p&gt;For example, the output of a log statement of logger NHibernateLogger will go to all the appenders in NHibernateLogger and its ancestors. This is the meaning of the term &amp;quot;appender additivity&amp;quot;.&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;level &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;font color="#0000ff"&gt;DEBUG&lt;/font&gt;&amp;quot;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The level property controls the amount of information you want to be written to the log.&lt;/p&gt;

&lt;p&gt;&lt;span style="color: blue"&gt;&lt;/span&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender-ref &lt;/span&gt;&lt;span style="color: red"&gt;ref&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernateRollingFileAppender&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The property appender-ref specifies what appenders this logger uses.&lt;/p&gt;

&lt;p&gt;That’s it! &lt;strong&gt;:-)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With this basic configuration you can start you search for points where NHibernate is generating to much queries where it shouldn’t.&lt;/p&gt;

&lt;p&gt;I’m currently working on a performance branch where I’m learning how to deal with NHibernate lazy configuration.&lt;/p&gt;

&lt;p&gt;This process of logging the SQL generated by NHibernate plays a great role when one is solving the bottlenecks involved in performance implications.&lt;/p&gt;

&lt;p&gt;Just one note: keep in mind that the process of logging is by itself an onerous one. The amount of data that gets written by NHibernate is expressive and depending on the level of information you set inside the logger, the file size will grow very fast.&lt;/p&gt;

&lt;p&gt;Hope this helps the fellow developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;log4net homepage 
  &lt;br /&gt;&lt;a href="http://logging.apache.org/log4net" target="_blank"&gt;http://logging.apache.org/log4net&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;log4net introduction 
  &lt;br /&gt;&lt;a title="http://logging.apache.org/log4net/release/manual/introduction.html" href="http://logging.apache.org/log4net/release/manual/introduction.html" target="_blank"&gt;http://logging.apache.org/log4net/release/manual/introduction.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;log4net configuration examples 
  &lt;br /&gt;&lt;a title="http://logging.apache.org/log4net/release/config-examples.html" href="http://logging.apache.org/log4net/release/config-examples.html" target="_blank"&gt;http://logging.apache.org/log4net/release/config-examples.html&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-4467567757632460427?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mAIPPoSWTwJ6dUBc4oKIuOjbbrY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mAIPPoSWTwJ6dUBc4oKIuOjbbrY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mAIPPoSWTwJ6dUBc4oKIuOjbbrY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mAIPPoSWTwJ6dUBc4oKIuOjbbrY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=JQCbAdJmOfc:kq0NCnSFvV0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=JQCbAdJmOfc:kq0NCnSFvV0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=JQCbAdJmOfc:kq0NCnSFvV0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=JQCbAdJmOfc:kq0NCnSFvV0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=JQCbAdJmOfc:kq0NCnSFvV0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=JQCbAdJmOfc:kq0NCnSFvV0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=JQCbAdJmOfc:kq0NCnSFvV0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=JQCbAdJmOfc:kq0NCnSFvV0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=JQCbAdJmOfc:kq0NCnSFvV0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/JQCbAdJmOfc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/4467567757632460427/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/05/logging-nhibernate-sql-log4net-aspnet.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/4467567757632460427?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/4467567757632460427?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/JQCbAdJmOfc/logging-nhibernate-sql-log4net-aspnet.html" title="Logging NHibernate SQL with log4net in ASP.NET" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/05/logging-nhibernate-sql-log4net-aspnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQNSHs_fip7ImA9WxJREUo.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-9197944081561845521</id><published>2009-05-11T02:55:00.001-03:00</published><updated>2009-05-12T22:16:39.546-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T22:16:39.546-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NFA" /><category scheme="http://www.blogger.com/atom/ns#" term="parser" /><category scheme="http://www.blogger.com/atom/ns#" term="DFA" /><category scheme="http://www.blogger.com/atom/ns#" term="state transition diagram" /><category scheme="http://www.blogger.com/atom/ns#" term="Finite State Machine" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="Regex" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><title>Regex engine in C# - matching strings</title><content type="html">&lt;p&gt;To close this series of posts, today I’m going to match some input strings using the regex &lt;font face="Courier New"&gt;&lt;strong&gt;(l|e)*n?(i|e)el* &lt;/strong&gt;&lt;/font&gt;&lt;font face="Arial"&gt;that we’ve been using since the beginning.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;To match the strings I’ll make use of the DFA we constructed in the last post titled &lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html" target="_blank"&gt;Regex engine in C# - the DFA&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;These are the 20 strings I’ll be matching:&lt;/p&gt;  &lt;p&gt;eee, eeeil, eel, ennil, ie, leie, lele, leleel, lelel, lelenil, leliel, leniel, llnel, ln, lnel, lniel, nelll, niel, nil and nll.&lt;/p&gt;  &lt;p&gt;In the DFA class we have a method called Simulate which I show bellow:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;Simulate(&lt;span style="color: blue"&gt;string &lt;/span&gt;@in)
{
  &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;currentState = start;

  &lt;span style="color: #2b91af"&gt;CharEnumerator &lt;/span&gt;i = @in.GetEnumerator();

  &lt;span style="color: blue"&gt;while&lt;/span&gt;(i.MoveNext())
  {
    &lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; transition = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;(currentState, i.Current);

    &lt;span style="color: blue"&gt;if&lt;/span&gt;(!transTable.ContainsKey(transition))
      &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Rejected&amp;quot;&lt;/span&gt;;

    currentState = transTable[transition];
  }

  &lt;span style="color: blue"&gt;if&lt;/span&gt;(final.Contains(currentState))
    &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Accepted&amp;quot;&lt;/span&gt;;
  &lt;span style="color: blue"&gt;else
    return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Rejected&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The Simulate method takes as input a string to be matched and returns a string that signalizes success or failing when matching such a string.&lt;/p&gt;

&lt;p&gt;To test it I’ll match the string “leniel” which by the way is my own name. &lt;strong&gt;:-)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, what the Simulate method do?&lt;/p&gt;

&lt;p&gt;It starts by assigning the start state 0 to the variable currentState.&lt;/p&gt;

&lt;p&gt;Next we get a charEnumerator that is used in the &lt;font color="#0000ff" face="Courier New"&gt;while&lt;/font&gt; block to move letter by letter (input symbol by input symbol) till we get to the end of the string.&lt;/p&gt;

&lt;p&gt;We declare a &lt;font face="Courier New"&gt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;&lt;/font&gt; designated transition that has as the key the currentState and as the value the current input symbol we’re simulating.&lt;/p&gt;

&lt;p&gt;We check to see if the DFA’s transition table contains such a transition, that is, if there’s a valid path from that state with that input symbol to another state. If it doesn’t, we reject the string we’re matching, otherwise we make the currentState variable receive the next state, that is, the state appointed by the transition we’ve just checked.&lt;/p&gt;

&lt;p&gt;The process inside the &lt;font color="#0000ff" face="Courier New"&gt;while&lt;/font&gt; block goes on until we reach the last input symbol taken from the string we’re matching, in this case, the last “l” letter.&lt;/p&gt;

&lt;p&gt;After getting out of the &lt;font color="#0000ff" face="Courier New"&gt;while&lt;/font&gt; block we make a final check to see if the state we achieved is part of the DFA’s set of final states. If it is, we accept the string, otherwise, we reject it.&lt;/p&gt;

&lt;p&gt;This is an x-ray from the variables’ value when in the first iteration of the &lt;font color="#0000ff" face="Courier New"&gt;while&lt;/font&gt; block:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Regex Parser Matching the string &amp;quot;leniel&amp;quot;" border="0" alt="Regex Parser Matching the string &amp;quot;leniel&amp;quot;" src="http://lh3.ggpht.com/_W1dLiLjFqdw/Sge9sbL6PgI/AAAAAAAAAiY/TQIxx5hTkhE/RegexParserMatchingLeniel%5B10%5D.png?imgmax=800" width="510" height="509" /&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the transition table, from start state (currentState) “0” with the fist input symbol “l” we can go to state “3”.&lt;/p&gt;

&lt;p&gt;The following table shows the result obtained while testing the strings mentioned above: &lt;/p&gt;

&lt;br /&gt;

&lt;table class="custom2" border="0" cellspacing="0" cellpadding="0" width="75%" align="center"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;th valign="top" align="center"&gt;&lt;strong&gt;Accepted&lt;/strong&gt;&lt;/th&gt;

      &lt;th valign="top" align="center"&gt;&lt;strong&gt;Rejected&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;eee&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;eeeil&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;eel&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;ennil&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;ie&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;lele&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;leie&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;lelel&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;leleel&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;lelenil&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;leliel&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;llnel&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;leniel&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;ln&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;lniel&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;lnel&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;niel&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;nelll&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;nil&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;p align="left"&gt;nll&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;To make sure it’s correct, debug each one of these strings visually looking at the DFA’s graph representation shown below. Starting at state 0 we must end in one of the final states {7, 8, 9, 10}.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DFA for the regex (l|e)*n?(i|e)el*" border="0" alt="DFA for the regex (l|e)*n?(i|e)el*" src="http://lh6.ggpht.com/_W1dLiLjFqdw/Sge9tewxpJI/AAAAAAAAAio/lkfnrzUzLvA/DFARegex%28le%29n%28ie%29el%5B6%5D.png?imgmax=800" width="525" height="626" /&gt; &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Regex Engine executable 
    &lt;br /&gt;&lt;/strong&gt;The Regex Engine presented in this series of posts is a C# Console Application. As such it was written in a way that its command line arguments must be entered in the following form:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;RegularExpressionEngine &amp;quot;(l|e)*n?(i|e)el*&amp;quot; leniel&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;RegularExpressionEngine -&amp;gt;&lt;/font&gt;&amp;#160; the name of the executable .exe file (the program itself)&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&amp;quot;(l|e)*n?(i|e)el*&amp;quot; –&amp;gt;&lt;/font&gt;&lt;font face="Arial"&gt; between the double quotes we pass the regex&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;leniel –&amp;gt;&lt;/font&gt;&lt;font face="Arial"&gt; the string we want to match in the regex&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Using Microsoft Visual Studio C# 2008 we can set the command line arguments using the Debug properties page of the project like the following picture:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Regex Expression Engine Debug Properties Page" border="0" alt="Regex Expression Engine Debug Properties Page" src="http://lh3.ggpht.com/_W1dLiLjFqdw/Sge9uZUiwnI/AAAAAAAAAig/Zhx_cQ1VyZQ/RegexParserDebugPropertiesPage%5B13%5D.png?imgmax=800" width="525" height="185" /&gt; &lt;/p&gt;

&lt;p&gt;To get to the Debug page, right click in the solution inside Solution Explorer as shown in the following picture:&lt;/p&gt;

&lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Regex Expression Engine Solution Properties" border="0" alt="Regex Expression Engine Solution Properties" src="http://lh5.ggpht.com/_W1dLiLjFqdw/Sge9vG75YuI/AAAAAAAAAik/6-UZXm3VRJs/RegexParserSolutionProperties%5B5%5D.png?imgmax=800" width="401" height="405" /&gt; &lt;/p&gt;

&lt;p&gt;After setting the command line arguments, hit F5 and you’re ready to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Regex Engine source code 
    &lt;br /&gt;&lt;/strong&gt;You can get the complete code (Microsoft Visual C# 2008 Console application) and executable at:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://leniel.googlepages.com/RegularExpressionEngine.rar" href="http://leniel.googlepages.com/RegularExpressionEngine.rar"&gt;http://leniel.googlepages.com/RegularExpressionEngine.rar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To try out the code you can use the free Microsoft Visual C# 2008 Express Edition that you can get at: &lt;a href="http://www.microsoft.com/express/vcsharp" target="_blank"&gt;http://www.microsoft.com/express/vcsharp&lt;/a&gt;&lt;/p&gt;

&lt;p align="right"&gt;&lt;em&gt;&lt;strong&gt;Updated on 5/12/2009 10:06:00 PM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I finished writing the posts, here goes the list that points to them:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html" target="_blank"&gt;Regular Expression Engine in C# (the Story)&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;Regex engine in C# - the Regex Parser&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html" target="_blank"&gt;Regex engine in C# - the NFA&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html" target="_blank"&gt;Regex engine in C# - the DFA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References 
    &lt;br /&gt;&lt;/strong&gt;The following links can help you when dealing with regexes:&lt;/p&gt;

&lt;p&gt;Regular-Expressions.info - Regex Tutorial, Examples and Reference - Regex Patterns 
  &lt;br /&gt;&lt;a href="http://www.regular-expressions.info" target="_blank"&gt;http://www.regular-expressions.info&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Regular Expression Library (great site with lots of regexes and an excellent regex tester) 
  &lt;br /&gt;&lt;a href="http://regexlib.com/Default.aspx" target="_blank"&gt;http://regexlib.com/Default.aspx&lt;/a&gt; 

  &lt;br /&gt;&lt;a title="http://regexlib.com/RETester.aspx" href="http://regexlib.com/RETester.aspx" target="_blank"&gt;http://regexlib.com/RETester.aspx&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-9197944081561845521?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/e6xZKK1AfneJSAA9Z19A_p2ILL4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e6xZKK1AfneJSAA9Z19A_p2ILL4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/e6xZKK1AfneJSAA9Z19A_p2ILL4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e6xZKK1AfneJSAA9Z19A_p2ILL4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=wKOiWs240tY:6_0i2ysJB9M:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=wKOiWs240tY:6_0i2ysJB9M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=wKOiWs240tY:6_0i2ysJB9M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=wKOiWs240tY:6_0i2ysJB9M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=wKOiWs240tY:6_0i2ysJB9M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=wKOiWs240tY:6_0i2ysJB9M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=wKOiWs240tY:6_0i2ysJB9M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=wKOiWs240tY:6_0i2ysJB9M:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=wKOiWs240tY:6_0i2ysJB9M:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/wKOiWs240tY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/9197944081561845521/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/9197944081561845521?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/9197944081561845521?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/wKOiWs240tY/regex-engine-in-csharp-match-strings.html" title="Regex engine in C# - matching strings" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAHQnwyfyp7ImA9WxJXE08.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-6504716162188715992</id><published>2009-05-09T18:14:00.001-03:00</published><updated>2009-06-06T19:35:33.297-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-06T19:35:33.297-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows 7" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><title>Testing Windows 7 beta and RC versions</title><content type="html">&lt;p&gt;Windows is the piece of software that underlies everything on my computer so that I thought it would be a great opportunity to write about it since we’re on the verge of its new version, namely, Windows 7.&lt;/p&gt;  &lt;p&gt;I’ve been testing Windows 7 for the last two months. It’s been my operating system since then.&lt;/p&gt;  &lt;p&gt;Firstly I got the &lt;a href="http://en.wikipedia.org/wiki/32-bit" target="_blank"&gt;32-bit&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Beta_version#Beta" target="_blank"&gt;Beta&lt;/a&gt; release on March, 15th and today I’m downloading the &lt;a href="http://en.wikipedia.org/wiki/X86-64" target="_blank"&gt;64-bit&lt;/a&gt;&amp;#160;&lt;a href="http://en.wikipedia.org/wiki/Software_release_life_cycle#Release_candidate" target="_blank"&gt;RC&lt;/a&gt; (release candidate) version. I plan to install it this weekend and as soon as I have it installed and configured I’ll update this post.&lt;/p&gt;  &lt;p&gt;What I have to write about this operating system? Numbered from 1 to 7 in an unordered relevance fashion…&lt;/p&gt;  &lt;p&gt;1 - It is fast.    &lt;br /&gt;2 - I risk to say it is faster than Windows XP.     &lt;br /&gt;3 - It is beautiful! Take a look at the new &lt;a href="http://en.wikipedia.org/wiki/Features_new_to_Windows_7#Taskbar" target="_blank"&gt;taskbar&lt;/a&gt;.     &lt;br /&gt;4 - It simplifies a lot of tasks.     &lt;br /&gt;5 - It has more native programs.     &lt;br /&gt;6 - Previous Windows’s native programs got a refresh and were optimized.     &lt;br /&gt;7 - It adds more security points to your day to day tasks. &lt;/p&gt;  &lt;p&gt;My Windows 7 Beta taskbar:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Windows 7 Beta Taskbar" border="0" alt="Windows 7 Beta Taskbar" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SirqBQ8tOiI/AAAAAAAAAi8/bqCB9oxPZIA/Windows7BetaTaskbar%5B3%5D.jpg?imgmax=800" width="523" height="75" /&gt; &lt;/p&gt;  &lt;p&gt;I moved directly from &lt;a href="http://en.wikipedia.org/wiki/Windows_XP" target="_blank"&gt;Windows XP&lt;/a&gt; to &lt;a href="http://en.wikipedia.org/wiki/Windows_7" target="_blank"&gt;Windows 7&lt;/a&gt;. I didn’t use &lt;a href="http://en.wikipedia.org/wiki/Windows_Vista" target="_blank"&gt;Windows Vista&lt;/a&gt; because it was too &lt;a href="http://en.wikipedia.org/wiki/Software_bloat" target="_blank"&gt;bloated&lt;/a&gt; for my computer in the beginning of 2006 when I also tested it in the beta period. At that time I had an &lt;a href="http://en.wikipedia.org/wiki/List_of_AMD_Athlon_XP_microprocessors" target="_blank"&gt;AMD Athlon XP 2400+&lt;/a&gt; with 512 MB RAM memory and an onboard video card which didn’t allow me to get the so famous &lt;a href="http://en.wikipedia.org/wiki/Windows_Aero" target="_blank"&gt;Aero interface&lt;/a&gt;. I didn’t have a plan to upgrade my hardware. That was the big impediment. I think that Windows Vista arrived in a time in which the majority of computers didn’t have a proper hardware configuration yet.&lt;/p&gt;  &lt;p&gt;Now the landscape is different. Windows 7 appears in a time that it’s much cheaper to buy a 2-core computer with GBs of RAM memory; Computer prices went down during the past years even here in Brazil where hardware prices double if compared with US $. Today $ 1 = R$ 2.07. This price is still attractive. Believe it or not! :)&lt;/p&gt;  &lt;p&gt;The following picture shows my current computer configuration:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows 7 System configuration" border="0" alt="Windows 7 System configuration" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SgX_NbwKA2I/AAAAAAAAAiE/PBrDp_dLsDo/Windows7System%5B14%5D.png?imgmax=800" width="486" height="119" /&gt; &lt;/p&gt;  &lt;p&gt;This is the &lt;a href="http://en.wikipedia.org/wiki/Windows_System_Assessment_Tool" target="_blank"&gt;Windows Experience Index&lt;/a&gt; score I got - a low score given the fact that I still use an onboard video card and that the score is determined by the lowest subscore:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows 7 Windows Experience Index" border="0" alt="Windows 7 Windows Experience Index" src="http://lh4.ggpht.com/_W1dLiLjFqdw/SgX_PH0eN3I/AAAAAAAAAiQ/7zz1WxZegG0/Windows7WEI%5B9%5D.png?imgmax=800" width="505" height="276" /&gt; &lt;/p&gt;  &lt;p&gt;Even with a 3.2 score I have the windows Aero enabled. Take a look at the &lt;a href="http://windowsteamblog.com/blogs/windowsvista/pages/windows-experience-index-an-in-depth-look.aspx" target="_blank"&gt;Windows Experience Index: An In-Depth Look&lt;/a&gt; post that describes the score levels and what system’s features are enabled or disabled based on them.&lt;/p&gt;  &lt;p&gt;From the &lt;a href="http://blogs.msdn.com/e7/archive/2009/01/19/engineering-the-windows-7-windows-experience-index.aspx" target="_blank"&gt;Engineering the Windows 7 “Windows Experience Index”&lt;/a&gt; post we have the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The Vista-era general &lt;/em&gt;&lt;a href="http://windowshelp.microsoft.com/windows/en-us/help/0fee4637-8b21-41f1-87f6-66d2205420d61033.mspx" target="_blank"&gt;guidelines&lt;/a&gt;&lt;em&gt;&lt;/em&gt;&lt;em&gt; for systems in the 1.0, 2.0, 3.0, 4.0 and 5.0 ranges still apply to Windows 7. But, Windows 7 has added levels 6.0 and 7.0; meaning 7.9 is the maximum score possible.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;While using Windows 7 beta I installed all the software I work with as the Microsoft Visual Studio 2008 Professional, Oracle Database, PL/SQL Developer, TortoiseSVN, etc - a typical developer box.&lt;/p&gt;  &lt;p&gt;Windows 7 didn’t crash and was a well behaved operating system during this beta period in which I did everything I used to do in Windows XP.&lt;/p&gt;  &lt;p&gt;The only hardware problem I had was with a Creative Audigy sound card (model number SB0090). There was no driver available for Windows 7. So I had to install a driver that wasn’t full compatible. The sound didn’t sound as good as it should be. I experienced a lot of noise.   &lt;br /&gt;Creative Labs has a &lt;a href="http://support.creative.com/kb/showarticle.aspx?sid=61105" target="_blank"&gt;Windows 7 - Driver Availability Chart&lt;/a&gt; in case you’re interested.&lt;/p&gt;  &lt;p&gt;All in all you’ll get a great experience with such a robust operating system. After all Windows is ubiquitous and the more you can do with it the better you get at work.&lt;/p&gt;  &lt;p align="right"&gt;&lt;em&gt;&lt;strong&gt;Updated on 6/6/2009 05:48:00 PM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p align="left"&gt;I’ve installed Windows 7 64-bit version but I didn’t use it because for the sake of my work I thought Win 7 wouldn’t play as expected.&lt;/p&gt;  &lt;p align="left"&gt;Firstly we should consider that Windows 7 64-bit has a default Program Files (x86) folder where it puts all applications that are made to run on a 32-bit operating system. This particularly broke my way because the software that I develop rely on an Oracle database connection. There is a known bug with Oracle that prevents an application hosted in a folder that has parenthesis in its name to access an Oracle database.&lt;/p&gt;  &lt;p align="left"&gt;I didn’t notice any performance gains while running the 64-bit OS.&lt;/p&gt;  &lt;p align="left"&gt;Today I finally installed the Windows 7 RC 32-bit. I upgraded from the 32-bit Beta version to the RC version. The upgrade is only possible from 32-bit to 32-bit versions and not from a 64-bit Beta to 32-bit RC and vice versa.&lt;/p&gt;  &lt;p align="left"&gt;The upgrade took 1 hour and 40 minutes to complete and ran flawlessly. You may ask why this took so long? This is because in a upgrade it is necessary to copy a lot of files from the old OS to the new one.&lt;/p&gt;  &lt;p align="left"&gt;I downloaded the ISO file and extracted its content to a temp folder. I changed the file cversion.ini as described in the post &lt;a href="http://blogs.msdn.com/e7/archive/2009/04/07/delivering-a-quality-upgrade-experience.aspx" target="_blank"&gt;Delivering a quality upgrade experience&lt;/a&gt; from the Engineering Windows 7 blog so that I could go through the upgrade. I then clicked setup.exe while running the Windows 7 beta version and the installation started.&lt;/p&gt;  &lt;p align="left"&gt;I got the following report:&lt;/p&gt;  &lt;p&gt;Upgrading Windows will affect the following devices and/or programs: &lt;/p&gt;  &lt;ul&gt;&lt;/ul&gt;  &lt;ul&gt;&lt;/ul&gt;  &lt;ul&gt;   &lt;ul&gt;&lt;/ul&gt; &lt;/ul&gt;  &lt;ul&gt;These programs might not work properly after the upgrade. We recommend uninstalling these programs before upgrading. Cancel the upgrade, open Control Panel, and search for &amp;quot;uninstall a program&amp;quot;. (Note: Programs marked as * can be safely reinstalled after the upgrade.) &lt;/ul&gt;  &lt;ul&gt;   &lt;ul&gt;     &lt;li&gt;Microsoft SQL Server 2008 &lt;/li&gt;      &lt;li&gt;Microsoft SQL Server 2005&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;I then decided to ignore the report and proceeded with the installation.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Windows 7 - Upgrading from 32-bit Beta to RC" border="0" alt="Windows 7 - Upgrading from 32-bit Beta to RC" src="http://lh3.ggpht.com/_W1dLiLjFqdw/SirqCHpMMeI/AAAAAAAAAjA/5eFsJLa3fmI/Windows7UpgradingFrom32BitBetaToRC%5B3%5D.jpg?imgmax=800" width="524" height="393" /&gt; &lt;/p&gt;  &lt;p&gt;The above image shows the early stages of the upgrade. In fact there were more than 400000 files to be gathered. I already had an extensive list of apps installed on the beta OS as for example Microsoft Office 2007 that in itself is a big suite of apps.&lt;/p&gt;  &lt;p&gt;Windows 7 then restarted sometimes and installed the new OS bits that were refined from Beta to RC. The last step was to transfer files, settings and programs to the new OS. It transferred a total of 524490 files.&lt;/p&gt;  &lt;p&gt;My Windows 7 RC taskbar:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Windows 7 RC Taskbar" border="0" alt="Windows 7 RC Taskbar" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SirqC3Lj1CI/AAAAAAAAAjE/kukvXm0uTbc/Windows7RCTaskbar%5B6%5D.jpg?imgmax=800" width="525" height="75" /&gt; &lt;/p&gt;  &lt;p&gt;From this what I have to say now that I’m using the RC to write this blog post using &lt;a href="http://windowslivewriter.spaces.live.com/" target="_blank"&gt;Windows Live Writer&lt;/a&gt; is that the upgrade was successful. I didn’t need to reinstall anything (including &lt;a href="http://download.live.com/writer" target="_blank"&gt;Windows Live Writer&lt;/a&gt;). Everything is the way they were before installing the RC version.&lt;/p&gt;  &lt;p&gt;I had a pleasant experience while upgrading from Beta to RC.&lt;/p&gt;  &lt;p&gt;Congratulations to the Microsoft Windows 7 Team for providing this must have feature, that is, making upgrades possible! &lt;strong&gt;:-)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A last note: I described above the problem I had while configuring my Creative Audigy sound card in Windows 7 Beta. With the RC version the Creative Audigy soundcard is functioning as expected. One of the first things Windows 7 did was to install the sound card driver!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;References     &lt;br /&gt;&lt;/strong&gt;Engineering Windows 7 blog    &lt;br /&gt;&lt;a title="http://blogs.msdn.com/e7" href="http://blogs.msdn.com/e7" target="_blank"&gt;http://blogs.msdn.com/e7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Windows 7 Team blog    &lt;br /&gt;&lt;a title="http://windowsteamblog.com/blogs/windows7" href="http://windowsteamblog.com/blogs/windows7" target="_blank"&gt;http://windowsteamblog.com/blogs/windows7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Microsoft official Windows 7 site    &lt;br /&gt;&lt;a title="http://www.microsoft.com/windows/windows-7/default.aspx" href="http://www.microsoft.com/windows/windows-7/default.aspx" target="_blank"&gt;http://www.microsoft.com/windows/windows-7/default.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Windows 7 @ Paul Thurrott's SuperSite for Windows    &lt;br /&gt;&lt;a href="http://www.winsupersite.com/win7" target="_blank"&gt;http://www.winsupersite.com/win7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Windows 7 article at Wikipedia    &lt;br /&gt;&lt;a title="http://en.wikipedia.org/wiki/Windows_7" href="http://en.wikipedia.org/wiki/Windows_7" target="_blank"&gt;http://en.wikipedia.org/wiki/Windows_7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;List of features new to Windows 7    &lt;br /&gt;&lt;a title="http://en.wikipedia.org/wiki/Features_new_to_Windows_7" href="http://en.wikipedia.org/wiki/Features_new_to_Windows_7" target="_blank"&gt;http://en.wikipedia.org/wiki/Features_new_to_Windows_7&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-6504716162188715992?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/H-w1jcPmkXUZLaF-lOib2UCWEsA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H-w1jcPmkXUZLaF-lOib2UCWEsA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/H-w1jcPmkXUZLaF-lOib2UCWEsA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H-w1jcPmkXUZLaF-lOib2UCWEsA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=4q8jE1-k-qg:o7nxvPnIKyA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=4q8jE1-k-qg:o7nxvPnIKyA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=4q8jE1-k-qg:o7nxvPnIKyA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=4q8jE1-k-qg:o7nxvPnIKyA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=4q8jE1-k-qg:o7nxvPnIKyA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=4q8jE1-k-qg:o7nxvPnIKyA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=4q8jE1-k-qg:o7nxvPnIKyA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=4q8jE1-k-qg:o7nxvPnIKyA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=4q8jE1-k-qg:o7nxvPnIKyA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/4q8jE1-k-qg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/6504716162188715992/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/05/testing-windows-7-beta-and-rc-versions.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6504716162188715992?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6504716162188715992?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/4q8jE1-k-qg/testing-windows-7-beta-and-rc-versions.html" title="Testing Windows 7 beta and RC versions" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.leniel.net/2009/05/testing-windows-7-beta-and-rc-versions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUMRHY-cCp7ImA9WxJREUo.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-8778848638614019215</id><published>2009-05-03T03:21:00.001-03:00</published><updated>2009-05-12T22:14:45.858-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T22:14:45.858-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DFA" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Regex" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><title>Regex engine in C# - the DFA</title><content type="html">&lt;p&gt;This time, we’ll take a look at the DFA’s class and its helper class called SubsetMachine.&lt;/p&gt;  &lt;p&gt;To understand what’s a DFA, refer to the first post in this series called &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;Regex engine in C# - the Regex Parser&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;In the &lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html" target="_blank"&gt;Regex engine in C# - the NFA&lt;/a&gt; post we ended with an NFA.&lt;/p&gt;  &lt;p&gt;Now we’re going to build a DFA based on such NFA.&lt;/p&gt;  &lt;p&gt;Remember that the main difference between a DFA and an NFA is that a DFA doesn’t have epsilon (ε) transitions that represent &amp;quot;nothing&amp;quot; or &amp;quot;no input&amp;quot; between states.&lt;/p&gt;  &lt;p&gt;As described in the section &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html#dfaxnfa" target="_blank"&gt;DFA versus NFA&lt;/a&gt; in the introduction of this series of posts, it may be shown that a DFA is equivalent to an NFA, in that, for any given NFA, one may construct an equivalent DFA, and vice-versa: this is the &lt;a href="http://en.wikipedia.org/wiki/Powerset_construction" target="_blank"&gt;powerset construction or subset construction&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;So, let’s get our hands dirty with some code.&lt;/p&gt;  &lt;p&gt;Below I present the DFA class:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;//
//  Regular Expression Engine C# Sample Application
//  2006, by Leniel Braz de Oliveira Macaferi &amp;amp; Wellington Magalhães Leite.
//
//  UBM's Computer Engineering - 7th term [http://www.ubm.br/]
//  
//  This program sample was developed and turned in as a term paper for Lab. of
//  Compilers Construction. It was based on the source code provided by Eli Bendersky
//  [http://eli.thegreenplace.net/] and is provided &amp;quot;as is&amp;quot; without warranty.
//

&lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;SCG = System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;C5;

&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;;
&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Char&lt;/span&gt;;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;RegularExpressionEngine
{
  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Implements a deterministic finite automata (DFA)
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DFA
  &lt;/span&gt;{
    &lt;span style="color: green"&gt;// Start state
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;start;
    &lt;span style="color: green"&gt;// Set of final states
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; final;
    &lt;span style="color: green"&gt;// Transition table
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;SCG.&lt;span style="color: #2b91af"&gt;SortedList&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; transTable;

    &lt;span style="color: blue"&gt;public &lt;/span&gt;DFA()
    {
      final = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;();

      transTable = &lt;span style="color: blue"&gt;new &lt;/span&gt;SCG.&lt;span style="color: #2b91af"&gt;SortedList&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Comparer&lt;/span&gt;());
    }

    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Simulate(&lt;span style="color: blue"&gt;string &lt;/span&gt;@in)
    {
      &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;curState = start;

      &lt;span style="color: #2b91af"&gt;CharEnumerator &lt;/span&gt;i = @in.GetEnumerator();

      &lt;span style="color: blue"&gt;while&lt;/span&gt;(i.MoveNext())
      {
        &lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; transition = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;(curState, i.Current);

        &lt;span style="color: blue"&gt;if&lt;/span&gt;(!transTable.ContainsKey(transition))
          &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Rejected&amp;quot;&lt;/span&gt;;

        curState = transTable[transition];
      }

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(final.Contains(curState))
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Accepted&amp;quot;&lt;/span&gt;;
      &lt;span style="color: blue"&gt;else
        return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Rejected&amp;quot;&lt;/span&gt;;
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;Show()
    {
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;DFA start state: {0}\n&amp;quot;&lt;/span&gt;, start);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;DFA final state(s): &amp;quot;&lt;/span&gt;);

      SCG.&lt;span style="color: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; iE = final.GetEnumerator();

      &lt;span style="color: blue"&gt;while&lt;/span&gt;(iE.MoveNext())
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(iE.Current + &lt;span style="color: #a31515"&gt;&amp;quot; &amp;quot;&lt;/span&gt;);

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n\n&amp;quot;&lt;/span&gt;);

      &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(SCG.&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; kvp &lt;span style="color: blue"&gt;in &lt;/span&gt;transTable)
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;Trans[{0}, {1}] = {2}\n&amp;quot;&lt;/span&gt;, kvp.Key.Key, kvp.Key.Value, kvp.Value);
    }
  }

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Implements a comparer that suits the transTable SordedList
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Comparer &lt;/span&gt;: SCG.&lt;span style="color: #2b91af"&gt;IComparer&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;&amp;gt;
  {
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;Compare(&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; transition1, &lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; transition2)
    {
      &lt;span style="color: blue"&gt;if&lt;/span&gt;(transition1.Key == transition2.Key)
        &lt;span style="color: blue"&gt;return &lt;/span&gt;transition1.Value.CompareTo(transition2.Value);
      &lt;span style="color: blue"&gt;else
        return &lt;/span&gt;transition1.Key.CompareTo(transition2.Key);
    }
  }

}&lt;/pre&gt;

&lt;p&gt;As you see, a DFA has 3 variables: a start state, a set of final states and a transition table that maps transitions between states.&lt;/p&gt;

&lt;p&gt;Below I present the SubsetMachine class that is responsible for the hard work of extracting an equivalent DFA from a given NFA:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//
//  Regular Expression Engine C# Sample Application
//  2006, by Leniel Braz de Oliveira Macaferi &amp;amp; Wellington Magalhães Leite.
//
//  UBM's Computer Engineering - 7th term [http://www.ubm.br/]
//  
//  This program sample was developed and turned in as a term paper for Lab. of
//  Compilers Construction. It was based on the source code provided by Eli Bendersky
//  [http://eli.thegreenplace.net/] and is provided &amp;quot;as is&amp;quot; without warranty.
//

&lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;SCG = System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;C5;

&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;;
&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Char&lt;/span&gt;;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;RegularExpressionEngine
{
  &lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SubsetMachine
  &lt;/span&gt;{
    &lt;span style="color: blue"&gt;private static int &lt;/span&gt;num = 0;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Subset machine that employs the powerset construction or subset construction algorithm.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;It creates a DFA that recognizes the same language as the given NFA.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DFA &lt;/span&gt;SubsetConstruct(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa)
    {
      &lt;span style="color: #2b91af"&gt;DFA &lt;/span&gt;dfa = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DFA&lt;/span&gt;();

      &lt;span style="color: green"&gt;// Sets of NFA states which is represented by some DFA state
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt; markedStates = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt;();
      &lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt; unmarkedStates = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt;();

      &lt;span style="color: green"&gt;// Gives a number to each state in the DFA
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HashDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; dfaStateNum = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HashDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;();

      &lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; nfaInitial = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;();
      nfaInitial.Add(nfa.initial);

      &lt;span style="color: green"&gt;// Initially, EpsilonClosure(nfa.initial) is the only state in the DFAs states and it's unmarked.
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; first = EpsilonClosure(nfa, nfaInitial);
      unmarkedStates.Add(first);

      &lt;span style="color: green"&gt;// The initial dfa state
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;dfaInitial = GenNewState();
      dfaStateNum[first] = dfaInitial;
      dfa.start = dfaInitial;

      &lt;span style="color: blue"&gt;while&lt;/span&gt;(unmarkedStates.Count != 0)
      {
        &lt;span style="color: green"&gt;// Takes out one unmarked state and posteriorly mark it.
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; aState = unmarkedStates.Choose();

        &lt;span style="color: green"&gt;// Removes from the unmarked set.
        &lt;/span&gt;unmarkedStates.Remove(aState);

        &lt;span style="color: green"&gt;// Inserts into the marked set.
        &lt;/span&gt;markedStates.Add(aState);

        &lt;span style="color: green"&gt;// If this state contains the NFA's final state, add it to the DFA's set of
        // final states.
        &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(aState.Contains(nfa.final))
          dfa.final.Add(dfaStateNum[aState]);

        SCG.&lt;span style="color: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; iE = nfa.inputs.GetEnumerator();

        &lt;span style="color: green"&gt;// For each input symbol the nfa knows...
        &lt;/span&gt;&lt;span style="color: blue"&gt;while&lt;/span&gt;(iE.MoveNext())
        {
          &lt;span style="color: green"&gt;// Next state
          &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; next = EpsilonClosure(nfa, nfa.Move(aState, iE.Current));

          &lt;span style="color: green"&gt;// If we haven't examined this state before, add it to the unmarkedStates and make up a new number for it.
          &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(!unmarkedStates.Contains(next) &amp;amp;&amp;amp; !markedStates.Contains(next))
          {
            unmarkedStates.Add(next);
            dfaStateNum.Add(next, GenNewState());
          }

          &lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; transition = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;();&lt;br /&gt;          transition.Key = dfaStateNum[aState];
          transition.Value = iE.Current;

          dfa.transTable[transition] = dfaStateNum[next];
        }
      }

      &lt;span style="color: blue"&gt;return &lt;/span&gt;dfa;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Builds the Epsilon closure of states for the given NFA 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;nfa&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;states&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; EpsilonClosure(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa, &lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; states)
    {
      &lt;span style="color: green"&gt;// Push all states onto a stack
      &lt;/span&gt;SCG.&lt;span style="color: #2b91af"&gt;Stack&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; uncheckedStack = &lt;span style="color: blue"&gt;new &lt;/span&gt;SCG.&lt;span style="color: #2b91af"&gt;Stack&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;(states);

      &lt;span style="color: green"&gt;// Initialize EpsilonClosure(states) to states
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; epsilonClosure = states;

      &lt;span style="color: blue"&gt;while&lt;/span&gt;(uncheckedStack.Count != 0)
      {
        &lt;span style="color: green"&gt;// Pop state t, the top element, off the stack
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;t = uncheckedStack.Pop();

        &lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0;

        &lt;span style="color: green"&gt;// For each state u with an edge from t to u labeled Epsilon
        &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;input &lt;span style="color: blue"&gt;in &lt;/span&gt;nfa.transTable[t])
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(input == (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;NFA&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon)
          {
            &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;u = &lt;span style="color: #2b91af"&gt;Array&lt;/span&gt;.IndexOf(nfa.transTable[t], input, i);

            &lt;span style="color: green"&gt;// If u is not already in epsilonClosure, add it and push it onto stack
            &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(!epsilonClosure.Contains(u))
            {
              epsilonClosure.Add(u);
              uncheckedStack.Push(u);
            }
          }

          i = i + 1;
        }
      }

      &lt;span style="color: blue"&gt;return &lt;/span&gt;epsilonClosure;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Creates unique state numbers for DFA states
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;GenNewState()
    {
      &lt;span style="color: blue"&gt;return &lt;/span&gt;num++;
    }

  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;first post&lt;/a&gt; of this series we see the following line of code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;DFA &lt;/span&gt;dfa = &lt;span style="color: #2b91af"&gt;SubsetMachine&lt;/span&gt;.SubsetConstruct(nfa);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The SubsetConstruct method from the SubsetMachine class receives as input an NFA and returns a DFA.&lt;/p&gt;

&lt;p&gt;Inside the SubsetConstruct method we firstly instantiate a new DFA object and then we create two variables markedStates and unmarkedStates that are sets of NFA states which represent a DFA state.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Sets of NFA states which is represented by some DFA state
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt; markedStates = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt;();
&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt; unmarkedStates = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;From this we see that a DFA state can represent a set of NFA states. Take a look at the introductory post and see &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html#figure2" target="_blank"&gt;Figure 2&lt;/a&gt;. It shows two DFA states that represent sets of NFA states, in this particular case the DFA final states represent the NFA states {s2, s3} and {s5, s6}.&lt;/p&gt;

&lt;p&gt;The HashDictionary helps us to give a name (to number) each DFA state.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Gives a number to each state in the DFA
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;HashDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; dfaStateNum = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HashDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;We declare a variable called nfaInitial that is a set of states. It receives the initial NFA state:&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; nfaInitial = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;();
nfaInitial.Add(nfa.initial);&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;We’ll start using the EpsilonClosure function.&lt;/font&gt; &lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Initially, EpsilonClosure(nfa.initial) is the only state in the DFAs states and it's unmarked.
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; first = EpsilonClosure(nfa, nfaInitial);&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;The EpsilonClosure function receives as parameters the NFA and its initial state and returns a set of states. Take a look at the method signature:&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; EpsilonClosure(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa, &lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; states)&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;So, what does it do? You may ask. To answer this question let’s debug this first method call:&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;From the NFA transition table presented in &lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html#nfatranstable" target="_blank"&gt;Figure 2&lt;/a&gt; and from the transition graph presented in &lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html#nfagraph" target="_blank"&gt;Figure 3&lt;/a&gt; in the second post of this series we can see how many transitions are represented by eps transitions.&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;The first time we enter into this function we’ll get as a return value a set of states that contains all the states that are reachable with an eps transition from the start state 0.&lt;/font&gt;&lt;/pre&gt;

&lt;div align="center"&gt;
  &lt;pre class="code"&gt;&lt;a name="figure1"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="EpsilonClosureFunction" border="0" alt="EpsilonClosureFunction" src="http://lh5.ggpht.com/_W1dLiLjFqdw/Sf033a8mfRI/AAAAAAAAAgQ/tHzu98LfW3w/EpsilonClosureFunction6.png?imgmax=800" width="497" height="64" /&gt;&lt;/a&gt;&lt;/pre&gt;

  &lt;pre class="code"&gt;&lt;font face="Arial"&gt;Figure 1 - States reachable by an eps transition from start state 0.&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;For the sake of comparison I’ll show the NFA’s graph representation for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt; that we’re studying since the beginning of this series.&lt;/p&gt;
&lt;a name="figure2"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NFA for the Regex (l|e)*n?(i|e)el*" border="0" alt="NFA for the Regex (l|e)*n?(i|e)el*" src="http://lh3.ggpht.com/_W1dLiLjFqdw/Sf034KXNCVI/AAAAAAAAAgU/JS9PpHjsRGw/NFARegexlenieel11.png?imgmax=800" width="565" height="455" /&gt;&lt;/a&gt; 

&lt;p align="center"&gt;Figure 2 - NFA’s graph representation for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="left"&gt;If you pay close attention you’ll see that the order the regex parser found the states is the order we visually debug the code looking at the graph above.&lt;/p&gt;

&lt;p align="left"&gt;With such states found we move next adding this DFA state into the variable unmarkedStates.&lt;/p&gt;

&lt;p align="left"&gt;We then use a function called GetNewState that is responsible for generating a number that uniquely identifies each state of the DFA:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// The initial dfa state
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;dfaInitial = GenNewState();&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;When we pass to the next line of code we add to the dfaStateNum dictionary a key that is the set of states returned by the EpsilonClosure function and a value that is the name of the initial state of the DFA.&lt;/p&gt;

&lt;pre class="code"&gt;dfaStateNum[first] = dfaInitial;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;We make the initial state of the DFA be the dfaInitial value we just got.&amp;#160; &lt;pre class="code"&gt;dfa.start = dfaInitial;&lt;/pre&gt;

&lt;p&gt;Next we enter in the first &lt;font color="#0000ff" face="Courier New"&gt;while&lt;/font&gt; keyword. In this &lt;font color="#0000ff" face="Courier New"&gt;while&lt;/font&gt; we basically extract one of the unmarkedStates and add the same to the markedStates set. This has the meaning of telling that we already checked such state.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Takes out one unmarked state and posteriorly mark it.
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; aState = unmarkedStates.Choose();

&lt;span style="color: green"&gt;// Removes from the unmarked set.
&lt;/span&gt;unmarkedStates.Remove(aState);

&lt;span style="color: green"&gt;// Inserts into the marked set.
&lt;/span&gt;markedStates.Add(aState);&lt;/pre&gt;

&lt;p&gt;In the next line of code (one of the most interesting parts of the whole code) we check to see if this current DFA state (remember that it is a set of states) we’re on contains the NFA final state, if it holds true, we add it to the DFA’s set of final states:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// If this state contains the NFA's final state, add it to the DFA's set of final states.
&lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(aState.Contains(nfa.final))
  dfa.final.Add(dfaStateNum[aState]);&lt;/pre&gt;

&lt;p&gt;Now it’s time to check against the NFA’s input symbols. To accomplish this we declare an &lt;a href="http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx" target="_blank"&gt;enumerator&lt;/a&gt; of type &lt;font color="#408080" face="Courier New"&gt;state &lt;/font&gt;that does the job of moving through each of the input symbols in the next &lt;font color="#0000ff" face="Courier New"&gt;while &lt;/font&gt;code block:&lt;/p&gt;

&lt;pre class="code"&gt;SCG.&lt;span style="color: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; iE = nfa.inputs.GetEnumerator();

&lt;span style="color: green"&gt;// For each input symbol the nfa knows...
&lt;/span&gt;&lt;span style="color: blue"&gt;while&lt;/span&gt;(iE.MoveNext())
{ . . .&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Arial"&gt;Now it’s time to create the next DFA state. We do this by declaring a new set of states and we call the EpsilonClosure function again to fill this state, but this time we pass the EpsilonClosure function a different second parameter.&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Next state
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; next = EpsilonClosure(nfa, nfa.Move(aState, iE.Current));&lt;/pre&gt;

&lt;p&gt;Let’s go deeper to take a look at this second parameter.&lt;/p&gt;

&lt;p&gt;As you see we call the function Move that is part of the NFA class. This function receives as parameters a set of states and an input symbol to be checked against. It returns a set of states.&lt;/p&gt;

&lt;p&gt;What the move function does is: &lt;font color="#0000ff" face="Courier New"&gt;foreach&lt;/font&gt; state in the set of states passed as the first parameter we check each transition present in the NFA’s transition table from this state to another state with the input symbol passed as the second parameter.&lt;/p&gt;

&lt;p&gt;So, the first time we pass we get the following output from the Move function:&lt;/p&gt;

&lt;p align="left"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="NFAMoveFunction" border="0" alt="NFAMoveFunction" src="http://lh3.ggpht.com/_W1dLiLjFqdw/Sf034SZclbI/AAAAAAAAAgo/WD2ZhvNGwqQ/NFAMoveFunction%5B3%5D.png?imgmax=800" width="333" height="62" /&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p align="center"&gt;Figure 3 - Result from the NFA’s Move function the 1st time it’s called&lt;/p&gt;

&lt;p align="left"&gt;If we look at &lt;a href="#figure2"&gt;Figure 2&lt;/a&gt;&amp;#160; we can assert that from the states present in the first state of the DFA (see &lt;a href="#figure1"&gt;Figure 1&lt;/a&gt;) we can move to states {5, 16} with the first NFA input that is equal to ‘e’.&lt;/p&gt;

&lt;p&gt;With the above result taken from the Move function we’re ready to go the EpsilonClosure function for the second time to create the 2nd DFA state in the SubsetMachine class. This second time we get the following result from EpsilonClosure function:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="EpsilonClosureFunction2" border="0" alt="EpsilonClosureFunction2" src="http://lh5.ggpht.com/_W1dLiLjFqdw/Sf0345xcjNI/AAAAAAAAAgc/POXpsBm5cMc/EpsilonClosureFunction25.png?imgmax=800" width="576" height="67" /&gt;&lt;/p&gt;

&lt;p align="center"&gt;Figure 4 - Result from the EpsilonClosure function the 2nd time it’s called&lt;/p&gt;

&lt;p&gt;Now, if you pay close attention, we can assert that starting at the states {5, 16} we can move with an eps-transition to the states shown above. Remember that the states we pass to the EpsilonClosure function are themselves included in the result returned by the function.&lt;/p&gt;

&lt;p&gt;Now that we have created the 2nd DFA state we check to see if it wasn’t examined yet and if it holds true we add it to the unmarkedStates variable and give a new name to this state numbering it with the GenNewState function.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// If we haven't examined this state before, add it to the unmarkedStates and make up a new number for it.
&lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(!unmarkedStates.Contains(next) &amp;amp;&amp;amp; !markedStates.Contains(next))
{
  unmarkedStates.Add(next);
  dfaStateNum.Add(next, GenNewState());
}&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Now the best part of it. :)&lt;/p&gt;

&lt;p&gt;We create a new transition that has as key the number of the DFA state we’re checking and as the value the current input symbol we’re after.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; transition = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;();&lt;br /&gt;transition.Key = dfaStateNum[aState];
transition.Value = iE.Current;&lt;/pre&gt;

&lt;p&gt;We then add this transition to the DFA’s transition table:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DFATransitionTable" border="0" alt="DFATransitionTable" src="http://lh4.ggpht.com/_W1dLiLjFqdw/Sf035f6B-iI/AAAAAAAAAgg/N0XnRkJp-4Y/DFATransitionTable5.png?imgmax=800" width="542" height="82" /&gt;&lt;/p&gt;

&lt;p align="center"&gt;Figure 5 - DFA’s transition table &lt;/p&gt;

&lt;p&gt;This has the following meaning: from state 0 with input ‘e’ go to state 1!&lt;/p&gt;

&lt;p&gt;These are the subsequent values we get for the first unmarkedState we’re checking:&lt;/p&gt;

&lt;p&gt;With input ‘i’ we can go to state { 14 } from which with an eps transition we can go to state { 17 }.&lt;/p&gt;

&lt;p&gt;With input ‘l’ we can go to state { 3 } from which with an eps transition we can go to states { 4, 13, 8, 3, 12, 7, 2, 11, 6, 1, 15, 10 }.&lt;/p&gt;

&lt;p&gt;With input ‘n’ we can go to state { 9 } from which with an eps transition we can go to states { 12, 9, 13, 15 }.&lt;/p&gt;

&lt;p&gt;A point that deserves consideration is that each time you run the regex parser it’s not guaranteed that the numbers that identify the DFA states will remain the same.&lt;/p&gt;

&lt;p&gt;I won’t continue debugging because it would consume a lot of space in this blog post.&lt;/p&gt;

&lt;p&gt;I think that with the above explanation it’s easy to get the point.&lt;/p&gt;

&lt;p&gt;In short we’ll repeat the above steps for each unmarked state that hasn’t been checked yet working with it against each input symbol.&lt;/p&gt;

&lt;p&gt;For the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt; in one of the times I ran the code, I got the following DFA’s transition table:&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="75%" align="center"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td align="center"&gt;
        &lt;p&gt;&lt;font face="Courier New"&gt;DFA start state: 0 
            &lt;br /&gt;DFA final state(s): 7 8 9 10&lt;/font&gt;&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[0, e] = 1&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[0, i] = 2&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[0, l] = 3&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[0, n] = 4&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[1, e] = 7&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[1, i] = 2&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[1, l] = 3&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[1, n] = 4&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[2, e] = 8&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[2, i] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[2, l] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[2, n] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[3, e] = 1&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[3, i] = 2&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[3, l] = 3&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[3, n] = 4&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[4, e] = 5&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[4, i] = 2&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[4, l] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[4, n] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[5, e] = 8&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[5, i] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[5, l] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[5, n] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[6, e] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;&lt;font face="Courier New"&gt;Trans[6, i] = 6&lt;/font&gt;&lt;/font&gt; &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[6, l] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[6, n] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[7, e] = 7&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[7, i] = 2&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[7, l] = 10&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[7, n] = 4&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[8, e] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[8, i] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[8, l] = 9&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[8, n] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[9, e] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[9, i] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[9, l] = 9&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[9, n] = 6&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[10, e] = 1&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[&lt;font face="Courier New"&gt;10&lt;/font&gt;, i] = 2&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[&lt;font face="Courier New"&gt;10&lt;/font&gt;, l] = 10&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Trans[&lt;font face="Courier New"&gt;10&lt;/font&gt;, n] = 4&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p align="center"&gt;Figure 6 - DFA’s transition table for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Below is the DFA’s graph representation:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="DFA for the Regex (l|e)*n?(i|e)el*" border="0" alt="DFA for the Regex (l|e)*n?(i|e)el*" src="http://lh3.ggpht.com/_W1dLiLjFqdw/Sf036d48qxI/AAAAAAAAAgk/-kILff4ORCg/DFARegex%28le%29n%28ie%29el%5B10%5D.png?imgmax=800" width="538" height="641" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p align="center"&gt;Figure 7 - DFA’s graph representation for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="left"&gt;In the next &lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html" target="_blank"&gt;post&lt;/a&gt; I’ll simulate some input strings against this DFA to assert its validity.&lt;/p&gt;

&lt;p align="left"&gt;See you there!&lt;/p&gt;

&lt;p align="right"&gt;&lt;em&gt;&lt;strong&gt;Updated on 5/12/2009 09:57:00 PM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I finished writing the posts, here goes the list that points to them: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html" target="_blank"&gt;Regular Expression Engine in C# (the Story)&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;Regex engine in C# - the Regex Parser&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html" target="_blank"&gt;Regex engine in C# - the NFA&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html" target="_blank"&gt;Regex engine in C# - matching strings&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-8778848638614019215?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lAx75lc5t33yd8zE8ZOMzDBwV0Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lAx75lc5t33yd8zE8ZOMzDBwV0Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lAx75lc5t33yd8zE8ZOMzDBwV0Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lAx75lc5t33yd8zE8ZOMzDBwV0Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=YyTNewSh00U:8k71x_mhD2k:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=YyTNewSh00U:8k71x_mhD2k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=YyTNewSh00U:8k71x_mhD2k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=YyTNewSh00U:8k71x_mhD2k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=YyTNewSh00U:8k71x_mhD2k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=YyTNewSh00U:8k71x_mhD2k:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=YyTNewSh00U:8k71x_mhD2k:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=YyTNewSh00U:8k71x_mhD2k:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=YyTNewSh00U:8k71x_mhD2k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/YyTNewSh00U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/8778848638614019215/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/8778848638614019215?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/8778848638614019215?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/YyTNewSh00U/regex-engine-in-csharp-dfa.html" title="Regex engine in C# - the DFA" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMDQ34zfSp7ImA9WxJREUo.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-5297242213630927506</id><published>2009-04-13T01:04:00.002-03:00</published><updated>2009-05-12T22:01:12.085-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T22:01:12.085-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NFA" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Regex" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><title>Regex engine in C# - the NFA</title><content type="html">&lt;p&gt;As promised, let’s dive into the NFA’s class. To understand what’s an NFA, refer to the first post in this series called &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;Regex engine in C# - the Regex Parser&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Last time we ended with the main Regex Engine class (RegexParser) which delegates to the NFA class the logic for constructing the NFA based on the parse tree we got on the last &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The following is the NFA class:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;//
//  Regular Expression Engine C# Sample Application
//  2006, by Leniel Braz de Oliveira Macaferi &amp;amp; Wellington Magalhães Leite.
//
//  UBM's Computer Engineering - 7th term [http://www.ubm.br/]
//  
//  This program sample was developed and turned in as a term paper for Lab. of
//  Compilers Construction. It was based on the source code provided by Eli Bendersky
//  [http://eli.thegreenplace.net/] and is provided &amp;quot;as is&amp;quot; without warranty.
//
//  It makes use of C5 collections library (see reference at the end of this post.)
//

&lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;SCG = System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;C5;

&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;;
&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Char&lt;/span&gt;;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;RegularExpressionEngine
{

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Implements a non-deterministic finite automata
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA
  &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;initial;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;final;
    &lt;span style="color: blue"&gt;private int &lt;/span&gt;size;
    &lt;span style="color: green"&gt;// Inputs this NFA responds to
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SortedArray&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; inputs;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[][] transTable;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Provides default values for epsilon and none
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public enum &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Constants
    &lt;/span&gt;{
      Epsilon = &lt;span style="color: #a31515"&gt;'ε'&lt;/span&gt;,
      None = &lt;span style="color: #a31515"&gt;'\0'
    &lt;/span&gt;}

    &lt;span style="color: blue"&gt;public &lt;/span&gt;NFA(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa)
    {
      initial = nfa.initial;
      final = nfa.final;
      size = nfa.size;
      inputs = nfa.inputs;
      transTable = nfa.transTable;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Constructed with the NFA size (amount of states), the initial state and the
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;final state
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;size_&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Amount of states.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;initial_&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Initial state.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;final_&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Final state.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;NFA(&lt;span style="color: blue"&gt;int &lt;/span&gt;size_, &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;initial_, &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;final_)
    {
      initial = initial_;
      final = final_;
      size = size_;

      IsLegalState(initial);
      IsLegalState(final);

      inputs = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SortedArray&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt;();

      &lt;span style="color: green"&gt;// Initializes transTable with an &amp;quot;empty graph&amp;quot;, no transitions between its
      // states
      &lt;/span&gt;transTable = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[size][];

      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; size; ++i)
        transTable[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[size];
    }

    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsLegalState(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;s)
    {
      &lt;span style="color: green"&gt;// We have 'size' states, numbered 0 to size-1
      &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(s &amp;lt; 0 || s &amp;gt;= size)
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;

      &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Adds a transition between two states.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;from&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;to&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;in&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;AddTrans(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;from, &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;to, &lt;span style="color: #2b91af"&gt;input &lt;/span&gt;@in)
    {
      IsLegalState(from);
      IsLegalState(to);

      transTable[from][to] = @in;

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(@in != (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon)
        inputs.Add(@in);
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Fills states 0 up to other.size with other's states.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;other&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;FillStates(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;other)
    {
      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;i = 0; i &amp;lt; other.size; ++i)
        &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;j = 0; j &amp;lt; other.size; ++j)
          transTable[i][j] = other.transTable[i][j];

      SCG.&lt;span style="color: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;&amp;gt; cE = other.inputs.GetEnumerator();

      &lt;span style="color: blue"&gt;while&lt;/span&gt;(cE.MoveNext())
        inputs.Add(cE.Current);
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Renames all the NFA's states. For each nfa state: number += shift.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Functionally, this doesn't affect the NFA, it only makes it larger and renames
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;its states.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;shift&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;ShiftStates(&lt;span style="color: blue"&gt;int &lt;/span&gt;shift)
    {
      &lt;span style="color: blue"&gt;int &lt;/span&gt;newSize = size + shift;

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(shift &amp;lt; 1)
        &lt;span style="color: blue"&gt;return&lt;/span&gt;;

      &lt;span style="color: green"&gt;// Creates a new, empty transition table (of the new size).
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[][] newTransTable = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[newSize][];

      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; newSize; ++i)
        newTransTable[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[newSize];

      &lt;span style="color: green"&gt;// Copies all the transitions to the new table, at their new locations.
      &lt;/span&gt;&lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;i = 0; i &amp;lt; size; ++i)
        &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;j = 0; j &amp;lt; size; ++j)
          newTransTable[i + shift][j + shift] = transTable[i][j];

      &lt;span style="color: green"&gt;// Updates the NFA members.
      &lt;/span&gt;size = newSize;
      initial += shift;
      final += shift;
      transTable = newTransTable;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Appends a new, empty state to the NFA.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;AppendEmptyState()
    {
      transTable = Resize(transTable, size + 1);

      size += 1;
    }

    &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[][] Resize(&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[][] transTable, &lt;span style="color: blue"&gt;int &lt;/span&gt;newSize)
    {
      &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[][] newTransTable = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[newSize][];

      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; newSize; ++i)
        newTransTable[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;[newSize];

      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt;= transTable.Length - 1; i++)
        &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt;= transTable[i].Length - 1; j++)
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(transTable[i][j] != &lt;span style="color: #a31515"&gt;'\0'&lt;/span&gt;)
            newTransTable[i][j] = transTable[i][j];
        }

      &lt;span style="color: blue"&gt;return &lt;/span&gt;newTransTable;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Returns a set of NFA states from which there is a transition on input symbol
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;inp from some state s in states.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;states&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;inp&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; Move(&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; states, &lt;span style="color: #2b91af"&gt;input &lt;/span&gt;inp)
    {
      &lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt; result = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Set&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;state&lt;/span&gt;&amp;gt;();

      &lt;span style="color: green"&gt;// For each state in the set of states
      &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;state &lt;span style="color: blue"&gt;in &lt;/span&gt;states)
      {
        &lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0;

        &lt;span style="color: green"&gt;// For each transition from this state
        &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;input &lt;span style="color: blue"&gt;in &lt;/span&gt;transTable[state])
        {
          &lt;span style="color: green"&gt;// If the transition is on input inp, add it to the resulting set
          &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(input == inp)
          {
            &lt;span style="color: #2b91af"&gt;state &lt;/span&gt;u = &lt;span style="color: #2b91af"&gt;Array&lt;/span&gt;.IndexOf(transTable[state], input, i);
            result.Add(u);
          }

          i = i + 1;
        }
      }

      &lt;span style="color: blue"&gt;return &lt;/span&gt;result;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Prints out the NFA.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;Show()
    {
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;This NFA has {0} states: 0 - {1}&amp;quot;&lt;/span&gt;, size, size - 1);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;The initial state is {0}&amp;quot;&lt;/span&gt;, initial);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;The final state is {0}\n&amp;quot;&lt;/span&gt;, final);

      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;from = 0; from &amp;lt; size; ++from)
      {
        &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;state &lt;/span&gt;to = 0; to &amp;lt; size; ++to)
        {
          &lt;span style="color: #2b91af"&gt;input &lt;/span&gt;@in = transTable[from][to];

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(@in != (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.None)
          {
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;Transition from {0} to {1} on input &amp;quot;&lt;/span&gt;, from, to);

            &lt;span style="color: blue"&gt;if&lt;/span&gt;(@in == (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon)
              &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;Epsilon\n&amp;quot;&lt;/span&gt;);
            &lt;span style="color: blue"&gt;else
              &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;{0}\n&amp;quot;&lt;/span&gt;, @in);
          }
        }
      }
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n\n&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;tree&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;TreeToNFA(&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;tree)
    {
        &lt;span style="color: blue"&gt;switch &lt;/span&gt;(tree.type)
        {
            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Chr:
                &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFABasic(tree.data.Value);
            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Alter:
                &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAAlter(TreeToNFA(tree.left), TreeToNFA(tree.right));
            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Concat:
                &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAConcat(TreeToNFA(tree.left), TreeToNFA(tree.right));
            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Star:
                &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAStar(TreeToNFA(tree.left));
            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Question:
                &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAAlter(TreeToNFA(tree.left), BuildNFABasic((&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon));
            &lt;span style="color: blue"&gt;default&lt;/span&gt;:
                &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
        }
    }

    &lt;span style="color: green"&gt;/////////////////////////////////////////////////////////////////
    //
    // NFA building functions
    //
    // Using Thompson Construction, build NFAs from basic inputs or 
    // compositions of other NFAs.
    //

    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Builds a basic, single input NFA
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;in&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;BuildNFABasic(&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;@in)
    {
      &lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;basic = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA&lt;/span&gt;(2, 0, 1);

      basic.AddTrans(0, 1, @in);

      &lt;span style="color: blue"&gt;return &lt;/span&gt;basic;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Builds an alternation of nfa1 and nfa2 (nfa1|nfa2)
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;nfa1&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;nfa2&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;BuildNFAAlter(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa1, &lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa2)
    {
      &lt;span style="color: green"&gt;// How this is done: the new nfa must contain all the states in
      // nfa1 and nfa2, plus a new initial and final states. 
      // First will come the new initial state, then nfa1's states, then
      // nfa2's states, then the new final state

      // make room for the new initial state
      &lt;/span&gt;nfa1.ShiftStates(1);

      &lt;span style="color: green"&gt;// make room for nfa1
      &lt;/span&gt;nfa2.ShiftStates(nfa1.size);

      &lt;span style="color: green"&gt;// create a new nfa and initialize it with (the shifted) nfa2
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;newNFA = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA&lt;/span&gt;(nfa2);

      &lt;span style="color: green"&gt;// nfa1's states take their places in new_nfa
      &lt;/span&gt;newNFA.FillStates(nfa1);

      &lt;span style="color: green"&gt;// Set new initial state and the transitions from it
      &lt;/span&gt;newNFA.AddTrans(0, nfa1.initial, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);
      newNFA.AddTrans(0, nfa2.initial, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);

      newNFA.initial = 0;

      &lt;span style="color: green"&gt;// Make up space for the new final state
      &lt;/span&gt;newNFA.AppendEmptyState();

      &lt;span style="color: green"&gt;// Set new final state
      &lt;/span&gt;newNFA.final = newNFA.size - 1;

      newNFA.AddTrans(nfa1.final, newNFA.final, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);
      newNFA.AddTrans(nfa2.final, newNFA.final, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);

      &lt;span style="color: blue"&gt;return &lt;/span&gt;newNFA;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Builds an alternation of nfa1 and nfa2 (nfa1|nfa2)
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;nfa1&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;nfa2&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;BuildNFAConcat(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa1, &lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa2)
    {
      &lt;span style="color: green"&gt;// How this is done: First will come nfa1, then nfa2 (its initial state replaced
      // with nfa1's final state)
      &lt;/span&gt;nfa2.ShiftStates(nfa1.size - 1);

      &lt;span style="color: green"&gt;// Creates a new NFA and initialize it with (the shifted) nfa2
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;newNFA = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA&lt;/span&gt;(nfa2);

      &lt;span style="color: green"&gt;// nfa1's states take their places in newNFA
      // note: nfa1's final state overwrites nfa2's initial state,
      // thus we get the desired merge automatically (the transition
      // from nfa2's initial state now transits from nfa1's final state)
      &lt;/span&gt;newNFA.FillStates(nfa1);

      &lt;span style="color: green"&gt;// Sets the new initial state (the final state stays nfa2's final state,
      // and was already copied)
      &lt;/span&gt;newNFA.initial = nfa1.initial;

      &lt;span style="color: blue"&gt;return &lt;/span&gt;newNFA;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Builds a star (kleene closure) of nfa (nfa*)
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;How this is done: First will come the new initial state, then NFA, then the&lt;/span&gt;&lt;span style="color: gray"&gt; &lt;/span&gt;&lt;span style="color: green"&gt;new final state
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;nfa&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;BuildNFAStar(&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa)
    {
      &lt;span style="color: green"&gt;// Makes room for the new initial state
      &lt;/span&gt;nfa.ShiftStates(1);

      &lt;span style="color: green"&gt;// Makes room for the new final state
      &lt;/span&gt;nfa.AppendEmptyState();

      &lt;span style="color: green"&gt;// Adds new transitions
      &lt;/span&gt;nfa.AddTrans(nfa.final, nfa.initial, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);
      nfa.AddTrans(0, nfa.initial, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);
      nfa.AddTrans(nfa.final, nfa.size - 1, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);
      nfa.AddTrans(0, nfa.size - 1, (&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon);

      nfa.initial = 0;
      nfa.final = nfa.size - 1;

      &lt;span style="color: blue"&gt;return &lt;/span&gt;nfa;
    }
  }

}&lt;/pre&gt;

&lt;p&gt;We pass the parse tree (see &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;last post&lt;/a&gt;) to a function responsible for converting the parse tree to an NFA.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;TreeToNFA(&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;tree)
{
  &lt;span style="color: blue"&gt;switch&lt;/span&gt;(tree.type)
  {
    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Chr:
      &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFABasic(tree.data.Value);
    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Alter:
      &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAAlter(TreeToNFA(tree.left), TreeToNFA(tree.right));
    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Concat:
      &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAConcat(TreeToNFA(tree.left), TreeToNFA(tree.right));
    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Star:
      &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAStar(TreeToNFA(tree.left));
    &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Question:
      &lt;span style="color: blue"&gt;return &lt;/span&gt;BuildNFAAlter(TreeToNFA(tree.left), BuildNFABasic((&lt;span style="color: blue"&gt;char&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Epsilon));
    &lt;span style="color: blue"&gt;default&lt;/span&gt;:
      &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The &lt;font face="Courier New"&gt;TreeToNFA&lt;/font&gt; function delegates to the building functions that employ Thompson Construction to build the NFA from basic inputs or compositions of other NFAs.&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;TreeToNFA&lt;/font&gt; is recursive! It calls itself, that is, the calls are put into the &lt;a href="http://en.wikipedia.org/wiki/Stack_%28data_structure%29" target="_blank"&gt;stack&lt;/a&gt;. Debug the code to see how it works.&lt;/p&gt;

&lt;p&gt;The building functions are well documented. Take a look at the comments in the code above.&lt;/p&gt;

&lt;p&gt;While debugging the code we get the following variables’ structure:&lt;/p&gt;

&lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="NFADebugging" border="0" alt="NFADebugging" src="http://lh6.ggpht.com/_W1dLiLjFqdw/Sfy-rK3NRJI/AAAAAAAAAgE/CmMsveE5NV0/NFADebugging%5B1%5D.png?imgmax=800" width="544" height="495" /&gt;&amp;#160; &lt;br /&gt;Figure 1 - Variables' structure while in debugging mode&lt;/p&gt;

&lt;p&gt;From the above picture we see that there’s a transition from state 8 to state 9 with the input symbol ‘n’.&lt;/p&gt;

&lt;p&gt;The NFA’s &lt;font face="Courier New"&gt;Show&lt;/font&gt; function will only output something if the transition’s value present in the&lt;font face="Courier New"&gt; transTable&lt;/font&gt; variable is different from 0 ‘\0’, that is, if there’s indeed a transition from one state to another.&lt;/p&gt;

&lt;p&gt;So, for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt; we get the following transition table:&lt;/p&gt;

&lt;br /&gt;&lt;a name="nfatranstable"&gt;
  &lt;table border="0" cellspacing="0" cellpadding="2" width="75%" align="center"&gt;&lt;tbody&gt;
      &lt;tr&gt;
        &lt;td align="center"&gt;&lt;font face="Courier New"&gt;This NFA has 22 states: 0 - 21 
            &lt;br /&gt;The initial state is 0 

            &lt;br /&gt;The final state is 21&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 0 to 1&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 0 to 7&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 1 to 2&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 1 to 4&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 2 to 3&amp;#160;&amp;#160; on input l&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 3 to 6&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 4 to 5&amp;#160;&amp;#160; on input e&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 5 to 6&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 6 to 1&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 6 to 7&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 7 to 8&amp;#160;&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 7 to 10&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 8 to 9&amp;#160;&amp;#160; on input n&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 9 to 12&amp;#160; on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 10 to 11 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 11 to 12 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 12 to 13 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 12 to 15 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 13 to 14 on input i&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 14 to 17 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 15 to 16 on input e&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 16 to 17 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 17 to 18 on input e&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 18 to 19 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 18 to 21 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 19 to 20 on input l&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 20 to 19 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="middle" align="left"&gt;&lt;font face="Courier New"&gt;Transition from 20 to 21 on input Epsilon&lt;/font&gt; &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
&lt;/a&gt;

&lt;br /&gt;&lt;center&gt;Figure 2 - NFA’s transition table for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt;&lt;/center&gt;

&lt;p align="left"&gt;This is the NFA’s graph representation: 
  &lt;br /&gt;&lt;/p&gt;
&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NFA for the Regex (l|e)*n?(i|e)el*" border="0" alt="NFA for the Regex (l|e)*n?(i|e)el*" src="http://lh6.ggpht.com/_W1dLiLjFqdw/Sf0AFpIaZWI/AAAAAAAAAgM/O4QsaWwkctg/NFARegex%28le%29n%28ie%29el%5B5%5D.png?imgmax=800" width="565" height="455" /&gt; 

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p align="center"&gt;Figure 3 - NFA’s graph representation for the regex &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you see, some states have an eps-transition – eps or epsilon (ε) that represents &amp;quot;nothing&amp;quot; or &amp;quot;no input&amp;quot;. This is absolutely valid in an NFA.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html" target="_blank"&gt;Next time&lt;/a&gt; we’ll dive into the DFA class that uses a subset machine to construct a DFA based on an NFA.&lt;/p&gt;

&lt;p&gt;See you there!&lt;/p&gt;

&lt;p align="right"&gt;&lt;em&gt;&lt;strong&gt;Updated on 5/12/2009 09:54:00 PM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I finished writing the posts, here goes the list that points to them:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html" target="_blank"&gt;Regular Expression Engine in C# (the Story)&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;Regex engine in C# - the Regex Parser&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html" target="_blank"&gt;Regex engine in C# - the DFA&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html" target="_blank"&gt;Regex engine in C# - matching strings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; 

  &lt;br /&gt;[1] Kokholm, Niels; Sestoft, Peter. &lt;strong&gt;The C5 Generic Collection Library for C# and CLI&lt;/strong&gt;. Available at &amp;lt;&lt;a title="http://www.itu.dk/research/c5/" href="http://www.itu.dk/research/c5/"&gt;http://www.itu.dk/research/c5/&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on May 2, 2008.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-5297242213630927506?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zskbW5UGAfXOkR3N7Za2ATv5V3s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zskbW5UGAfXOkR3N7Za2ATv5V3s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zskbW5UGAfXOkR3N7Za2ATv5V3s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zskbW5UGAfXOkR3N7Za2ATv5V3s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/leniel?a=zzfFB9b4aqU:HoApXKq7tV0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=zzfFB9b4aqU:HoApXKq7tV0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=zzfFB9b4aqU:HoApXKq7tV0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=zzfFB9b4aqU:HoApXKq7tV0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=zzfFB9b4aqU:HoApXKq7tV0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=zzfFB9b4aqU:HoApXKq7tV0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?i=zzfFB9b4aqU:HoApXKq7tV0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=zzfFB9b4aqU:HoApXKq7tV0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/leniel?a=zzfFB9b4aqU:HoApXKq7tV0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/leniel?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/zzfFB9b4aqU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/5297242213630927506/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/5297242213630927506?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/5297242213630927506?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/zzfFB9b4aqU/regex-engine-in-csharp-nfa.html" title="Regex engine in C# - the NFA" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcGQXo4fSp7ImA9WxJREUo.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-6019914016319882899</id><published>2009-02-24T21:25:00.001-03:00</published><updated>2009-05-12T21:53:40.435-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T21:53:40.435-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NFA" /><category scheme="http://www.blogger.com/atom/ns#" term="parser" /><category scheme="http://www.blogger.com/atom/ns#" term="DFA" /><category scheme="http://www.blogger.com/atom/ns#" term="Finite State Machine" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Regex" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><title>Regex engine in C# - the Regex Parser</title><content type="html">&lt;p&gt;I really like to study &lt;a href="http://en.wikipedia.org/wiki/Theory_of_computation" target="_blank"&gt;theory of computation&lt;/a&gt;. This series of posts show how much I like it! :)&lt;/p&gt;  &lt;p&gt;Following the open post titled &lt;a href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html" target="_blank"&gt;Regular Expression Engine in C# (the Story)&lt;/a&gt;, let’s begin this endeavor with the definition of the words most used from now on:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;State      &lt;br /&gt;&lt;/strong&gt;A &lt;a href="http://en.wikipedia.org/wiki/State_%28computer_science%29" target="_blank"&gt;state&lt;/a&gt; is a unique configuration of information in a program or machine.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Finite State Machine (FSM)&lt;/strong&gt;     &lt;br /&gt;A &lt;a href="http://en.wikipedia.org/wiki/Finite_state_machine"&gt;finite state machine&lt;/a&gt; is a model of behavior composed of a finite number of states, transitions between those states, and actions. It’s an abstract model of a machine with a primitive internal memory.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Nondeterministic Finite Automaton (NFA)&lt;/b&gt;     &lt;br /&gt;A &lt;a href="http://en.wikipedia.org/wiki/Nondeterministic_finite_state_machine"&gt;nondeterministic finite automaton&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;is a finite state machine where for each pair of state and input symbol there may be several possible next states.&lt;/p&gt;  &lt;p&gt;Its mathematical model is as follow:    &lt;br /&gt;1. A set of states (S)     &lt;br /&gt;2. A set of &lt;a href="http://en.wikipedia.org/wiki/Input_symbol" target="_blank"&gt;input symbols&lt;/a&gt; - the input symbol alphabet (Σ)     &lt;br /&gt;3. A transition function that maps state-symbol pairs to a given state &lt;i&gt;T&lt;/i&gt; : &lt;i&gt;S&lt;/i&gt; × Σ → &lt;i&gt;P&lt;/i&gt;(&lt;i&gt;S&lt;/i&gt;)     &lt;br /&gt;4. A state s0 that is the start state &lt;em&gt;s&lt;/em&gt;&lt;sub&gt;0&lt;/sub&gt; ∈ &lt;em&gt;S&lt;/em&gt;     &lt;br /&gt;5. A set of states that are the final states &lt;i&gt;F&lt;/i&gt; ⊆ &lt;i&gt;S&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;The following example explains a NFA &lt;i&gt;M&lt;/i&gt;, with a 2 letters alphabet.&lt;/p&gt;  &lt;p&gt;Let &lt;i&gt;M&lt;/i&gt; = (&lt;i&gt;Q&lt;/i&gt;, Σ, &lt;i&gt;T&lt;/i&gt;, &lt;i&gt;s&lt;sub&gt;0&lt;/sub&gt;&lt;/i&gt;, &lt;i&gt;F&lt;/i&gt;) where:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Σ = { a, b } &lt;/li&gt;    &lt;li&gt;&lt;i&gt;Q&lt;/i&gt; = { &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;0&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;3&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;4&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;5&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;6&lt;/sub&gt;, &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;7 &lt;/sub&gt;} &lt;/li&gt;    &lt;li&gt;E({ &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;0 &lt;/sub&gt;}) = { s&lt;sub&gt;0&lt;/sub&gt;, s&lt;sub&gt;1&lt;/sub&gt;, s&lt;sub&gt;4&lt;/sub&gt; } &lt;/li&gt;    &lt;li&gt;&lt;i&gt;F&lt;/i&gt; = { &lt;i&gt;s&lt;/i&gt;&lt;sub&gt;7 &lt;/sub&gt;} &lt;/li&gt;    &lt;li&gt;The transition function &lt;i&gt;T&lt;/i&gt; can be defined by this &lt;a href="http://en.wikipedia.org/wiki/State_transition_table" target="_blank"&gt;state transition table&lt;/a&gt;: &lt;/li&gt; &lt;/ul&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="401" align="center"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;a&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;b&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;ε&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s0&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{s1, s4}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s1&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{s2}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s2&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{s2, s3}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{s2}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s3&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{} &lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{s7}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s4&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{s5}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s5&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{s5}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{s5, s6}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s6&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{s7}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;s7&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="100" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99" align="center"&gt;&lt;font face="Courier New"&gt;{}&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p align="left"&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Nondeterministic Finite Automaton (NFA)" border="0" alt="Nondeterministic Finite Automaton (NFA)" src="http://lh6.ggpht.com/_W1dLiLjFqdw/SaTJLtvDBfI/AAAAAAAAAfU/7ZULjntgraY/NFA%5B11%5D.png?imgmax=800" width="502" height="300" /&gt;   &lt;p&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 1 - NFA example with 8 states&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;b&gt;Deterministic Finite Automaton (DFA)&lt;/b&gt;       &lt;br /&gt;&lt;/strong&gt;A &lt;a href="http://en.wikipedia.org/wiki/Deterministic_finite_state_machine" target="_blank"&gt;deterministic finite automaton&lt;/a&gt; is a finite state machine where for each pair of state and input symbol there is one and only one transition to a next state.&lt;/p&gt;  &lt;p&gt;Its mathematical model is as follow:    &lt;br /&gt;1. A finite set of states (S)     &lt;br /&gt;2. A finite set called the alphabet (Σ)     &lt;br /&gt;3. A transition function (δ : S × Σ → S)     &lt;br /&gt;4. A start state (s0 ∈ S)     &lt;br /&gt;5. A set of accept final states (F ⊆ S)     &lt;br /&gt;6. No state has an eps-transition – eps or epsilon (ε) represents &amp;quot;nothing&amp;quot; or &amp;quot;no input&amp;quot;.     &lt;br /&gt;7. For each state S and input x, there is at most one edge labeled x leaving S.&lt;/p&gt;  &lt;p align="center"&gt;&lt;a name="figure2"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Deterministic Finite Automaton (DFA) " border="0" alt="Deterministic Finite Automaton (DFA) " src="http://lh4.ggpht.com/_W1dLiLjFqdw/SaTyDjutnkI/AAAAAAAAAfg/uHNiznam_BI/DFA5%5B1%5D.png?imgmax=800" width="389" height="374" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 2 - DFA equivalent to the NFA shown in Figure 1&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a name="dfaxnfa"&gt;DFA versus NFA&lt;/a&gt;&lt;/strong&gt;     &lt;br /&gt;Despite the fact that the DFA and NFA have distinct definitions, it may be shown in the formal theory that they are equivalent, in that, for any given NFA, one may construct an equivalent DFA, and vice-versa: this is the &lt;a href="http://en.wikipedia.org/wiki/Powerset_construction" target="_blank"&gt;powerset construction&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Both types of automata recognize only &lt;a href="http://en.wikipedia.org/wiki/Regular_languages" target="_blank"&gt;regular languages&lt;/a&gt;.&lt;/p&gt;  &lt;p align="center"&gt;&lt;em&gt;&lt;strong&gt;DFA + NFA = FSM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Regular Expression (regex)&lt;/strong&gt;     &lt;br /&gt;A &lt;a href="http://en.wikipedia.org/wiki/Regular_expression" target="_blank"&gt;regular expression&lt;/a&gt; provide a concise and flexible means for identifying strings of text of interest, such as particular characters, words, or patterns of characters. Regular expressions are written in a &lt;a href="http://en.wikipedia.org/wiki/Formal_language" target="_blank"&gt;formal language&lt;/a&gt; that can be interpreted by a &lt;font color="#ff0000"&gt;&lt;strong&gt;regular expression processor (engine)&lt;/strong&gt;&lt;/font&gt;, a program that either serves as a &lt;a href="http://en.wikipedia.org/wiki/Parser" target="_blank"&gt;parser&lt;/a&gt; generator or examines text and identifies parts that match the provided pattern (regex).&lt;/p&gt;  &lt;p&gt;A regex (any regex!) can be represented as a FSM.&lt;/p&gt;  &lt;p&gt;Some symbols you’ll encounter in regexes and their meanings:&lt;/p&gt; &lt;dl&gt;&lt;dt&gt;Alternation &lt;/dt&gt;&lt;dd&gt;A vertical bar separates alternatives. For example, &lt;code&gt;gray|grey&lt;/code&gt; can match &amp;quot;&lt;i&gt;gray&lt;/i&gt;&amp;quot; or &amp;quot;&lt;i&gt;grey&lt;/i&gt;&amp;quot;.&lt;/dd&gt;&lt;dt&gt;Grouping &lt;/dt&gt;&lt;dd&gt;Parentheses are used to define the scope and precedence of the operators (among other uses). For example, &lt;code&gt;gray|grey&lt;/code&gt; and &lt;code&gt;gr(a|e)y&lt;/code&gt; are equivalent patterns which both describe the set of &amp;quot;&lt;i&gt;gray&lt;/i&gt;&amp;quot; and &amp;quot;&lt;i&gt;grey&lt;/i&gt;&amp;quot;. &lt;/dd&gt;&lt;dt&gt;Quantification &lt;/dt&gt;&lt;dd&gt;A quantifier after a token (such as a character) or group specifies how often that preceding element is allowed to occur. The most common quantifiers are the question mark &lt;code&gt;?&lt;/code&gt;, the asterisk &lt;code&gt;*&lt;/code&gt; and the plus sign &lt;code&gt;+&lt;/code&gt;. &lt;/dd&gt;&lt;/dl&gt;&lt;dl&gt;&lt;dd&gt;     &lt;p&gt;&lt;code&gt;&lt;b&gt;? =&lt;/b&gt;&lt;/code&gt;&amp;#160;&lt;i&gt;zero or one&lt;/i&gt; of the preceding element.         &lt;br /&gt;Example: &lt;code&gt;colou?r&lt;/code&gt; matches both &amp;quot;&lt;i&gt;color&lt;/i&gt;&amp;quot; and &amp;quot;&lt;i&gt;colour&lt;/i&gt;&amp;quot;.&lt;/p&gt;      &lt;p&gt;&lt;code&gt;&lt;b&gt;* = &lt;/b&gt;&lt;/code&gt;&lt;i&gt;zero or more&lt;/i&gt; of the preceding element.         &lt;br /&gt;Example: &lt;code&gt;ab*c&lt;/code&gt; matches &amp;quot;&lt;i&gt;ac&lt;/i&gt;&amp;quot;, &amp;quot;&lt;i&gt;abc&lt;/i&gt;&amp;quot;, &amp;quot;&lt;i&gt;abbc&lt;/i&gt;&amp;quot;, &amp;quot;&lt;i&gt;abbbc&lt;/i&gt;&amp;quot;, and so on.&lt;/p&gt;      &lt;p&gt;&lt;code&gt;&lt;b&gt;+ = &lt;/b&gt;&lt;/code&gt;&lt;i&gt;one or more&lt;/i&gt; of the preceding element.         &lt;br /&gt;Example: &lt;code&gt;ab+c&lt;/code&gt; matches &amp;quot;&lt;i&gt;abc&lt;/i&gt;&amp;quot;, &amp;quot;&lt;i&gt;abbc&lt;/i&gt;&amp;quot;, &amp;quot;&lt;i&gt;abbbc&lt;/i&gt;&amp;quot;, and so on, but not &amp;quot;&lt;i&gt;ac&lt;/i&gt;&amp;quot;.&lt;/p&gt;   &lt;/dd&gt;&lt;/dl&gt;  &lt;p&gt;After reading this we should be able to answer the following question:&lt;/p&gt;  &lt;p&gt;What is the regular expression that describes the machine &lt;i&gt;M&lt;/i&gt; shown in Figure 1 above?&lt;/p&gt;  &lt;p&gt;The language of &lt;i&gt;M&lt;/i&gt; can be described by the regular language given by this regular expression: &lt;font face="Courier New"&gt;(a|b)(a|b)*(a|b)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Regex Parser      &lt;br /&gt;&lt;/strong&gt;Let me show you some code.&lt;/p&gt;  &lt;p&gt;As I’ve written in &lt;a href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html" target="_blank"&gt;Regular Expression Engine in C# (the Story)&lt;/a&gt;, I’ll present the code in a top-down approach, that is, from the higher level class to its dependencies.&lt;/p&gt;  &lt;p&gt;The RegexParser class:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;//
//    Regular Expression Engine C# Sample Application
//    2006, by Leniel Braz de Oliveira Macaferi &amp;amp; Wellington Magalhães Leite.
//
//  UBM's Computer Engineering - 7th term [http://www.ubm.br/]
//  
//  This program sample was developed and turned in as a term paper for Lab. of
//  Compilers Construction. It was based on the source code provided by Eli Bendersky
//  [http://eli.thegreenplace.net/] and is provided &amp;quot;as is&amp;quot; without warranty.
//

&lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Text;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;RegularExpressionEngine
{
  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Implements a parser for a given regular expression.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RegexParser
  &lt;/span&gt;{
    &lt;span style="color: blue"&gt;private string &lt;/span&gt;data;
    &lt;span style="color: blue"&gt;private int &lt;/span&gt;next;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;data&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;Init(&lt;span style="color: blue"&gt;string &lt;/span&gt;data)
    {
      &lt;span style="color: blue"&gt;this&lt;/span&gt;.data = Preprocess(data);
      next = 0;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private char &lt;/span&gt;Peek()
    {
      &lt;span style="color: blue"&gt;return &lt;/span&gt;(next &amp;lt; data.Length) ? data[next] : &lt;span style="color: #a31515"&gt;'\0'&lt;/span&gt;;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private char &lt;/span&gt;Pop()
    {
      &lt;span style="color: blue"&gt;char &lt;/span&gt;cur = Peek();

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(next &amp;lt; data.Length)
        ++next;

      &lt;span style="color: blue"&gt;return &lt;/span&gt;cur;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private int &lt;/span&gt;GetPos()
    {
      &lt;span style="color: blue"&gt;return &lt;/span&gt;next;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Generates concatenation chars ('.') where appropriate.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;in&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;Preprocess(&lt;span style="color: blue"&gt;string &lt;/span&gt;@in)
    {
      &lt;span style="color: #2b91af"&gt;StringBuilder &lt;/span&gt;@out = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();

      &lt;span style="color: #2b91af"&gt;CharEnumerator &lt;/span&gt;c, up;
      c = @in.GetEnumerator();
      up = @in.GetEnumerator();

      up.MoveNext();

      &lt;span style="color: green"&gt;// In this loop c is the current char of in, up is the next one.
      &lt;/span&gt;&lt;span style="color: blue"&gt;while&lt;/span&gt;(up.MoveNext())
      {
        c.MoveNext();

        @out.Append(c.Current);

        &lt;span style="color: blue"&gt;if&lt;/span&gt;((&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsLetterOrDigit(c.Current) || c.Current == &lt;span style="color: #a31515"&gt;')' &lt;/span&gt;|| c.Current == &lt;span style="color: #a31515"&gt;'*' &lt;/span&gt;||
          c.Current == &lt;span style="color: #a31515"&gt;'?'&lt;/span&gt;) &amp;amp;&amp;amp; (up.Current != &lt;span style="color: #a31515"&gt;')' &lt;/span&gt;&amp;amp;&amp;amp; up.Current != &lt;span style="color: #a31515"&gt;'|' &lt;/span&gt;&amp;amp;&amp;amp;
          up.Current != &lt;span style="color: #a31515"&gt;'*' &lt;/span&gt;&amp;amp;&amp;amp; up.Current != &lt;span style="color: #a31515"&gt;'?'&lt;/span&gt;))
          @out.Append(&lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;);
      }

      &lt;span style="color: green"&gt;// Don't forget the last char...
      &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(c.MoveNext())
        @out.Append(c.Current);

      &lt;span style="color: blue"&gt;return &lt;/span&gt;@out.ToString();
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;node&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;offset&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private static void &lt;/span&gt;PrintTree(&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;node, &lt;span style="color: blue"&gt;int &lt;/span&gt;offset)
    {
      &lt;span style="color: blue"&gt;if&lt;/span&gt;(node == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        &lt;span style="color: blue"&gt;return&lt;/span&gt;;

      &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; offset; ++i)
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot; &amp;quot;&lt;/span&gt;);

      &lt;span style="color: blue"&gt;switch&lt;/span&gt;(node.type)
      {
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Chr:
          &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(node.data);
          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Alter:
          &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;|&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Concat:
          &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Question:
          &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;?&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Star:
          &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
      }

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);

      PrintTree(node.left, offset + 8);
      PrintTree(node.right, offset + 8);
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;RD parser
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;char ::= alphanumeric character (letter or digit)
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Chr()
    {
      &lt;span style="color: blue"&gt;char &lt;/span&gt;data = Peek();

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsLetterOrDigit(data) || data == &lt;span style="color: #a31515"&gt;'\0'&lt;/span&gt;)
      {
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Chr, &lt;span style="color: blue"&gt;this&lt;/span&gt;.Pop(), &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;);
      }
      &lt;span style="color: blue"&gt;else
      &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Parse error: expected alphanumeric, got {0} at #{1}&amp;quot;&lt;/span&gt;,
        Peek(), GetPos());

        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey();

        &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.Exit(1);

        &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
      }
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;atom ::= char | '(' expr ')'
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Atom()
    {
      &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;atomNode;

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'('&lt;/span&gt;)
      {
        Pop();

        atomNode = Expr();

        &lt;span style="color: blue"&gt;if&lt;/span&gt;(Pop() != &lt;span style="color: #a31515"&gt;')'&lt;/span&gt;)
        {
          &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Parse error: expected ')'&amp;quot;&lt;/span&gt;);

          &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.Exit(1);
        }
      }
      &lt;span style="color: blue"&gt;else
        &lt;/span&gt;atomNode = Chr();

      &lt;span style="color: blue"&gt;return &lt;/span&gt;atomNode;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;rep ::= atom '*' | atom '?' | atom
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Rep()
    {
      &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;atomNode = Atom();

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'*'&lt;/span&gt;)
      {
        Pop();

        &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;repNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Star, &lt;span style="color: blue"&gt;null&lt;/span&gt;, atomNode, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;repNode;
      }
      &lt;span style="color: blue"&gt;else if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'?'&lt;/span&gt;)
      {
        Pop();

        &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;repNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Question, &lt;span style="color: #a31515"&gt;' '&lt;/span&gt;, atomNode, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;repNode;
      }
      &lt;span style="color: blue"&gt;else
        return &lt;/span&gt;atomNode;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;concat ::= rep . concat | rep
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Concat()
    {
      &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;left = Rep();

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;)
      {
        Pop();

        &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;right = Concat();

        &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;concatNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Concat, &lt;span style="color: blue"&gt;null&lt;/span&gt;, left, right);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;concatNode;
      }
      &lt;span style="color: blue"&gt;else
        return &lt;/span&gt;left;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;expr   ::= concat '|' expr | concat
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Expr()
    {
      &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;left = Concat();

      &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'|'&lt;/span&gt;)
      {
        Pop();

        &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;right = Expr();

        &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;exprNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Alter, &lt;span style="color: blue"&gt;null&lt;/span&gt;, left, right);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;exprNode;
      }
      &lt;span style="color: blue"&gt;else
        return &lt;/span&gt;left;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;The main entry point of the Console Application
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
    {
      &lt;span style="color: blue"&gt;if&lt;/span&gt;(args.Length != 3)
      {
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Call with the regex as an argument.&amp;quot;&lt;/span&gt;);

        &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.Exit(1);
      }

      &lt;span style="color: #2b91af"&gt;RegexParser &lt;/span&gt;myRegexParser = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RegexParser&lt;/span&gt;();

      &lt;span style="color: green"&gt;// Passing the regex to be preprocessed.
      &lt;/span&gt;myRegexParser.Init(args[1]);

      &lt;span style="color: green"&gt;// Creating a parse tree with the preprocessed regex
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;parseTree = myRegexParser.Expr();

      &lt;span style="color: green"&gt;// Checking for a string termination character after
      // parsing the regex
      &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(myRegexParser.Peek() != &lt;span style="color: #a31515"&gt;'\0'&lt;/span&gt;)
      {
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Parse error: unexpected char, got {0} at #{1}&amp;quot;&lt;/span&gt;,

        myRegexParser.Peek(), myRegexParser.GetPos());

        &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.Exit(1);
      }

      PrintTree(parseTree, 1);

      &lt;span style="color: #2b91af"&gt;NFA &lt;/span&gt;nfa = &lt;span style="color: #2b91af"&gt;NFA&lt;/span&gt;.TreeToNFA(parseTree);

      nfa.Show();

      &lt;span style="color: #2b91af"&gt;DFA &lt;/span&gt;dfa = &lt;span style="color: #2b91af"&gt;SubsetMachine&lt;/span&gt;.SubsetConstruct(nfa);

      dfa.Show();

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n\n&amp;quot;&lt;/span&gt;);

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;Result: {0}&amp;quot;&lt;/span&gt;, dfa.Simulate(args[2]));

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey();
    }

  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;From the &lt;font face="Courier New"&gt;Main&lt;/font&gt; entry point above in the code you can see that it’s a &lt;a href="http://en.wikipedia.org/wiki/Console_application" target="_blank"&gt;console application&lt;/a&gt; that starts with 3 arguments (parameters). For example, the parameters could be:&lt;/p&gt;

&lt;p align="center"&gt;&lt;font face="Courier New"&gt;RegularExpressionEngine &amp;quot;&lt;strong&gt;(l|e)*n?(i|e)el*&lt;/strong&gt;&amp;quot; leniel&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;1st param = &lt;font face="Courier New"&gt;RegularExpressionEngine&lt;/font&gt; = name of the program (executable)&lt;/p&gt;

&lt;p&gt;2nd param = &lt;font face="Courier New"&gt;&lt;strong&gt;(l|e)*n?(i|e)el*&lt;/strong&gt;&lt;/font&gt; = the pattern (regex) to match (to check against)&lt;/p&gt;

&lt;p&gt;3rd param = &lt;font face="Courier New"&gt;leniel&lt;/font&gt; = the input that will be tested against the regex&lt;/p&gt;

&lt;p&gt;Next we instantiate a new &lt;font color="#408080" face="Courier New"&gt;RegexParser&lt;/font&gt; and call its &lt;font face="Courier New"&gt;Init&lt;/font&gt;&lt;font face="Arial"&gt; &lt;/font&gt;method passing to it the second parameter - &lt;strong&gt;&lt;font face="Courier New"&gt;(l|e)*n?(i|e)el*&lt;/font&gt;&lt;/strong&gt; - that is located at the index 1 position within the &lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;[]&lt;/font&gt; args array.&lt;/p&gt;

&lt;p&gt;At the &lt;font color="#408080" face="Courier New"&gt;Init&lt;/font&gt; method we set the variable &lt;font face="Courier New"&gt;data&lt;/font&gt;&lt;font face="Arial"&gt; &lt;/font&gt;with the resulting string of the &lt;font face="Courier New"&gt;Preprocess()&lt;/font&gt; method, which as the name suggests preprocesses the regex so that we can translate it to an appropriate format to create a &lt;a href="http://en.wikipedia.org/wiki/Parse_tree" target="_blank"&gt;parse tree&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the preprocessed data we get for the regex: &lt;font face="Courier New"&gt;(l|e)*.n?.(i|e).e.l*&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Note that it adds dots (&lt;font face="Courier New"&gt;.&lt;/font&gt;) where appropriate.&lt;/p&gt;

&lt;p&gt;The regex engine presented here uses &lt;font face="Courier New"&gt;.&lt;/font&gt; for concatenation, &lt;font face="Courier New"&gt;|&lt;/font&gt; for alternation, and &lt;font face="Courier New"&gt;*&lt;/font&gt; for star. So, the regex &lt;font face="Courier New"&gt;&lt;strong&gt;(l|e)*n?(i|e)el*&lt;/strong&gt;&lt;/font&gt; can be represented in a tree form, just like an arithmetic expression.&lt;/p&gt;

&lt;p&gt;We then create a &lt;font color="#408080" face="Courier New"&gt;ParseTree&lt;/font&gt; that is nothing more than a data structure.&lt;/p&gt;

&lt;p&gt;The ParseTree class:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Text;

&lt;span style="color: blue"&gt;using &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input &lt;/span&gt;= System.&lt;span style="color: #2b91af"&gt;Char&lt;/span&gt;;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;RegularExpressionEngine
{
  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Parse tree
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree
  &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public enum &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NodeType
    &lt;/span&gt;{
      Chr,
      Star,
      Question,
      Alter,
      Concat
    }
    
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NodeType &lt;/span&gt;type;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;input&lt;/span&gt;? data;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;left;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;right;

    &lt;span style="color: blue"&gt;public &lt;/span&gt;ParseTree(&lt;span style="color: #2b91af"&gt;NodeType &lt;/span&gt;type_, &lt;span style="color: #2b91af"&gt;input&lt;/span&gt;? data_, &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;left_, &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;right_)
    {
      type = type_;
      data = data_;
      left = left_;
      right = right_;
    }
  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The local variable &lt;font face="Courier New"&gt;parseTree&lt;/font&gt; is generated through the result we get from the &lt;font face="Courier New"&gt;Expr()&lt;/font&gt; method. This method reads the preprocessed regex to create a parse tree that will be used further to create an NFA.&lt;/p&gt;

&lt;p&gt;If you look at the &lt;font color="#408080" face="Courier New"&gt;ParseTree&lt;/font&gt; class you’ll se that it has four properties: a &lt;font face="Courier New"&gt;nodeType&lt;/font&gt;, the &lt;font color="#408080" face="Courier New"&gt;input&lt;/font&gt; symbol (a character) and a left and right &lt;font color="#408080" face="Courier New"&gt;ParseTree&lt;/font&gt;. It’s a parse tree made of parse trees if you get the point.&lt;/p&gt;

&lt;p&gt;The property &lt;font face="Courier New"&gt;nodeType&lt;/font&gt; stores the type of the node that can be one of four types represented by the &lt;font color="#0000ff" face="Courier New"&gt;enum&lt;/font&gt; &lt;font color="#408080" face="Courier New"&gt;NodeType&lt;/font&gt;.&lt;/p&gt;

&lt;p&gt;The parse tree is created in four methods that also return a &lt;font color="#408080" face="Courier New"&gt;ParseTree&lt;/font&gt;. These methods are: &lt;font face="Courier New"&gt;Atom()&lt;/font&gt;, &lt;font face="Courier New"&gt;Chr()&lt;/font&gt;, &lt;font face="Courier New"&gt;Concat()&lt;/font&gt;, and &lt;font face="Courier New"&gt;Rep()&lt;/font&gt;.&lt;/p&gt;

&lt;p&gt;The order in which the afore mentioned methods are called is the following:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;Expr()&lt;/font&gt; calls &lt;font face="Courier New"&gt;Concat()&lt;/font&gt; that calls &lt;font face="Courier New"&gt;Rep()&lt;/font&gt; that calls &lt;font face="Courier New"&gt;Atom()&lt;/font&gt;. Note that &lt;font face="Courier New"&gt;Atom()&lt;/font&gt; can call &lt;font face="Courier New"&gt;Expr()&lt;/font&gt; again in case the first character of the regex be a grouping symbol “(“.&lt;/p&gt;

&lt;p&gt;These are the rules we must abide to create our parse tree:&lt;/p&gt;

&lt;p&gt;&lt;font color="#008000" face="Courier New"&gt;expr&amp;#160;&amp;#160; -&amp;gt; concat '|' expr | concat 
    &lt;br /&gt;&lt;/font&gt;&lt;font color="#008000" face="Courier New"&gt;concat -&amp;gt; rep . concat | rep 
    &lt;br /&gt;&lt;/font&gt;&lt;font color="#008000" face="Courier New"&gt;rep&amp;#160;&amp;#160;&amp;#160; -&amp;gt; atom '*' | atom '?' | atom 
    &lt;br /&gt;&lt;/font&gt;&lt;font color="#008000" face="Courier New"&gt;atom&amp;#160;&amp;#160; -&amp;gt; char | '(' expr ')' 
    &lt;br /&gt;&lt;/font&gt;&lt;font color="#008000" face="Courier New"&gt;char&amp;#160;&amp;#160; -&amp;gt; alphanumeric character (letter or digit)&lt;/font&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;expr   ::= concat '|' expr | concat
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Expr()
{
  &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;left = Concat();

  &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'|'&lt;/span&gt;)
  {
    Pop();

    &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;right = Expr();

    &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;exprNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Alter, &lt;span style="color: blue"&gt;null&lt;/span&gt;, left, right);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;exprNode;
  }
  &lt;span style="color: blue"&gt;else
    return &lt;/span&gt;left;
}&lt;/pre&gt;

&lt;p&gt;We call the method &lt;font face="Courier New"&gt;Concat()&lt;/font&gt; within &lt;font face="Courier New"&gt;Expr()&lt;/font&gt;:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;concat ::= rep . concat | rep
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Concat()
{
  &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;left = Rep();

  &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;)
  {
    Pop();

    &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;right = Concat();

    &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;concatNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Concat, &lt;span style="color: blue"&gt;null&lt;/span&gt;, left, right);
    
    &lt;span style="color: blue"&gt;return &lt;/span&gt;concatNode;
  }
  &lt;span style="color: blue"&gt;else
    return &lt;/span&gt;left;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Then we call &lt;font face="Courier New"&gt;Rep()&lt;/font&gt; within &lt;font face="Courier New"&gt;Concat()&lt;/font&gt;:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;rep ::= atom '*' | atom '?' | atom
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Rep()
{
  &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;atomNode = Atom();

  &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'*'&lt;/span&gt;)
  {
    Pop();

    &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;repNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Star, &lt;span style="color: blue"&gt;null&lt;/span&gt;, atomNode, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;repNode;
  }
  &lt;span style="color: blue"&gt;else if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'?'&lt;/span&gt;)
  {
    Pop();

    &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;repNode = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Question, &lt;span style="color: #a31515"&gt;' '&lt;/span&gt;, atomNode, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;repNode;
  }
  &lt;span style="color: blue"&gt;else
    return &lt;/span&gt;atomNode;
}&lt;/pre&gt;

&lt;p&gt;The &lt;font face="Courier New"&gt;Atom()&lt;/font&gt;&lt;font face="Arial"&gt; &lt;/font&gt;method is called within &lt;font face="Courier New"&gt;Rep()&lt;/font&gt;:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;atom ::= chr | '(' expr ')'
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Atom()
{
  &lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;atomNode;

  &lt;span style="color: blue"&gt;if&lt;/span&gt;(Peek() == &lt;span style="color: #a31515"&gt;'('&lt;/span&gt;)
  {
    Pop();

    atomNode = Expr();

    &lt;span style="color: blue"&gt;if&lt;/span&gt;(Pop() != &lt;span style="color: #a31515"&gt;')'&lt;/span&gt;)
    {
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Parse error: expected ')'&amp;quot;&lt;/span&gt;);

      &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.Exit(1);
    }
  }
  &lt;span style="color: blue"&gt;else
    &lt;/span&gt;atomNode = Chr();

  &lt;span style="color: blue"&gt;return &lt;/span&gt;atomNode;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;An interesting thing to note is that we’re using &lt;a href="http://en.wikipedia.org/wiki/Recursion_%28computer_science%29"&gt;recursive calls&lt;/a&gt; in two methods: &lt;font face="Courier New"&gt;Expr()&lt;/font&gt; and &lt;font face="Courier New"&gt;Concat()&lt;/font&gt;. A method is recursive if it calls itself.&lt;/p&gt;

&lt;p&gt;In &lt;font face="Courier New"&gt;Concat()&lt;/font&gt; we use the &lt;font face="Courier New"&gt;Peek()&lt;/font&gt; method to verify if the first character of the regex is an open round bracket ‘(‘. &lt;font face="Courier New"&gt;Peek()&lt;/font&gt; doesn’t increment the counter variable &lt;font face="Courier New"&gt;next&lt;/font&gt; used to access a symbol located at the index appointed by &lt;font face="Courier New"&gt;next&lt;/font&gt; within the &lt;font face="Courier New"&gt;data&lt;/font&gt; variable (the preprocessed regex). It only returns the symbol (a char).&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If the first character is an ‘(‘, then we use the &lt;font face="Courier New"&gt;Pop()&lt;/font&gt; method to get the next character to be checked and increment the counter variable &lt;font face="Courier New"&gt;next&lt;/font&gt;.&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you can see in the &lt;font face="Courier New"&gt;Atom()&lt;/font&gt; method, we call the &lt;font face="Courier New"&gt;Expr()&lt;/font&gt; method again, which will then iterate all over, that is, build the tree downward.&lt;/p&gt;

&lt;p&gt;In case the parser doesn’t find a group character ‘(‘ we fall within the &lt;font color="#0000ff" face="Courier New"&gt;else&lt;/font&gt; statement and then the &lt;font face="Courier New"&gt;atomNode&lt;/font&gt; which is itself a parse tree will receive a &lt;font color="#408080" face="Courier New"&gt;ParseTree&lt;/font&gt; object that contains a symbol.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;RD parser
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;char ::= alphanumeric character
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree &lt;/span&gt;Chr()
{
  &lt;span style="color: blue"&gt;char &lt;/span&gt;data = Peek();

  &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsLetterOrDigit(data) || data == &lt;span style="color: #a31515"&gt;'\0'&lt;/span&gt;)
  {
    &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ParseTree&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;NodeType&lt;/span&gt;.Chr, &lt;span style="color: blue"&gt;this&lt;/span&gt;.Pop(), &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;);
  }
  &lt;span style="color: blue"&gt;else
  &lt;/span&gt;{
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Parse error: expected alphanumeric, got {0} at #{1}&amp;quot;&lt;/span&gt;,
    Peek(), GetPos());

    &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.Exit(1);

    &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
  }
}&lt;/pre&gt;

&lt;p&gt;We check to see if the character peeked is a letter or digit or a character that signalizes the end of a string ‘&lt;font face="Courier New"&gt;\0&lt;/font&gt;’. In case it is we return a new object of type &lt;font color="#408080" face="Courier New"&gt;ParseTree&lt;/font&gt;, passing to its constructor the type of the node and the symbol it’ll store. We pass &lt;font color="#0000ff" face="Courier New"&gt;null&lt;/font&gt; to the last two parameters because in the case of an alphanumeric (letter or digit) the node created will be a leaf node. For more on this, read the article about &lt;a href="http://en.wikipedia.org/wiki/Parse_tree" target="_blank"&gt;parse trees&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the parse tree we get if we execute the program with the regex 
  &lt;br /&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;(l|e)*n?(i|e)el*&lt;/strong&gt;:&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;. 
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; * 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; l 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; . 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ? 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; n 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; . 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; i 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; . 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; * 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; l&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html" target="_blank"&gt;next post&lt;/a&gt; we’ll generate a NFA with this tree. I’ll then present the NFA class.&lt;/p&gt;

&lt;p align="right"&gt;&lt;em&gt;&lt;strong&gt;Updated on 5/12/2009 09:50:00 PM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I finished writing the series of posts, here goes the list that points to them:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html" target="_blank"&gt;Regular Expression Engine in C# (the Story)&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html" target="_blank"&gt;Regex engine in C# - the NFA&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html" target="_blank"&gt;Regex engine in C# - the DFA&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html" target="_blank"&gt;Regex engine in C# - matching strings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; 

  &lt;br /&gt;[1] &lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Bendersky, Eli&lt;/a&gt;. &lt;strong&gt;Algorithmic Forays - Part 1&lt;/strong&gt;. March 7, 2004. Available at &amp;lt;&lt;a href="http://www.gamedev.net/reference/programming/features/af1" target="_blank"&gt;http://www.gamedev.net/reference/programming/features/af1&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on February 24, 2008.&lt;/p&gt;

&lt;p&gt;[2] &lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Bendersky, Eli&lt;/a&gt;. &lt;strong&gt;Algorithmic Forays - Part 2&lt;/strong&gt;. March 29, 2004. Available at &amp;lt;&lt;a href="http://www.gamedev.net/reference/programming/features/af2" target="_blank"&gt;http://www.gamedev.net/reference/programming/features/af2&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on February 24, 2008.&lt;/p&gt;

&lt;p&gt;[3] &lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Bendersky, Eli&lt;/a&gt;. &lt;strong&gt;Algorithmic Forays - Part 3&lt;/strong&gt;. April 28, 2004. Available at &amp;lt;&lt;a href="http://www.gamedev.net/reference/programming/features/af3" target="_blank"&gt;http://www.gamedev.net/reference/programming/features/af3&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on February 24, 2008.&lt;/p&gt;

&lt;p&gt;[4] &lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Bendersky, Eli&lt;/a&gt;. &lt;strong&gt;Algorithmic Forays - Part 4&lt;/strong&gt;. June 7, 2004. Available at &amp;lt;&lt;a href="http://www.gamedev.net/reference/programming/features/af4" target="_blank"&gt;http://www.gamedev.net/reference/programming/features/af4&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on February 24, 2008.&lt;/p&gt;

&lt;p&gt;[5] &lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Bendersky, Eli&lt;/a&gt;. &lt;strong&gt;Algorithmic Forays - Part 5&lt;/strong&gt;. August 17, 2004. Available at &amp;lt;&lt;a href="http://www.gamedev.net/reference/programming/features/af5" target="_blank"&gt;http://www.gamedev.net/reference/programming/features/af5&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on February 24, 2008.&lt;/p&gt;

&lt;p&gt;[6] &lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Bendersky, Eli&lt;/a&gt;. &lt;strong&gt;Algorithmic Forays - Part 6&lt;/strong&gt;. November 4, 2004. Available at &amp;lt;&lt;a href="http://www.gamedev.net/reference/programming/features/af6" target="_blank"&gt;http://www.gamedev.net/reference/programming/features/af6&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&amp;gt;. Accessed on February 24, 2008.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-6019914016319882899?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7AEfxhKby0FBKiqGZLv3yeLz2zQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7AEfxhKby0FBKiqGZLv3yeLz2zQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7AEfxhKby0FBKiqGZLv3yeLz2zQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7AEfxhKby0FBKiqGZLv3yeLz2zQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=Dwvwurwp"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=8PZkfSt2"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=8PZkfSt2" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=gMnnGaFG"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=gMnnGaFG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=LOvKBTc6"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=LOvKBTc6" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=5MBifu0B"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=lFVYDepU"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/N7VYm91or6g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/6019914016319882899/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6019914016319882899?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6019914016319882899?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/N7VYm91or6g/regex-engine-in-csharp-regexparser.html" title="Regex engine in C# - the Regex Parser" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIDSHg_eyp7ImA9WxJREUo.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-7059465790618112548</id><published>2009-02-23T03:36:00.001-03:00</published><updated>2009-05-12T22:02:59.643-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T22:02:59.643-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NFA" /><category scheme="http://www.blogger.com/atom/ns#" term="DFA" /><category scheme="http://www.blogger.com/atom/ns#" term="Finite State Machine" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Regex" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Regular Expression Engine in C# (the Story)</title><content type="html">&lt;p&gt;A “long time ago”, more precisely 3 years ago, I was studying &lt;a href="http://en.wikipedia.org/wiki/Automata_theory" target="_blank"&gt;Automata&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Formal_language" target="_blank"&gt;Formal Languages&lt;/a&gt; which was a Computer Engineering discipline in the 6th semester out of 10 at &lt;a href="http://ubm.br" target="_blank"&gt;UBM&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;At that time I was amazed by the new things I was learning such as &lt;a href="http://en.wikipedia.org/wiki/Nondeterministic_finite_state_machine" target="_blank"&gt;NFA - Nondetermistic Finite Automaton&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Deterministic_finite_state_machine" target="_blank"&gt;DFA - Deterministic Finite Automaton&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Finite_state_machine" target="_blank"&gt;Finite State Machine&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Regular_expression" target="_blank"&gt;Regular Expressions&lt;/a&gt;. For more on this, read my last post: &lt;a href="http://www.leniel.net/2009/02/fortran-numerical-constants-recognizer.html"&gt;Fortran Numerical Constants Recognizer&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For the sake of my development I started searching for programming related material that could put me informed about such amazing computer science constructs.&lt;/p&gt;  &lt;p&gt;I then came across a series of articles at &lt;a href="http://gamedev.net" target="_blank"&gt;GameDev.net&lt;/a&gt; called &lt;strong&gt;&lt;a href="http://www.gamedev.net/reference/programming/features/af1" target="_blank"&gt;Algorithmic Forays&lt;/a&gt;&lt;/strong&gt;. It’s been written by &lt;strong&gt;&lt;a href="http://eli.thegreenplace.net" target="_blank"&gt;Eli Bendersky&lt;/a&gt;&lt;/strong&gt;. This guy did a great job putting together the base for a Regular Expression Engine that exercise the concepts of NFA and DFA. His code was presented in C++ and I took the time to learn a bit more about this powerful language too.&lt;/p&gt;  &lt;p&gt;After reading Algorithmic Forays from part 1 through part 6 I started thinking about translating the code from C++ to C#. That’d be a great opportunity to grasp new C# constructs and at the same time get in touch with material related to the discipline afore mentioned.&lt;/p&gt;  &lt;p&gt;Setting that in my mind I put my hands at work and after struggling here and there I got the code translated. I also thought about writing a Portuguese version of the article to be publicized at my university’s scientific magazine. The idea was to write an adapted version of the article presenting both code (C++ and C#) showing how to achieve the same results using different programming languages &lt;a href="http://en.wikipedia.org/wiki/Data_structure" target="_blank"&gt;data structures&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I’ve sent a message to Eli asking him permission to write a Portuguese version of the article. You can read the e-mail I’ve sent Eli and his reply below:&lt;/p&gt;  &lt;p&gt;&lt;img alt="Gmail" src="http://mail.google.com/mail/help/images/logo1.gif" width="143" height="59" /&gt;     &lt;br /&gt;&lt;b&gt;Leniel Macaferi &amp;lt;le@…&amp;gt; &lt;/b&gt;&lt;/p&gt;  &lt;hr /&gt;&lt;b&gt;Algorithmic Forays for a Regex Parser&lt;/b&gt;   &lt;hr /&gt;  &lt;p&gt;&lt;b&gt;le@... &amp;lt;&lt;b&gt;le@...&lt;/b&gt;&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/b&gt;&lt;b&gt;Wed, Jan 3, 2007 at 5:43 AM &lt;/b&gt;&lt;/p&gt;  &lt;p&gt;To: eli…@…&lt;/p&gt;  &lt;p&gt;Cc: Wellington Magalhães Leite &amp;lt;wml@…&amp;gt; &lt;/p&gt;  &lt;p&gt;Dear Eli,&lt;/p&gt;  &lt;p&gt;My name is Leniel and I'm a student of Computer Engineering here in    &lt;br /&gt;Brazil. I'm currently in the 9th term out of 10.     &lt;br /&gt;You can see my basic profile at     &lt;br /&gt;&lt;a href="http://www.codeproject.com/script/profile/whos_who.asp?id=1224713"&gt;http://www.codeproject.com/script/profile/whos_who.asp?id=1224713&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Today I'm on my vacation and I'm going to come back studying on February.&lt;/p&gt;  &lt;p&gt;I'm passionate for anything related to technology and specially    &lt;br /&gt;programming which is my hobby just like yours.&lt;/p&gt;  &lt;p&gt;Firstly I'd like to congratulate you by your advanced knowledge of    &lt;br /&gt;such great topics about Computer Science and Computer Engineering like     &lt;br /&gt;the one you discussed in the article Algorithmic Forays - Part 1 to 6.&lt;/p&gt;  &lt;p&gt;Well, I've read your biography at &lt;a href="http://eli.thegreenplace.net/about/"&gt;http://eli.thegreenplace.net/about/&lt;/a&gt;     &lt;br /&gt;and I'm currently seeing your photo album. You're a great example for     &lt;br /&gt;us to follow due your characteristics as liking to study and liking to     &lt;br /&gt;travel the whole world. It's just what I want to do too as a     &lt;br /&gt;professional and as a traveler! You really do very well on this.&lt;/p&gt;  &lt;p&gt;Your site is all of good! Think about the entire internet filled with    &lt;br /&gt;sites just like yours. With a complete bunch of interesting     &lt;br /&gt;information! My God it's a dream.&lt;/p&gt;  &lt;p&gt;Coming to the real reason I'm writing to you - it's about a project    &lt;br /&gt;that has been proposed to me and a friend of mine called Wellington.     &lt;br /&gt;When we were in the 7th term at the university during our class of     &lt;br /&gt;Laboratory of Compiler Construction studying Lex and Yacc, our teacher     &lt;br /&gt;asked us to prepare an article about the process of creation of an     &lt;br /&gt;engine to parse Regular Expressions. Since that moment we started     &lt;br /&gt;searching the Internet for something that we could use as a base for     &lt;br /&gt;our article. For our lucky, we found your article Algorithmic Forays     &lt;br /&gt;at &lt;a href="http://www.gamedev.net"&gt;www.gamedev.net&lt;/a&gt; that is amazing for everyone to understand. It's     &lt;br /&gt;simple and direct with implementation examples.     &lt;br /&gt;During the 6th term at the university we had a discipline called     &lt;br /&gt;Automatons and Formal Languages. Was at this period that we learned     &lt;br /&gt;topics regarding Finite State Machines (FSM), Deterministic Finite     &lt;br /&gt;Automatons (DFA), Nondeterministic Finite Automatons (NFA) and Regular     &lt;br /&gt;Expressions. So, from there we know that a DFA + NFA = FSM! We've also     &lt;br /&gt;implemented some code for covering and getting a better understanding     &lt;br /&gt;of how such topics work in reality.&lt;/p&gt;  &lt;p&gt;In true, we started our project preparing an article on April, May of    &lt;br /&gt;2006, when I particularly started converting all your Algorithmic     &lt;br /&gt;Foray's C++ code to the C# language that is the one I most like to use     &lt;br /&gt;for writing any kind of code. But due our other tasks, in other words,     &lt;br /&gt;other disciplines, we stopped working on this project. It's important     &lt;br /&gt;to mention that I could finalize translating your C++ code to C# on     &lt;br /&gt;the middle of May 2006.&lt;/p&gt;  &lt;p&gt;I've learned such great things working with the code as mastering my    &lt;br /&gt;knowledge with the Generics in C#. I even got one third party DLL     &lt;br /&gt;called C5.dll from &lt;a href="http://www.itu.dk/research/c5/"&gt;http://www.itu.dk/research/c5/&lt;/a&gt; which includes lots     &lt;br /&gt;of new classes to work with sets of data as is necessary when dealing     &lt;br /&gt;with regular expressions.&lt;/p&gt;  &lt;p&gt;Yesterday, 1/2, when I woke up I just thought why not to continue    &lt;br /&gt;working on that project about a regex parser. So, I started again with     &lt;br /&gt;new motivations.&lt;/p&gt;  &lt;p&gt;I started translating your whole article from English to Portuguese    &lt;br /&gt;and I'd like to ask you if we could use some text and diagrams of your     &lt;br /&gt;article as the base of our article and we would present it with both     &lt;br /&gt;versions of code, C++ and C#.&lt;/p&gt;  &lt;p&gt;Our aim is to forward it to be issued in our university's scientific    &lt;br /&gt;magazine and propagate to the ones interested – see     &lt;br /&gt;&lt;a href="http://www.ubm.br/ubm/paginas/copep/inicial.php?pagina=apresentacao.php"&gt;http://www.ubm.br/ubm/paginas/copep/inicial.php?pagina=apresentacao.php&lt;/a&gt;     &lt;br /&gt;(it's in Portuguese - you're learning Spanish and it's a little bit     &lt;br /&gt;alike. I've already publicized one article in this magazine with the     &lt;br /&gt;title: Development and Numeric Simulation of Algorithms for     &lt;br /&gt;Computational Resolution of Ordinary Differential Equations. It was a     &lt;br /&gt;project I developed while I was in the 4th term. The code was     &lt;br /&gt;developed using C++. Further, this article will be available in the     &lt;br /&gt;Internet through an indexing project that's been prepared by a     &lt;br /&gt;university here in Brazil.&lt;/p&gt;  &lt;p&gt;We'll certainly cite the article's fonts as you can see in the    &lt;br /&gt;preliminary code I'm going to send you in this e-mail. Your great     &lt;br /&gt;initiative of publicizing the article must be preserved by any mean.     &lt;br /&gt;Haven't you used any other bibliography? Was it developed by just your     &lt;br /&gt;thoughts?&lt;/p&gt;  &lt;p&gt;Remember that this code I'm sending you needs a review because I have    &lt;br /&gt;to pass through it to get it all in mind again and see if everything     &lt;br /&gt;is Ok. To run the code you just need to recompile it using a C#     &lt;br /&gt;compiler. I use the Microsoft Visual Studio 2005 Express Edition as     &lt;br /&gt;you mentioned in your home page here     &lt;br /&gt;&lt;a href="http://eli.thegreenplace.net/2006/12/03/a-complete-c-development-environment-from-microsoft-free/"&gt;http://eli.thegreenplace.net/2006/12/03/a-complete-c-development-environment-from-microsoft-free/&lt;/a&gt;     &lt;br /&gt;The initial parameter I'm using is set in the command line argument     &lt;br /&gt;inside the project's properties in Debug and is as follow:     &lt;br /&gt;RegularExpressionEngine &amp;quot;(a|b)*abb&amp;quot; aaababb     &lt;br /&gt;It's seems to be working Ok.     &lt;br /&gt;Try it for yourself!&lt;/p&gt;  &lt;p&gt;From now on we're just waiting for your reply.&lt;/p&gt;  &lt;p&gt;By the way, if you and your wife want to come to visit Brazil you can    &lt;br /&gt;certainly come to my house. I'd like to have you as my guests. Who     &lt;br /&gt;knows, one day I can go to Israel and meet you personally. That would     &lt;br /&gt;be great too. Israel is the apple of God's eye!&lt;/p&gt;  &lt;p&gt;I simply think we have the same liking!&lt;/p&gt;  &lt;p&gt;It was a pleasure to write to you.&lt;/p&gt;  &lt;p&gt;My best regards,    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Leniel Braz de Oliveira Macaferi     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Volta Redonda, Rio de Janeiro, Brazil&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;img alt="Gmail" src="http://mail.google.com/mail/help/images/logo1.gif" width="143" height="59" /&gt;     &lt;br /&gt;&lt;b&gt;Leniel Macaferi &amp;lt;le@…&amp;gt; &lt;/b&gt;&lt;/p&gt;  &lt;hr /&gt;&lt;b&gt;Algorithmic Forays for a Regex Parser&lt;/b&gt;   &lt;hr /&gt;  &lt;p&gt;&lt;b&gt;Eli Bendersky &amp;lt;eli@…&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/b&gt;&lt;b&gt;Sun, Jan 21, 2007 at 2:03 AM &lt;/b&gt;&lt;/p&gt;  &lt;p&gt;To: &amp;quot;le@…&amp;quot; &amp;lt;le@…&amp;gt; &lt;/p&gt;  &lt;p&gt;Hello Leniel,&lt;/p&gt;  &lt;p&gt;First of all, thanks for all the compliments - I'm flattered.    &lt;br /&gt;You can certainly use any part of the articles and the diagrams for your translation. As for my sources, I certainly didn't invent anything - I took all the material from the &amp;quot;Dragon Book&amp;quot; (&amp;quot;Compilers&amp;quot; by Aho, Sethi and Ullman), perhaps with the help of some googling, but as far as I remember, the book was the main source.&lt;/p&gt;  &lt;p&gt;Keep being enthusiastic about your studies. That's a good thing :-)&lt;/p&gt;  &lt;p&gt;Regards,&lt;/p&gt;  &lt;p&gt;Eli&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;As you can see from the above e-mail, Eli agreed and so it was OK to write a Portuguese version of his articles.&lt;/p&gt;  &lt;p&gt;As the semesters passed and new commitments queued I stopped translating the articles and I have just decided this past week that now it’s a good time to come back to it and finish the planned objective of 2 years ago.&lt;/p&gt;  &lt;p&gt;While I write the next blog posts I’ll translate the remaining articles to Portuguese. I expect to publish it online here on this blog so that it can help people out there to learn this fascinating subject of &lt;a href="http://en.wikipedia.org/wiki/Theory_of_computation" target="_blank"&gt;Computation Theory&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I’ll follow a different path to explain how the regular expression engine work, that is, from part 1 to part 6 I’ll be showing each division of the engine by means of its representing class in code. I’ll do so, so that I can present each part of the translated code (C++ to C#) in such a way that it gets easier to understand. I’ll use a &lt;a href="http://en.wikipedia.org/wiki/Top-down_and_bottom-up_design" target="_blank"&gt;top down approach&lt;/a&gt;, that is, I’ll begin showing the higher level class and then I’ll go deep to its dependencies.&lt;/p&gt;  &lt;p&gt;This is the story behind the Regular Expression Engine in C# I’ll be presenting in the next posts, starting with this &lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;one&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Hope that you like it as much as I do. This was for sure one of or even the best discipline I’ve had in the Computer Engineering course and one of the more exciting things to write about.&lt;/p&gt;  &lt;p align="right"&gt;&lt;em&gt;&lt;strong&gt;Updated on 5/12/2009 09:41:00 PM&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;As I finished writing the series of posts, here goes the list that points to them:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.leniel.net/2009/02/regex-engine-in-csharp-regexparser.html" target="_blank"&gt;Regex engine in C# - the Regex Parser&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/04/regex-engine-in-csharp-nfa.html" target="_blank"&gt;Regex engine in C# - the NFA&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-dfa.html" target="_blank"&gt;Regex engine in C# - the DFA&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://www.leniel.net/2009/05/regex-engine-in-csharp-match-strings.html" target="_blank"&gt;Regex engine in C# - matching strings&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-7059465790618112548?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LSd66gvtmXrLha7kc6cdM1QBkIQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LSd66gvtmXrLha7kc6cdM1QBkIQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LSd66gvtmXrLha7kc6cdM1QBkIQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LSd66gvtmXrLha7kc6cdM1QBkIQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=BElBk9jc"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=9xE9a4SL"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=9xE9a4SL" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=8Sp34Xr6"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=8Sp34Xr6" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=pMaKRWP8"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=pMaKRWP8" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=SWDhdSSV"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=G1bFvGhc"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/3ce282sW7pI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/7059465790618112548/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/7059465790618112548?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/7059465790618112548?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/3ce282sW7pI/regular-expression-engine-in-csharp.html" title="Regular Expression Engine in C# (the Story)" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.leniel.net/2009/02/regular-expression-engine-in-csharp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUNRXw5eyp7ImA9WxVXEUg.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-645288991973412628</id><published>2009-02-09T01:19:00.001-02:00</published><updated>2009-02-09T02:04:54.223-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-09T02:04:54.223-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="compilers construction" /><category scheme="http://www.blogger.com/atom/ns#" term="state transition diagram" /><category scheme="http://www.blogger.com/atom/ns#" term="fortran" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><title>Fortran Numerical Constants Recognizer</title><content type="html">&lt;p&gt;&lt;strong&gt;Compilers construction paper      &lt;br /&gt;&lt;/strong&gt;I and a dear brother in faith of mine called Wellington Magalhães Leite wrote a paper titled: Fortran Numerical Constants Recognizer&lt;/p&gt;  &lt;p&gt;It exercises concepts related to &lt;a href="http://en.wikipedia.org/wiki/State_diagram" target="_blank"&gt;state transition diagram&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Finite_state_machine" target="_blank"&gt;finite state machine&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Automata_theory" target="_blank"&gt;automata theory&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Needless to say, &lt;a href="http://en.wikipedia.org/wiki/Compiler_construction" target="_blank"&gt;compilers construction&lt;/a&gt; was one of the best disciplines or even the best discipline I had in the computer engineering course. I really like this kind of stuff. State machines and automata theory really rocks! Automata theory is other discipline I had that really got my attention.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;State Transition Diagram      &lt;br /&gt;&lt;/strong&gt;This is the lexical state transition diagram in which our work is based:&lt;/p&gt;  &lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Fortran Numerical Constants - State Transition Diagram" border="0" alt="Fortran Numerical Constants - State Transition Diagram" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SY-nyJrd2oI/AAAAAAAAAeo/OH-YywcviEY/FortranNumericalConstantsStateTransitionDiagram%5B5%5D.png?imgmax=800" width="472" height="242" /&gt;&lt;/p&gt;  &lt;p&gt;Alphabet = {d, +, - , . , E} (d is any digit)&lt;/p&gt;  &lt;p&gt;The arches of any vertex to an Error vertex aren’t showed but they exist.&lt;/p&gt;  &lt;p&gt;Expressions like the following are recognized: 13, +13, -13, 13., 1.25, .25, -.25, -32.43, 13E-15, 13.E-15, -13.25E+72, .75E5, etc.&lt;/p&gt;  &lt;p&gt;Expressions like the following aren’t recognized: ++13, .E13, etc.&lt;/p&gt;  &lt;p&gt;The vertex with a 0 (zero) value is the initial state.&lt;/p&gt;  &lt;p&gt;The vertexes with bold circles are the final states.&lt;/p&gt;  &lt;p align="left"&gt;&lt;em&gt;Note: It’s important to note that lexical state transition diagrams are finite automatons.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Abstract      &lt;br /&gt;&lt;/strong&gt;A didactic method for the construction of a compiler front-end is the one substantiated in transition diagrams. So, its construction helps with the familiarization regarding the tasks of a compiler project.&lt;/p&gt;  &lt;p&gt;This paper presents a Fortran numerical constants recognizer. It is developed based on a state transition diagram and its implementation follows the standards of the C# programming language.&lt;/p&gt;  &lt;p&gt;Keywords: fortran, compiler construction, state transition diagram, C# programming language&lt;/p&gt;  &lt;pre&gt;&lt;span class="toc"&gt;CONTENTS
1 INTRODUCTION 6
  1.1 Objective	6
  1.2 Definition 6
2 DEVELOPMENT 7
  2.1 Mapping the constants 7
  2.2 Mapping the functions 7
  2.3 Application main entry point 10
3 APPLICATION 12
  3.1 Validating expressions 12
      3.1.1 Single expression 12
      3.1.2 Set of expressions 13
4 CONCLUSION 14
5 REFERENCES 15
6 ADDENDUM 16
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Resumo 
    &lt;br /&gt;&lt;/strong&gt;Um método muito didático para a construção do front-end de um compilador é aquele fundamentado em diagramas de transição. Logo, seu estudo ajuda na familiarização com as atividades envolvidas no projeto de um compilador.&lt;/p&gt;

&lt;p&gt;Esse trabalho apresenta um sistema reconhecedor de constantes numéricas em Fortran. O mesmo é desenvolvido a partir de um diagrama de transição de estados e sua codificação segue os padrões e moldes da linguagem de programação C#.&lt;/p&gt;

&lt;p&gt;Palavras-chave: fortran, construção de compiladores, diagrama de transição de estados, linguagem de programação C#&lt;/p&gt;

&lt;pre&gt;&lt;span class="toc"&gt;SUMÁRIO
1 Introdução 5
   1.1 Objetivo	5
   1.2 Definição 5
2 Desenvolvimento 6
   2.1 Mapeamento das constantes 6
   2.2 Mapeamento das funções 6
   2.3 Mapeamento da chamada principal 10
3 Aplicação 12
   3.1 Validação de expressões 12
       3.1.1 Uma única expressão 13
       3.1.2 Uma lista de expressões 14
4 Conclusão 15
5 Bibliografia	16
6 Anexo 17
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Source code&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StateTransitionSystem
&lt;/span&gt;{
  &lt;span style="color: blue"&gt;public static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
  {
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Title = &lt;span style="color: #a31515"&gt;&amp;quot;State Transition System for recognizing numeric constants in FORTRAN&amp;quot;&lt;/span&gt;;

    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.BackgroundColor = &lt;span style="color: #2b91af"&gt;ConsoleColor&lt;/span&gt;.White;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ForegroundColor = &lt;span style="color: #2b91af"&gt;ConsoleColor&lt;/span&gt;.Black;

    &lt;span style="color: blue"&gt;char &lt;/span&gt;ch;

    &lt;span style="color: blue"&gt;do
    &lt;/span&gt;{
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Clear();

      &lt;span style="color: green"&gt;// Print startup banner
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\nState Transition System C# Sample Application\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;Copyright ©2006 Leniel Braz de Oliveira Macaferi &amp;amp; Wellington Magalhães Leite.\n\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;UBM COMPUTER ENGINEERING - 7TH SEMESTER [http://www.ubm.br/]\n\n&amp;quot;&lt;/span&gt;);

      &lt;span style="color: green"&gt;// Describes program function
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;This program example demonstrates the State Transition Diagram's algorithm for\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;numeric constants validation in FORTRAN.\n\n&amp;quot;&lt;/span&gt;);

      &lt;span style="color: green"&gt;// Describes program's options     
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;You can validate expressions by two different ways as follow:\n\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;1 - A single expression by providing an entry.\n\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;2 - A set of expressions by providing an input file.\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;  * Notice: the expressions must be separeted in-lines.\n&amp;quot;&lt;/span&gt;);

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n\nEnter your choice: &amp;quot;&lt;/span&gt;);

      ch = &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey().KeyChar;

      &lt;span style="color: blue"&gt;switch&lt;/span&gt;(ch)
      {
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;'1'&lt;/span&gt;:
          {
            SingleExpression();
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;
          }
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;'2'&lt;/span&gt;:
          {
            SetOfExpressions();
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;
          }
      }
    }
    &lt;span style="color: blue"&gt;while&lt;/span&gt;(ch == &lt;span style="color: #a31515"&gt;'1' &lt;/span&gt;|| ch == &lt;span style="color: #a31515"&gt;'2'&lt;/span&gt;);
  }

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Enumeration where each item corresponds to one state in the State Transition Diagram.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public enum &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates
  &lt;/span&gt;{
    s0 = 0,
    s1,
    s2,
    s3,
    s4,
    s5,
    s6,
    s7,
    error
  }

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Array of type PossibleStates, which contains the finalStates acceptable by the
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;State Transition Diagram.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;[] finalStates = { &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s2, &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s3, &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s6 };

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Verifies if the last state achieved by the machine belongs to the finalStates
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;array.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public static bool &lt;/span&gt;IsFinalState(&lt;span style="color: #2b91af"&gt;PossibleStates &lt;/span&gt;currentState)
  {
    &lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; finalStates.Length; i++)
      &lt;span style="color: blue"&gt;if&lt;/span&gt;(currentState == finalStates[i])
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;

    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
  }

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Recognizes the current state and the character “label” being analysed, values
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;passed as parameters. After, the function does the transition of state case some
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;condition is satisfied, otherwise, the function will return an error flag.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates &lt;/span&gt;Recognizer(&lt;span style="color: #2b91af"&gt;PossibleStates &lt;/span&gt;currentState, &lt;span style="color: blue"&gt;char &lt;/span&gt;c)
  {
    &lt;span style="color: blue"&gt;switch&lt;/span&gt;(currentState)
    {
      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s0:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'+' &lt;/span&gt;|| c == &lt;span style="color: #a31515"&gt;'-'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s1;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s2;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s4;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s1:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s2;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s4;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s2:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s2;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s3;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'E'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s5;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s3:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s3;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'E'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s5;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s4:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s3;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s5:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s6;

          &lt;span style="color: blue"&gt;if&lt;/span&gt;(c == &lt;span style="color: #a31515"&gt;'+' &lt;/span&gt;|| c == &lt;span style="color: #a31515"&gt;'-'&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s7;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s6:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s6;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }

      &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s7:
        {
          &lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: blue"&gt;char&lt;/span&gt;.IsDigit(c))
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s6;

          &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        }
    }
    &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.error;
  }

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Reads an input expression, recognizes its characters, changes the states
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;accordingly to those characters and hence validates the entry.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public static void &lt;/span&gt;SingleExpression()
  {
    &lt;span style="color: blue"&gt;do
    &lt;/span&gt;{
      &lt;span style="color: green"&gt;// The machine points to the initial state of the State Transition Diagram.
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates &lt;/span&gt;currentState = &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s0;

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n\nEnter the expression to be evaluated: &amp;quot;&lt;/span&gt;);

      &lt;span style="color: green"&gt;// strExpression receives the entry typed by the user.
      &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;strExpression = &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();

      &lt;span style="color: green"&gt;/* For each string's character (label), calls the function Recognizer that
      on the other hand changes the machine state accordingly. */
      &lt;/span&gt;&lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; strExpression.Length &amp;gt; i; ++i)
        &lt;span style="color: blue"&gt;if&lt;/span&gt;(currentState != &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.error)
          currentState = Recognizer(currentState, strExpression[i]);
        &lt;span style="color: blue"&gt;else
          break&lt;/span&gt;;

      &lt;span style="color: green"&gt;/* Calls the function IsFinalState to verify if the state where the machine
       stopped is a final state or not. */
      &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(IsFinalState(currentState))
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;\n Valid expression.\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: blue"&gt;else
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;\n Invalid expression!\n&amp;quot;&lt;/span&gt;);

      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;Do you wanna try again? (y\\n) &amp;quot;&lt;/span&gt;);
    }
    &lt;span style="color: blue"&gt;while&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey().KeyChar == &lt;span style="color: #a31515"&gt;'y'&lt;/span&gt;);
  }

  &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
  /// &lt;/span&gt;&lt;span style="color: green"&gt;Reads an input file, recognizes its lines, expression by expression and changes
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;the states accordingly to each expression. In other words, validates the entire
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;list.
  &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;public static void &lt;/span&gt;SetOfExpressions()
  {
    &lt;span style="color: blue"&gt;do
    &lt;/span&gt;{
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n\nEnter the file path: &amp;quot;&lt;/span&gt;);

      &lt;span style="color: green"&gt;// Obtains the file name.
      &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;fileName = &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();

      &lt;span style="color: green"&gt;// Verifies if the file exists.
      &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(!&lt;span style="color: #2b91af"&gt;File&lt;/span&gt;.Exists(fileName))
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\n File not found!\n\n&amp;quot;&lt;/span&gt;);
      &lt;span style="color: blue"&gt;else
      &lt;/span&gt;{
        &lt;span style="color: green"&gt;// Reads all the file's lines and stores them.
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StreamReader &lt;/span&gt;sReader = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StreamReader&lt;/span&gt;(fileName);

        &lt;span style="color: blue"&gt;string &lt;/span&gt;expression;

        &lt;span style="color: green"&gt;// Evaluates each line until achieve the EOF (end of file).
        &lt;/span&gt;&lt;span style="color: blue"&gt;while&lt;/span&gt;((expression = sReader.ReadLine()) != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        {
          &lt;span style="color: green"&gt;// The machine points to the initial state of the State Transition Diagram.
          &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PossibleStates &lt;/span&gt;currentState = &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.s0;

          &lt;span style="color: green"&gt;/* For each expression's character (label), calls the function Recognizer that
          on the other hand changes the machine state accordingly. */
          &lt;/span&gt;&lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; expression.Length &amp;gt; i; ++i)
            &lt;span style="color: blue"&gt;if&lt;/span&gt;(currentState != &lt;span style="color: #2b91af"&gt;PossibleStates&lt;/span&gt;.error)
              currentState = Recognizer(currentState, expression[i]);
            &lt;span style="color: blue"&gt;else
              break&lt;/span&gt;;

          &lt;span style="color: green"&gt;/* Calls the function IsFinalState to verify if the state where the machine
           stopped for the expression is a final state or not. */
          &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(IsFinalState(currentState))
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;\n{0} is a valid expression.&amp;quot;&lt;/span&gt;, expression);
          &lt;span style="color: blue"&gt;else
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;\n{0} is an invalid expression!&amp;quot;&lt;/span&gt;, expression);
        }
        sReader.Close();
      }
      &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;&amp;quot;\nDo you wanna try again? (y\\n) &amp;quot;&lt;/span&gt;);
    }
    &lt;span style="color: blue"&gt;while&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey().KeyChar == &lt;span style="color: #a31515"&gt;'y'&lt;/span&gt;);
  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;Screenshots 
    &lt;br /&gt;&lt;/strong&gt;See screenshots of Fortran numerical constants recognizer in action:&lt;/p&gt;

&lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Fortran Numerical Constants Recognizer - Single Expression" border="0" alt="Fortran Numerical Constants Recognizer - Single Expression" src="http://lh6.ggpht.com/_W1dLiLjFqdw/SY-g0P-SWGI/AAAAAAAAAeg/pDuBD5T195M/FortranNumericalConstantsRecognizerSingleExpression%5B8%5D.png?imgmax=800" width="520" height="543" /&gt; &lt;/p&gt;

&lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Fortran Numerical Constants Recognizer - Set Of Expressions" border="0" alt="Fortran Numerical Constants Recognizer - Set Of Expressions" src="http://lh6.ggpht.com/_W1dLiLjFqdw/SY-g2plM3aI/AAAAAAAAAek/uF_SMk6rbKc/FortranNumericalConstantsRecognizerSetOfExpressions%5B5%5D.png?imgmax=800" width="520" height="505" /&gt; &lt;/p&gt;

&lt;p&gt;You can get a PDF copy of the paper and the accompanying Fortran Numerical Constants Recognizer files in a ZIP file at:&lt;/p&gt;

&lt;p&gt;English version 
  &lt;br /&gt;&lt;a title="http://leniel.googlepages.com/FortranNumericalConstantsRecognizer.pdf" href="http://leniel.googlepages.com/FortranNumericalConstantsRecognizer.pdf"&gt;http://leniel.googlepages.com/FortranNumericalConstantsRecognizer.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Portuguese version 
  &lt;br /&gt;&lt;a title="http://leniel.googlepages.com/SisReconhecedorConstNumericasFortran.pdf" href="http://leniel.googlepages.com/SisReconhecedorConstNumericasFortran.pdf"&gt;http://leniel.googlepages.com/SisReconhecedorConstNumericasFortran.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Visual Studio C# 2008 Console Application project 
  &lt;br /&gt;&lt;a href="http://leniel.googlepages.com/FortranNumericalConstantsRecognizer.zip"&gt;http://leniel.googlepages.com/FortranNumericalConstantsRecognizer.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The program’s source code is in a Microsoft Visual Studio C# 2008 Console Application project. If you don’t have Visual Studio, you can get a free copy of its express edition at &lt;a href="http://www.microsoft.com/express/download" target="_blank"&gt;http://www.microsoft.com/express/download&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-645288991973412628?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/icFOQMbTqgvqnLNM88NanLtg3jI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/icFOQMbTqgvqnLNM88NanLtg3jI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/icFOQMbTqgvqnLNM88NanLtg3jI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/icFOQMbTqgvqnLNM88NanLtg3jI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=xAKNqGzb"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=J4DSFayx"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=J4DSFayx" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=a6TSMaVd"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=a6TSMaVd" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=khnLTdSX"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=khnLTdSX" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=Lb0OWdoG"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=9BusYHz4"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/n2-S0Ue72E8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/645288991973412628/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/02/fortran-numerical-constants-recognizer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/645288991973412628?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/645288991973412628?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/n2-S0Ue72E8/fortran-numerical-constants-recognizer.html" title="Fortran Numerical Constants Recognizer" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/02/fortran-numerical-constants-recognizer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUASX89cSp7ImA9WxJWFkw.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-1506570643362511220</id><published>2009-02-02T00:59:00.008-02:00</published><updated>2009-06-21T18:04:08.169-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-21T18:04:08.169-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spreadsheet" /><category scheme="http://www.blogger.com/atom/ns#" term="Google Spreadsheet API" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Chart" /><title>ASP.NET Chart with MVC and Google Spreadsheet API</title><content type="html">&lt;span style="width: 160px; font-size: 9pt"&gt;   &lt;br /&gt;&lt;a href="http://www.barcodelib.com" target="_blank"&gt;BarcodeLib.com&lt;/a&gt; provides the leading barcode components for Java and ASP .NET developers.    &lt;br /&gt;For Java developers, you can use their &lt;a href="http://www.barcodelib.com/java_barcode/main.html" target="_blank"&gt;Java barcode&lt;/a&gt; library, a high quality &lt;a href="http://www.barcodelib.com/java_barcode/main.html" target="_blank"&gt;Java barcode generator&lt;/a&gt; generates high quality barcode images in Java applications.    &lt;br /&gt;For ASP.NET, C#, VB.NET developers, &lt;a href="http://www.barcodelib.com/net_barcode/main.html" target="_blank"&gt;ASP.NET barcode&lt;/a&gt; or &lt;a href="http://www.barcodelib.com/net_barcode/main.html" target="_blank"&gt;C# barcode&lt;/a&gt; will help developers generate barcode images in C#, VB.NET websites.    &lt;br /&gt;&lt;a href="http://www.barcodelib.com/net_barcode/main.html" target="_blank"&gt;.NET barcode&lt;/a&gt; library will also help developers generate barcode images in .NET WinForms application, SQL Server reporting service, and Crystal Reports for .NET.    &lt;br /&gt;&lt;a href="http://www.barcodelib.com/barcode_fonts/barcode-fonts.html" target="_blank"&gt;Barcode Fonts&lt;/a&gt; also allows to display barcode (Code 39, Code 129, UPC) in    &lt;br /&gt;office documents (Microsoft Word, Microsoft Excel) and reports (Crystal reports) easily. &lt;a href="http://www.barcodelib.com/net_barcode_reader/main.html" target="_blank"&gt;C# Barcode Reader&lt;/a&gt;, a barcode image recognition SDK for C#, VB.NET developers.&lt;/span&gt;  &lt;br /&gt;  &lt;br /&gt;  &lt;p&gt;Scott Guthrie recently posted about the &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/11/24/new-asp-net-charting-control-lt-asp-chart-runat-quot-server-quot-gt.aspx" target="_blank"&gt;New ASP.NET Charting Control: &amp;lt;asp:chart runat=&amp;quot;server&amp;quot;/&amp;gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This weekend I decided to give it a try and as always I had to go through the samples to learn how to assemble a chart.&lt;/p&gt;  &lt;p&gt;To learn about the new charting controls I got &lt;a href="http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591" target="_blank"&gt;the Microsoft Chart Controls Samples project&lt;/a&gt; and played with the contents of the Getting Started section.&lt;/p&gt;  &lt;p&gt;At the same time I was &lt;a href="http://weblogs.asp.net/scottguportuguese/archive/2009/01/27/asp-net-mvc-1.0-release-candidate-candidata-a-lancamento-agora-disponivel.aspx" target="_blank"&gt;translating to Portuguese&lt;/a&gt; ScottGu’s blog post about the &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx" target="_blank"&gt;ASP.NET MVC 1.0 Release Candidate&lt;/a&gt;. I was also updating a Google spreadsheet that I use to keep track of worked hours at &lt;a href="http://www.leniel.net/2008/08/arriving-at-chemtech.html" target="_blank"&gt;Chemtech&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To learn how to integrate ASP.NET charting controls with ASP.NET MVC and Google Spreadsheet Data API I created a new ASP.NET MVC project and started coding a sample application.&lt;/p&gt;  &lt;p&gt;The following is how I got it all together:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Drawing;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Linq;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.Mvc;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI.DataVisualization.Charting;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Google.GData.Client;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Google.GData.Extensions;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Google.GData.Spreadsheets;
&lt;span style="color: blue"&gt;namespace &lt;/span&gt;MvcChartGoogleSpreadsheet.Views.Home
{
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;ASP.NET MVC application + ASP.NET charting controls + Google Spreadsheet Data API web-based application
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;It demonstrates the operations supported by each of these technologies.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;It requires authentication in the form of your Google Docs &amp;amp; Spreadsheets username
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;and password, and retrieves data from a worksheet of your choice.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;A chart is created with the data acquired through a CellFeed query.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Index &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ViewPage
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;WorksheetEntry&lt;/span&gt;&amp;gt; allWorksheets = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;WorksheetEntry&lt;/span&gt;&amp;gt;();

        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;Page_Load(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, System.&lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e)
        {
            &lt;span style="color: green"&gt;// Calling the method that configures the chart.
            &lt;/span&gt;ConfigureChart();

            &lt;span style="color: green"&gt;// Creating a Google SpreadsheetService object passing to it the name of the application.
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SpreadsheetsService &lt;/span&gt;service = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SpreadsheetsService&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;MvcChartGoogleSpreadsheet&amp;quot;&lt;/span&gt;);

            &lt;span style="color: green"&gt;// Google account information (login and password)
            &lt;/span&gt;service.setUserCredentials(&lt;span style="color: #a31515"&gt;&amp;quot;username@gmail.com&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;);

            GetAllSpreadsheetsAndWorksheets(service);

            &lt;span style="color: green"&gt;// Using LINQ query expression to get a specific worksheet.
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;entry = &lt;span style="color: blue"&gt;from &lt;/span&gt;wse &lt;span style="color: blue"&gt;in &lt;/span&gt;allWorksheets
                        &lt;span style="color: blue"&gt;where
                            &lt;/span&gt;wse.Title.Text == &lt;span style="color: #a31515"&gt;&amp;quot;2008 leniel.net&amp;quot; &lt;/span&gt;&lt;span style="color: green"&gt;// This is the name of the worksheet.&lt;/span&gt;&lt;span style="color: #a31515"&gt;
                        &lt;/span&gt;&lt;span style="color: blue"&gt;select &lt;/span&gt;wse;

            &lt;span style="color: green"&gt;// Demonstrate a CellFeed query.
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CellFeed &lt;/span&gt;cellFeed = GetWorksheetCellFeed(service, entry.First());

            &lt;span style="color: green"&gt;// Each entry represents a cell within the worksheet.
            &lt;/span&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CellEntry &lt;/span&gt;cellEntry &lt;span style="color: blue"&gt;in &lt;/span&gt;cellFeed.Entries)
            {
                &lt;span style="color: green"&gt;// I just want to get the contents of column 2 of the worksheet.
                // The value of the cell present in column 2 will be used in the X axis.
                &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(cellEntry.Cell.Column == 2)
                {
                    &lt;span style="color: green"&gt;// I get the value of column 7 (cellEntry.Cell.Column + 5) of the same row. This value will be used in the Y axis.
                    // I replace the colon present in the value with a dot. I do so to make the data valid for calculating values.
                    &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;yValue = ((&lt;span style="color: #2b91af"&gt;CellEntry&lt;/span&gt;)cellFeed.Entries.SingleOrDefault(es =&amp;gt; ((&lt;span style="color: #2b91af"&gt;CellEntry&lt;/span&gt;)es).Cell.Row == cellEntry.Cell.Row &amp;amp;&amp;amp; ((&lt;span style="color: #2b91af"&gt;CellEntry&lt;/span&gt;)es).Cell.Column == cellEntry.Cell.Column + 5)).Cell.Value.Replace(&lt;span style="color: #a31515"&gt;&amp;quot;:&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);

                    &lt;span style="color: green"&gt;// I then remove the extra data that isn't necessary at all in my case.
                    &lt;/span&gt;yValue = yValue.Remove(yValue.Length - 3, 3);

                    &lt;span style="color: green"&gt;// I pass the X and Y values to create a Point used in the series of the chart.
                    &lt;/span&gt;chart1.Series[&lt;span style="color: #a31515"&gt;&amp;quot;Hours of work&amp;quot;&lt;/span&gt;].Points.AddXY(cellEntry.Cell.Value, yValue);
                }
            }
        }

        &lt;span style="color: blue"&gt;private void &lt;/span&gt;ConfigureChart()
        {
            chart1.Series.Add(&lt;span style="color: #a31515"&gt;&amp;quot;Hours of work&amp;quot;&lt;/span&gt;);

            chart1.Titles.Add(&lt;span style="color: #a31515"&gt;&amp;quot;My chart title&amp;quot;&lt;/span&gt;);

            &lt;span style="color: green"&gt;// Add header separator of type line      
            &lt;/span&gt;chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].HeaderSeparator = &lt;span style="color: #2b91af"&gt;LegendSeparatorStyle&lt;/span&gt;.Line;
            chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].HeaderSeparatorColor = &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.Gray;

            &lt;span style="color: green"&gt;// Add Color column      
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn &lt;/span&gt;firstColumn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn&lt;/span&gt;();
            firstColumn.ColumnType = &lt;span style="color: #2b91af"&gt;LegendCellColumnType&lt;/span&gt;.SeriesSymbol;
            firstColumn.HeaderText = &lt;span style="color: #a31515"&gt;&amp;quot;Color&amp;quot;&lt;/span&gt;;
            firstColumn.HeaderBackColor = &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.WhiteSmoke;
            chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].CellColumns.Add(firstColumn);

            &lt;span style="color: green"&gt;// Add Legend Text column      
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn &lt;/span&gt;secondColumn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn&lt;/span&gt;();
            secondColumn.ColumnType = &lt;span style="color: #2b91af"&gt;LegendCellColumnType&lt;/span&gt;.Text;
            secondColumn.HeaderText = &lt;span style="color: #a31515"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;;
            secondColumn.Text = &lt;span style="color: #a31515"&gt;&amp;quot;#LEGENDTEXT&amp;quot;&lt;/span&gt;;
            secondColumn.HeaderBackColor = &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.WhiteSmoke;
            chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].CellColumns.Add(secondColumn);

            &lt;span style="color: green"&gt;// Add AVG cell column      
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn &lt;/span&gt;avgColumn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn&lt;/span&gt;();
            avgColumn.Text = &lt;span style="color: #a31515"&gt;&amp;quot;#AVG{N2}&amp;quot;&lt;/span&gt;;
            avgColumn.HeaderText = &lt;span style="color: #a31515"&gt;&amp;quot;Avg&amp;quot;&lt;/span&gt;;
            avgColumn.Name = &lt;span style="color: #a31515"&gt;&amp;quot;AvgColumn&amp;quot;&lt;/span&gt;;
            avgColumn.HeaderBackColor = &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.WhiteSmoke;
            chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].CellColumns.Add(avgColumn);

            &lt;span style="color: green"&gt;// Add Total cell column      
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn &lt;/span&gt;totalColumn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn&lt;/span&gt;();
            totalColumn.Text = &lt;span style="color: #a31515"&gt;&amp;quot;#TOTAL{N1}&amp;quot;&lt;/span&gt;;
            totalColumn.HeaderText = &lt;span style="color: #a31515"&gt;&amp;quot;Total&amp;quot;&lt;/span&gt;;
            totalColumn.Name = &lt;span style="color: #a31515"&gt;&amp;quot;TotalColumn&amp;quot;&lt;/span&gt;;
            totalColumn.HeaderBackColor = &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.WhiteSmoke;
            chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].CellColumns.Add(totalColumn);

            &lt;span style="color: green"&gt;// Set Min cell column attributes      
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn &lt;/span&gt;minColumn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LegendCellColumn&lt;/span&gt;();
            minColumn.Text = &lt;span style="color: #a31515"&gt;&amp;quot;#MIN{N1}&amp;quot;&lt;/span&gt;;
            minColumn.HeaderText = &lt;span style="color: #a31515"&gt;&amp;quot;Min&amp;quot;&lt;/span&gt;;
            minColumn.Name = &lt;span style="color: #a31515"&gt;&amp;quot;MinColumn&amp;quot;&lt;/span&gt;;
            minColumn.HeaderBackColor = &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.WhiteSmoke;
            chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].CellColumns.Add(minColumn);

            &lt;span style="color: green"&gt;// Show labels at every 2 days
            &lt;/span&gt;chart1.ChartAreas[&lt;span style="color: #a31515"&gt;&amp;quot;ChartArea1&amp;quot;&lt;/span&gt;].AxisX.LabelStyle.Interval = 2;
            chart1.ChartAreas[&lt;span style="color: #a31515"&gt;&amp;quot;ChartArea1&amp;quot;&lt;/span&gt;].AxisX.MajorGrid.Interval = 2;
            chart1.ChartAreas[&lt;span style="color: #a31515"&gt;&amp;quot;ChartArea1&amp;quot;&lt;/span&gt;].AxisX.MajorTickMark.Interval = 2;

            &lt;span style="color: green"&gt;// Set series tooltips
            &lt;/span&gt;chart1.Series[&lt;span style="color: #a31515"&gt;&amp;quot;Hours of work&amp;quot;&lt;/span&gt;].ToolTip = &lt;span style="color: #a31515"&gt;&amp;quot;#VALX&amp;quot;&lt;/span&gt;;&lt;span style="color: green"&gt;

&lt;/span&gt;&lt;span style="color: green"&gt;// Set the width of the chart
&lt;/span&gt;           chart1.Width = 510;

&lt;span style="color: green"&gt;           // Set legend docking
&lt;/span&gt;           chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].Docking = &lt;span style="color: #2b91af"&gt;Docking&lt;/span&gt;.Bottom;

&lt;span style="color: green"&gt;           // Set legend alignment
&lt;/span&gt;           chart1.Legends[&lt;span style="color: #a31515"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;].Alignment = &lt;span style="color: #2b91af"&gt;StringAlignment&lt;/span&gt;.Center;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;&lt;/span&gt;        }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Gets a list of all the user's spreadsheets, and the
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;list of worksheets that each spreadsheet contains.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&amp;quot;service&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;An authenticated SpreadsheetsService object&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;GetAllSpreadsheetsAndWorksheets(&lt;span style="color: #2b91af"&gt;SpreadsheetsService &lt;/span&gt;service)
        {
            &lt;span style="color: #2b91af"&gt;SpreadsheetQuery &lt;/span&gt;query = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SpreadsheetQuery&lt;/span&gt;();

            &lt;span style="color: #2b91af"&gt;SpreadsheetFeed &lt;/span&gt;feed = service.Query(query);

            &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SpreadsheetEntry &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;feed.Entries)
            {
                GetAllWorksheets(service, entry);
            }
        }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Gets a list of all worksheets in the specified spreadsheet.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&amp;quot;service&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;An authenticated SpreadsheetsService object&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&amp;quot;entry&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The spreadsheet whose worksheets are to be retrieved&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;GetAllWorksheets(&lt;span style="color: #2b91af"&gt;SpreadsheetsService &lt;/span&gt;service, &lt;span style="color: #2b91af"&gt;SpreadsheetEntry &lt;/span&gt;entry)
        {
            &lt;span style="color: #2b91af"&gt;AtomLink &lt;/span&gt;link = entry.Links.FindService(&lt;span style="color: #2b91af"&gt;GDataSpreadsheetsNameTable&lt;/span&gt;.WorksheetRel, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

            &lt;span style="color: #2b91af"&gt;WorksheetQuery &lt;/span&gt;query = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WorksheetQuery&lt;/span&gt;(link.HRef.ToString());

            &lt;span style="color: #2b91af"&gt;WorksheetFeed &lt;/span&gt;feed = service.Query(query);

            &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;WorksheetEntry &lt;/span&gt;worksheet &lt;span style="color: blue"&gt;in &lt;/span&gt;feed.Entries)
            {
                allWorksheets.Add(worksheet);
            }
        }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Performs a cell range query on the specified worksheet to
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;retrieve only the cells contained within the specified range.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&amp;quot;service&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;An authenticated SpreadsheetsService object&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&amp;quot;entry&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The worksheet to retrieve&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CellFeed &lt;/span&gt;GetWorksheetCellFeed(&lt;span style="color: #2b91af"&gt;SpreadsheetsService &lt;/span&gt;service, &lt;span style="color: #2b91af"&gt;WorksheetEntry &lt;/span&gt;entry)
        {
            &lt;span style="color: #2b91af"&gt;AtomLink &lt;/span&gt;listFeedLink = entry.Links.FindService(&lt;span style="color: #2b91af"&gt;GDataSpreadsheetsNameTable&lt;/span&gt;.CellRel, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

            &lt;span style="color: #2b91af"&gt;CellQuery &lt;/span&gt;query = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CellQuery&lt;/span&gt;(listFeedLink.HRef.ToString());&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;            // Defining the range of cells that I want to be retrieved.&lt;/span&gt;
            query.Range = &lt;span style="color: #a31515"&gt;&amp;quot;B5:G29&amp;quot;&lt;/span&gt;;

            &lt;span style="color: #2b91af"&gt;CellFeed &lt;/span&gt;feed = service.Query(query);

            &lt;span style="color: blue"&gt;return &lt;/span&gt;feed;
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The above code is commented so I don’t think it needs more words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ASP.NET MVC 
    &lt;br /&gt;&lt;/strong&gt;I’ve already written about ASP.NET MVC in a post titled &lt;a href="http://www.leniel.net/2008/05/hello-world-web-site-with-aspnet-mvc.html"&gt;Hello World Web Site with ASP.NET MVC&lt;/a&gt;. If you don’t know what &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller" target="_blank"&gt;MVC&lt;/a&gt; means, don’t panic! It’s just an architectural and design pattern that advocates a clean separation of concerns in software engineering.&lt;/p&gt;

&lt;p&gt;To get the ASP.NET MVC I’d recommend the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=3a41fac1-ed06-4944-a24d-76c8da31cf7d&amp;amp;displaylang=en" target="_blank"&gt;Web Platform Installer&lt;/a&gt; that Microsoft released not so long ago.&lt;/p&gt;

&lt;p&gt;Just download and install the Web Platform Installer and select what web development tools you want to be installed on your machine.&lt;/p&gt;

&lt;p&gt;&lt;img title="MicrosoftWebPlatformInstaller" border="0" alt="MicrosoftWebPlatformInstaller" src="http://lh4.ggpht.com/_W1dLiLjFqdw/SYZhiK6ZqAI/AAAAAAAAAeQ/Ebpn3O21dWU/MicrosoftWebPlatformInstaller%5B8%5D.png?imgmax=800" width="510" height="380" /&gt;&lt;/p&gt;

&lt;p&gt;As you can see above I already have the &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx" target="_blank"&gt;ASP.NET MVC Release Candidate 1&lt;/a&gt; installed on my machine. In case you don’t have it yet, select the checkbox and click the Install button. The Web Platform Installer will do the rest of the job, that is, it’ll download the packages and install it conveniently for you.&lt;/p&gt;

&lt;p&gt;An interesting thing about the Web Platform Installer is that it’ll always have the most updated bits to be installed.&lt;/p&gt;

&lt;p&gt;After installing the ASP.NET MVC you’re ready to create an ASP.NET MVC Web Application in Visual Studio 2008:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_W1dLiLjFqdw/SYZhkynPPtI/AAAAAAAAAes/vkNwFsk6fVE/s1600-h/ASP.NETMvcChartGoogleSpreadsheetProject.png"&gt;&lt;img title="ASP.NETMvcChartGoogleSpreadsheetProject" border="0" alt="ASP.NETMvcChartGoogleSpreadsheetProject" src="http://lh3.ggpht.com/_W1dLiLjFqdw/SYZhoA8oIEI/AAAAAAAAAew/Nx4QmdkhNe0/ASP.NETMvcChartGoogleSpreadsheetProject_thumb.png?imgmax=800" width="510" height="372" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Spreadsheet API 
    &lt;br /&gt;&lt;/strong&gt;To accomplish the goal of this post I needed more documentation and so I went to &lt;a href="http://code.google.com/apis/spreadsheets/overview.html"&gt;Google Spreadsheets APIs and Tools page&lt;/a&gt;. From there I went to read &lt;a href="http://code.google.com/apis/spreadsheets/docs/2.0/developers_guide_protocol.html"&gt;the Google Spreadsheets Data API Developer's Guide&lt;/a&gt;. Specifically the &lt;a href="http://code.google.com/apis/spreadsheets/docs/2.0/developers_guide_dotnet.html"&gt;Developer's Guide for .NET&lt;/a&gt; since I’m playing with Microsoft development platform.&lt;/p&gt;

&lt;p&gt;After reading some bits here and some bits there I went directly to the &lt;a href="http://code.google.com/apis/spreadsheets/code.html"&gt;Libraries and Code page&lt;/a&gt; and went to the download page of &lt;a href="http://code.google.com/p/google-gdata/"&gt;google-gdata&lt;/a&gt; – the .NET library for the Google Data API.&lt;/p&gt;

&lt;p&gt;I downloaded the file &lt;a href="http://google-gdata.googlecode.com/files/Google%20Data%20API%20Setup%281.3.1.0%29.msi"&gt;Google Data API Setup(1.3.1.0).msi&lt;/a&gt; and installed it. It has sample projects for all Google Data APIs. I was interested in the Spreadsheet API and so I got the specific code and dropped it on the ASP.NET MVC project.&lt;/p&gt;

&lt;p&gt;As you can see in the above code the &lt;font color="#0000ff" size="2" face="Courier New"&gt;using&lt;/font&gt; statements include 3 references to Google Data API DLLs:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Google.GData.Client;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Google.GData.Extensions;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Google.GData.Spreadsheets;&lt;/pre&gt;

&lt;p&gt;These DLLs are part of &lt;a href="http://google-gdata.googlecode.com/files/Google%20Data%20API%20Setup%281.3.1.0%29.msi"&gt;Google Data API Setup(1.3.1.0).msi&lt;/a&gt; installation file and are located at &lt;font size="2" face="Courier New"&gt;C:\Program files\Google\Google Data API SDK\Redist&lt;/font&gt; in my machine. You’ll need to add these DLLs to the References folder of the ASP.NET MVC project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ASP.NET Charting Controls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are charts of all types:&lt;/p&gt;

&lt;p&gt;- Bar and Column Charts 
  &lt;br /&gt;- Line Charts 

  &lt;br /&gt;- Area Charts 

  &lt;br /&gt;- Pie and Doughnut Charts 

  &lt;br /&gt;- Point Charts 

  &lt;br /&gt;- Range Charts 

  &lt;br /&gt;- Circular Charts 

  &lt;br /&gt;- Accumulation Charts 

  &lt;br /&gt;- Data Distribution Charts 

  &lt;br /&gt;- Price Change Financial Charts 

  &lt;br /&gt;- Advanced Financial Charts 

  &lt;br /&gt;- Combinational Charts&lt;/p&gt;

&lt;p&gt;To get the charting controls in Visual Studio 2008 I downloaded 2 files:&lt;/p&gt;

&lt;p&gt;- &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=130f7986-bf49-4fe5-9ca8-910ae6ea442c&amp;amp;DisplayLang=en" target="_blank"&gt;Microsoft Chart Controls for Microsoft .NET Framework 3.5&lt;/a&gt; 

  &lt;br /&gt;- &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=1D69CE13-E1E5-4315-825C-F14D33A303E9&amp;amp;displaylang=en" target="_blank"&gt;Microsoft Chart Controls Add-on for Microsoft Visual Studio 2008&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installing both files, open Visual Studio 2008 and go to a webform/viewpage .ASPX page. Now in the Toolbox you’ll find the new Chart control.&lt;/p&gt;

&lt;p align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ASP.NET Chart Control" border="0" alt="ASP.NET Chart Control" src="http://lh3.ggpht.com/_W1dLiLjFqdw/SYZhfX33E9I/AAAAAAAAAeM/g1abySh3bKo/ASP.NETChartControl%5B5%5D.png?imgmax=800" width="228" height="539" /&gt; &lt;/p&gt;

&lt;p&gt;Drag and drop the chart onto the page and you’re ready to go.&lt;/p&gt;

&lt;p&gt;Look to the &lt;font color="#0000ff" size="2" face="Courier New"&gt;using&lt;/font&gt; statement present in the code behind page:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI.DataVisualization.Charting;&lt;/pre&gt;

&lt;p&gt;This is the column chart I got when I ran the application:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ASP.NET Chart Imgage" border="0" alt="ASP.NET Chart Imgage" src="http://lh3.ggpht.com/_W1dLiLjFqdw/SYZwAKogx6I/AAAAAAAAAec/9uVsOYj68-I/ASP.NETChartImgCAU0586K%5B5%5D.png?imgmax=800" width="510" height="296" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LINQ 
    &lt;br /&gt;&lt;/strong&gt;I used some constructs of LINQ in the above sample application. If you need further details about this fantastic technology: read my post &lt;a href="http://www.leniel.net/2008/01/linq-language-integrated-query.html" target="_blank"&gt;LINQ - Language Integrated Query&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: 
  &lt;br /&gt;To work with Dates in a chart I had to go through &lt;a href="http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591" target="_blank"&gt;the Microsoft Chart Controls Samples project&lt;/a&gt; and look at Working with Chart Data – Working with Dates – Setting Time Scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary 
    &lt;br /&gt;&lt;/strong&gt;As you could see the ASP.NET charting control is feature rich and you can use it to show data from all sorts of sources as for example a Google spreadsheet. I just showed here the simplest of the charts.&lt;/p&gt;

&lt;p&gt;Using the charting controls in an ASP.NET MVC application is a really straightforward task. Of course, you’d have action methods that’d generate the chart for you based on some logic you implement in such methods. The sample given here was just to exercise the integration of technologies available nowadays to build richer internet applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References 
    &lt;br /&gt;&lt;/strong&gt;&lt;em&gt;ASP.NET MVC 
    &lt;br /&gt;&lt;/em&gt;&lt;a href="http://www.leniel.net/2008/05/hello-world-web-site-with-aspnet-mvc.html" target="_blank"&gt;Hello World Web Site with ASP.NET MVC&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.asp.net/mvc" target="_blank"&gt;ASP.NET MVC : The Official Microsoft ASP.NET Site&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/scottgu" target="_blank"&gt;ScottGu's Blog&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Model-view-controller" target="_blank"&gt;Model View Controller (MVC) at Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Google Spreadsheet API&lt;/em&gt; 

  &lt;br /&gt;&lt;a href="http://code.google.com/apis/spreadsheets/overview.html" target="_blank"&gt;Google Spreadsheets APIs and Tools page&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://code.google.com/apis/spreadsheets/docs/2.0/developers_guide_protocol.html" target="_blank"&gt;Google Spreadsheets Data API Developer's Guide&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://code.google.com/apis/spreadsheets/docs/2.0/developers_guide_dotnet.html" target="_blank"&gt;Google Spreadsheets Developer's Guide for .NET&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://code.google.com/apis/spreadsheets/code.html" target="_blank"&gt;Google Spreadsheets Libraries and Code page&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://code.google.com/p/google-gdata" target="_blank"&gt;google-gdata – the .NET library for the Google Data API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ASP.NET Charting controls 
    &lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=EE8F6F35-B087-4324-9DBA-6DD5E844FD9F&amp;amp;displaylang=en" target="_blank"&gt;Download the Microsoft Chart Controls Documentation&lt;/a&gt; 

    &lt;br /&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/MSWinWebChart/threads/" target="_blank"&gt;Microsoft Chart Control Forum&lt;/a&gt; 

    &lt;br /&gt;&lt;/em&gt;&lt;a href="http://blogs.msdn.com/alexgor" target="_blank"&gt;Alex Gorev's Weblog - Data Visualization&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd453008.aspx" target="_blank"&gt;Charting With ASP.NET And LINQ&lt;/a&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downloads 
    &lt;br /&gt;&lt;/strong&gt;&lt;em&gt;ASP.NET MVC 
    &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=3a41fac1-ed06-4944-a24d-76c8da31cf7d&amp;amp;displaylang=en" target="_blank"&gt;Web Platform Installer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Google Spreadsheet API 
    &lt;br /&gt;&lt;/em&gt;&lt;a href="http://google-gdata.googlecode.com/files/Google%20Data%20API%20Setup%281.3.1.0%29.msi" target="_blank"&gt;Google Data API Setup(1.3.1.0).msi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ASP.NET Charting controls 
    &lt;br /&gt;&lt;/em&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=130f7986-bf49-4fe5-9ca8-910ae6ea442c&amp;amp;DisplayLang=en" target="_blank"&gt;Microsoft Chart Controls for Microsoft .NET Framework 3.5&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=1D69CE13-E1E5-4315-825C-F14D33A303E9&amp;amp;displaylang=en" target="_blank"&gt;Microsoft Chart Controls Add-on for Microsoft Visual Studio 2008&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591" target="_blank"&gt;Microsoft Chart Controls Samples project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visual Studio 2008 C# ASP.NET MVC Web Application 
    &lt;br /&gt;&lt;/strong&gt;You can get the Microsoft Visual Studio Project at:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://leniel.googlepages.com/MvcChartGoogleSpreadsheet.zip" href="http://leniel.googlepages.com/MvcChartGoogleSpreadsheet.zip"&gt;http://leniel.googlepages.com/MvcChartGoogleSpreadsheet.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Remember to change/substitute the username and password present in the file C:\MvcChartGoogleSpreadsheet\Views\Home\Index.aspx.cs so that the application can log you on to Google Spreadsheet service and get your data (spreadsheet along with the worksheets).&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-1506570643362511220?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NCbMN7iM64zTZF-SB7OPf33ialM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NCbMN7iM64zTZF-SB7OPf33ialM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NCbMN7iM64zTZF-SB7OPf33ialM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NCbMN7iM64zTZF-SB7OPf33ialM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=h9To4FeY"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=7gJFUXh1"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=7gJFUXh1" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=6jxSoYVp"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=6jxSoYVp" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=NyER1bS8"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=NyER1bS8" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=xGZruE71"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=h09aMs0x"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/Z0u1vuRCTlY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/1506570643362511220/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/02/aspnet-chart-mvc-google-spreadsheet-api.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/1506570643362511220?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/1506570643362511220?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/Z0u1vuRCTlY/aspnet-chart-mvc-google-spreadsheet-api.html" title="ASP.NET Chart with MVC and Google Spreadsheet API" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.leniel.net/2009/02/aspnet-chart-mvc-google-spreadsheet-api.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YDQ3k5eyp7ImA9WxJQF0g.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-2088316658637339884</id><published>2009-01-20T01:52:00.001-02:00</published><updated>2009-05-31T04:32:52.723-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-31T04:32:52.723-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="webservice" /><category scheme="http://www.blogger.com/atom/ns#" term="Chemtech" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="soapUI" /><category scheme="http://www.blogger.com/atom/ns#" term="LINQ" /><title>Line prefixer suffixer in C#</title><content type="html">&lt;p&gt;I extracted a lot of Ids from a database table and needed to pass such Ids as a parameter to a &lt;a href="http://en.wikipedia.org/wiki/Webservice" target="_blank"&gt;webservice&lt;/a&gt; method. The webservice method was expecting a parameter of type &lt;font face="Courier New"&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;long&lt;/span&gt;&amp;gt;&lt;/font&gt;. I didn’t find a way of passing such a list to the webservice using the built in webservice form constructed by Visual Studio. The cause is that a &lt;font face="Courier New"&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;long&lt;/span&gt;&amp;gt;&lt;/font&gt; isn’t a primitive type.&lt;/p&gt;&lt;p&gt;Talking with my peers I learned of a tool called &lt;a href="http://www.soapui.org" target="_blank"&gt;soapUI&lt;/a&gt;. It’s a tool used to test webservices. Using it I could pass the list of Ids.&lt;/p&gt;&lt;p&gt;I created a new project in soapUI passing to it the webservice &lt;a href="http://en.wikipedia.org/wiki/Web_Services_Description_Language" target="_blank"&gt;WSDL&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/URL" target="_blank"&gt;URL&lt;/a&gt; and I was ready to go.&lt;/p&gt;&lt;p align="center"&gt;&amp;#160;&lt;img title="soapUI New Project" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="440" alt="soapUI New Project" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SXVKgwzgpdI/AAAAAAAAAd4/hIdg_lBkpuc/soapUINewProject1%5B5%5D.png?imgmax=800" width="470" border="0" /&gt; &lt;/p&gt;&lt;p align="center"&gt;&lt;img title="New soapUI Project" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="296" alt="New soapUI Project" src="http://lh6.ggpht.com/_W1dLiLjFqdw/SXVKh1MVntI/AAAAAAAAAd8/_OiDWUWlgPc/soapUINewProject2%5B11%5D.png?imgmax=800" width="476" border="0" /&gt; &lt;/p&gt;&lt;p align="left"&gt;This is the value I’ve put in Initial WSDL/WADL: &lt;a title="http://localhost:7777/WebServices/MyWebserviceName.asmx?WSDL" href="http://localhost:7777/WebServices/MyWebserviceName.asmx?WSDL"&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre class="code"&gt;http://localhost:7777/WebServices/MyWebserviceName.asmx?WSDL&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;p&gt;After clicking OK, soapUI will then load the webservice definition.&lt;/p&gt;&lt;p&gt;Clicking in Request 1 as shown in the following picture, the &lt;a href="http://en.wikipedia.org/wiki/XML" target="_blank"&gt;XML&lt;/a&gt; of a &lt;a href="http://en.wikipedia.org/wiki/SOAP_%28protocol%29" target="_blank"&gt;SOAP&lt;/a&gt; envelope appears so that we can test the webservice method.&lt;/p&gt;&lt;p align="center"&gt;&lt;img title="soapUI Request 1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="371" alt="soapUI Request 1" src="http://lh4.ggpht.com/_W1dLiLjFqdw/SXVKi-Mf6QI/AAAAAAAAAeA/oVqlyzZk4kU/soapUIRequest1%5B9%5D.png?imgmax=800" width="477" border="0" /&gt; &lt;/p&gt;&lt;p&gt;The problem now was that I had a file called “input.txt” with only the Ids – each one in its proper line. The XML of the SOAP envelope expect that each id be passed in the format: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;?&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;p&gt;For example, &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;7&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;p&gt;As we can observe, my input data don’t fit the pattern required by the XML.&lt;/p&gt;&lt;p&gt;To put my data in conformity with the XML I created a small but useful application called LinePrefixerSuffixer that receives the name of an input file containing the the initial data, the text to be “prefixed” in the start of each line, the text to be “suffixed” in the end of each line of the file and the name of the output file.&lt;/p&gt;&lt;p&gt;So for example, to comply with the above pattern, I’d call the console application with:&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New" size="2"&gt;LinePrefixerSuffixer input.txt “&amp;lt;ns:long&amp;gt;” “&amp;lt;/ns:long&amp;gt;” output.txt&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Let’s say I have a file called input.txt with 1000 numbers in the same directory of the LinePrefixerSuffixer.exe executable.&lt;/p&gt;&lt;p&gt;Each line of the input.txt file has a number as:&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;1      &lt;br /&gt;
2       &lt;br /&gt;
3       &lt;br /&gt;
4       &lt;br /&gt;
5       &lt;br /&gt;
6       &lt;br /&gt;
7       &lt;br /&gt;
.       &lt;br /&gt;
.       &lt;br /&gt;
.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Running the above command line in the command prompt I’d get a file called output.txt with each line now in the format I want, that is:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;2&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;3&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;4&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;5&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;6&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;7&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ns:long&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;. 
. 
.&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;font face="Courier New"&gt;&lt;img title="Line Prefixer Suffixer" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="477" alt="Line Prefixer Suffixer" src="http://lh3.ggpht.com/_W1dLiLjFqdw/SXVKj42O8BI/AAAAAAAAAeE/sOmnEFQlxfQ/LinePrefixerSuffixer%5B5%5D.png?imgmax=800" width="517" border="0" /&gt; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;The C# code of the app is as follow:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Linq;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.IO;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;LinePrefixerSuffixer
{
    &lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Program
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color: blue"&gt;try
            &lt;/span&gt;{
                &lt;span style="color: green"&gt;// Read in all lines of the file using query expression (LINQ).
                // I &amp;quot;prefix&amp;quot; the start of each line with the content of args[1] and
                // &amp;quot;suffix&amp;quot; the end of each line with the content of args[2].
                &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; fileLines = &lt;span style="color: blue"&gt;from &lt;/span&gt;line &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;File&lt;/span&gt;.ReadAllLines(args[0])
                                                &lt;span style="color: blue"&gt;select &lt;/span&gt;args[1] + line + args[2];

                &lt;span style="color: green"&gt;// Writing the prefixed and suffixed file lines to a file named with the content of args[3].
                &lt;/span&gt;&lt;span style="color: #2b91af"&gt;File&lt;/span&gt;.WriteAllLines(args[3], fileLines.ToArray());

                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Operation done.&amp;quot;&lt;/span&gt;);
            }
            &lt;span style="color: blue"&gt;catch&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Exception &lt;/span&gt;e)
            {
                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Use: LinePrefixerSuffixer &amp;lt;input.txt&amp;gt; prefix suffix &amp;lt;output.txt&amp;gt;&amp;quot;&lt;/span&gt;);
            }
        }
    }
}&lt;/pre&gt;&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Now I can pass the content of the output.txt file to soapUI without worrying about having to manually prefix/suffix each line of my input.txt file:&lt;/p&gt;&lt;p align="center"&gt;&lt;img title="soapUI Request 1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="499" alt="soapUI Request 1" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SXVKktoZaZI/AAAAAAAAAeI/OdUeHj5a4vM/soapUIRequest2%5B5%5D.png?imgmax=800" width="462" border="0" /&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Summary      &lt;br /&gt;
&lt;/strong&gt;In this post we saw how to build a simple but powerful application that prefixes and suffixes each line of a file.&lt;/p&gt;&lt;p&gt;We’ve used concepts related to file handling and LINQ and with only 4 lines of code we could manage to accomplish the task.&lt;/p&gt;&lt;p&gt;I think this shows how powerful modern programming languages as C# enables a clean and beautiful coding experience.&lt;/p&gt;&lt;p&gt;Hope this helps.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Visual Studio C# Console Application      &lt;br /&gt;
&lt;/strong&gt;You can get the Microsoft Visual Studio Project and the app executable at:&lt;/p&gt;&lt;p&gt;&lt;a href="http://leniel.googlepages.com/LinePrefixerSuffixer.zip"&gt;http://leniel.googlepages.com/LinePrefixerSuffixer.zip&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note: As this program uses LINQ, you must have Microsoft .NET Framework 3.5 runtime libraries installed on you computer. You can get it at:&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=333325fd-ae52-4e35-b531-508d977d32a6&amp;amp;DisplayLang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=333325fd-ae52-4e35-b531-508d977d32a6&amp;amp;DisplayLang=en" target="_blank"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=333325fd-ae52-4e35-b531-508d977d32a6&amp;amp;DisplayLang=en&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;References      &lt;br /&gt;
&lt;/strong&gt;[1] soapUI - the Web Services Testing tool. Available at &amp;lt;&lt;a href="http://www.soapui.org" target="_blank"&gt;http://www.soapui.org&lt;/a&gt;&amp;gt;. Accessed on January 20, 2009.&lt;/p&gt;&lt;p&gt;[2] &lt;a href="http://dotnetperls.com/Content/About.aspx" target="_blank"&gt;Sam Allen&lt;/a&gt;. File Handling - C#. Available at &amp;lt;&lt;a href="http://dotnetperls.com/Content/File-Handling.aspx" target="_blank"&gt;http://dotnetperls.com/Content/File-Handling.aspx&lt;/a&gt;&amp;gt;. Accessed on January 20, 2009.&lt;/p&gt;&lt;p&gt;[3] LINQ. The LINQ Project. Available at &amp;lt;&lt;a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx" target="_blank"&gt;http://msdn.microsoft.com/en-us/netframework/aa904594.aspx&lt;/a&gt;&amp;gt;. Accessed on January 20, 2008.&lt;/p&gt;&lt;p&gt;[4] LINQ. Language Integrated Query. Available at &amp;lt;&lt;a href="http://www.leniel.net/2008/01/linq-language-integrated-query.html" target="_blank"&gt;http://www.leniel.net/2008/01/linq-language-integrated-query.html&lt;/a&gt;&amp;gt;. Accessed on January 20, 2008.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-2088316658637339884?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gcWoHtSBWpQwDXp6LgxghejL_aM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gcWoHtSBWpQwDXp6LgxghejL_aM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gcWoHtSBWpQwDXp6LgxghejL_aM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gcWoHtSBWpQwDXp6LgxghejL_aM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=viPXHGmZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=0uulK4qi"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=0uulK4qi" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=Er8V0IvG"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=Er8V0IvG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=bejUUkam"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=bejUUkam" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=6hrrRR7C"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=ohxMZWuQ"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/N6Jo2ODvo88" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/2088316658637339884/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/01/line-prefixer-suffixer-c-console-app.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/2088316658637339884?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/2088316658637339884?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/N6Jo2ODvo88/line-prefixer-suffixer-c-console-app.html" title="Line prefixer suffixer in C#" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/01/line-prefixer-suffixer-c-console-app.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUINQXY8eip7ImA9WxVRGEg.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-6051430589889574387</id><published>2009-01-18T02:53:00.002-02:00</published><updated>2009-01-25T02:26:30.872-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-25T02:26:30.872-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="technology" /><category scheme="http://www.blogger.com/atom/ns#" term="Chemtech" /><category scheme="http://www.blogger.com/atom/ns#" term="job" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><category scheme="http://www.blogger.com/atom/ns#" term="Compliments" /><category scheme="http://www.blogger.com/atom/ns#" term="Brazil" /><title>Chemtech compliments newly graduated engineers</title><content type="html">&lt;p&gt;Last Friday, January 16th, I was complimented by &lt;a href="http://www.chemtech.com.br" target="_blank"&gt;Chemtech&lt;/a&gt;. The company gave compliments to all employees that finished their college course in 2007/2008.&lt;/p&gt;  &lt;p align="center"&gt;&lt;a title="Chemtech compliments engineers by leniel macaferi, on Flickr" href="http://www.flickr.com/photos/leniel/3222734839/" target="_blank"&gt;&lt;img height="333" alt="Chemtech compliments engineers" src="http://farm4.static.flickr.com/3083/3222734839_034c456626.jpg" width="500" /&gt;&lt;/a&gt;&amp;#160; &lt;br /&gt;&lt;em&gt;The &lt;a href="http://en.wikipedia.org/wiki/Computer_engineer" target="_blank"&gt;computer engineers&lt;/a&gt; including me beside Rubião from right to left.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;We got together at the 23rd floor of Rio de Janeiro’s office where &lt;a href="http://www.gptw.com.br/encontro/site_v1/html/wf052_luizeduardo.asp" target="_blank"&gt;Luiz Eduardo Ganem Rubião&lt;/a&gt; (CEO and founder of Chemtech) talked a little bit about the company’s perspectives giving us some insight related to life, economy, the job market and ongoing and future projects.&lt;/p&gt;  &lt;p&gt;The way Rubião thinks about life subjects, mainly being an optimist is how I face the day to day. There’s no time to be wasted with illusions and we should always think positive. Doing so we’ll for sure harvest good fruits.&lt;/p&gt;  &lt;p&gt;The following is the transcription of the letter I received with a present (a book of my area of specialization - computer engineering) …&lt;/p&gt;  &lt;p align="left"&gt;Rio de Janeiro, January 16th, 2009&lt;/p&gt;  &lt;p align="left"&gt;Dear Leniel Braz de Oliveira Macaferi,&lt;/p&gt;  &lt;p align="left"&gt;Young people like you represent the future of technology. With your know how you can contribute to Brazil’s development so that it stands out in the worldwide technology. It is in the knowledge, in technology that a differential arises.&lt;/p&gt;  &lt;p align="left"&gt;Chemtech is proud to have been with you in your first steps to engineering and for us still being together. It’s with satisfaction that today we call you an engineer! A Chemtecheano engineer, a Brazilian engineer.&lt;/p&gt;  &lt;p align="left"&gt;We’re together in this journey that starts with your graduation. Success!&lt;/p&gt;  &lt;p align="left"&gt;A strong hug from the Chemtech family.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-6051430589889574387?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9asQgnQEEXb_Yf_GHUCGnwXLkrA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9asQgnQEEXb_Yf_GHUCGnwXLkrA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9asQgnQEEXb_Yf_GHUCGnwXLkrA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9asQgnQEEXb_Yf_GHUCGnwXLkrA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=1RU7IVOK"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=xOmd6afY"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=xOmd6afY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=uAehndGb"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=uAehndGb" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=8ejp8qog"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=8ejp8qog" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=6pQ2yXoN"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=WAq02O9O"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/XgCZ9fTKUMg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/6051430589889574387/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2009/01/chemtech-compliments-engineers.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6051430589889574387?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/6051430589889574387?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/XgCZ9fTKUMg/chemtech-compliments-engineers.html" title="Chemtech compliments newly graduated engineers" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2009/01/chemtech-compliments-engineers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EHSXszfip7ImA9WxJQEUw.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-8010048599470189470</id><published>2008-11-30T00:16:00.001-02:00</published><updated>2009-05-23T20:00:38.586-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-23T20:00:38.586-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate Query Analyzer" /><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="query language" /><title>NHibernate Query Analyzer + ActiveRecord</title><content type="html">&lt;p&gt;It's been a long time since I last posted something.&lt;/p&gt;  &lt;p&gt;My &lt;a href="http://lenielmacaferi.blogspot.com/2008/08/arriving-at-chemtech.html" target="_blank"&gt;work at Chemtech&lt;/a&gt; is really motivating and is keeping me busy. Well, I think this is good because I really like to work and while I help my team building new projects, we as a group contribute in some way to the world.&lt;/p&gt;  &lt;p&gt;Each day I learn new things and the tip I want to pass ahead is related to a new tool I knew a few days ago. It's called &lt;a href="http://ayende.com/projects/nhibernate-query-analyzer.aspx" target="_blank"&gt;NHibernate Query Analyzer&lt;/a&gt;. NHQA helps a lot while working in a project with a relational database that makes use of &lt;a href="http://www.hibernate.org/" target="_blank"&gt;NHibernate&lt;/a&gt; as the persistence manager.&lt;/p&gt;  &lt;p&gt;I was having a problem getting NHQA to work with a business data layer constructed with the help of &lt;a href="http://www.castleproject.org/activerecord/index.html" target="_blank"&gt;ActiveRecord&lt;/a&gt; - I searched the Internet for a path that would led me in the right direction and after solving small errors I got NHQA working with a proper configuration file. Below I post the content of the file so that you can get a sense of what must be done with the initial configuration of NHQA:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configSections&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;section &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;activerecord&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;section&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configSections&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;activerecord&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;config&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;hibernate.show_sql&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;

      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;hibernate.connection.driver_class&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernate.Driver.OracleClientDriver&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;

      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;hibernate.connection.provider&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernate.Connection.DriverConnectionProvider&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;

      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;hibernate.dialect&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;NHibernate.Dialect.OracleDialect&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;

      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;hibernate.connection.connection_string&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Data Source=YOUR DATA SOURCE;User ID=YOUR USER ID;Password=YOUR PASSWORD;&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;config&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;activerecord&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;See a screenshot of NHQA with a business data layer DLL plus the app.config file:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="NHQAMainForm" border="0" alt="NHQAMainForm" src="http://lh6.ggpht.com/_W1dLiLjFqdw/STH3cxMldnI/AAAAAAAAAcg/WLY3NGFANkQ/NHQAMainForm%5B19%5D.png?imgmax=800" width="502" height="305" /&gt;&lt;/p&gt;

&lt;p&gt;To get it going, just hit the Build Project button and once it’s built, just open a new Query (ctrl + Q) and start visualizing the SQL generated from the Hibernate Query Language (&lt;a href="http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html" target="_blank"&gt;HQL&lt;/a&gt;) you type. Besides this great feature you can also view the results from an HQL query in both tabular and object graph formats.&lt;/p&gt;

&lt;p&gt;Get a copy of the app.config file &lt;a href="http://leniel.googlepages.com/NHQAapp.config"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-8010048599470189470?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hDJSe7fIs2Vl55nUZYTbcCFCuXU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hDJSe7fIs2Vl55nUZYTbcCFCuXU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hDJSe7fIs2Vl55nUZYTbcCFCuXU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hDJSe7fIs2Vl55nUZYTbcCFCuXU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=pqi5EaKq"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=X8g3yBNm"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=X8g3yBNm" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=zd6IejOE"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=zd6IejOE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=w4aB65cR"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=w4aB65cR" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=4biNstvI"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=9a79BSgH"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/rcIQFNhNgPI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/8010048599470189470/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2008/11/nhibernate-query-analyzer-activerecord.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/8010048599470189470?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/8010048599470189470?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/rcIQFNhNgPI/nhibernate-query-analyzer-activerecord.html" title="NHibernate Query Analyzer + ActiveRecord" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.leniel.net/2008/11/nhibernate-query-analyzer-activerecord.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcMR3s7fyp7ImA9WxRTEk8.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-1115078642980355239</id><published>2008-08-31T03:06:00.001-03:00</published><updated>2008-08-31T19:51:26.507-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-31T19:51:26.507-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Chemtech" /><category scheme="http://www.blogger.com/atom/ns#" term="job" /><title>Arriving at Chemtech</title><content type="html">&lt;p&gt;&lt;a href="http://www.chemtech.com.br/lportal/web/guest/home?p_p_id=82&amp;amp;p_p_action=1&amp;amp;p_p_state=normal&amp;amp;p_p_mode=view&amp;amp;p_p_col_pos=2&amp;amp;p_p_col_count=5&amp;amp;_82_struts_action=%2Flanguage%2Fview&amp;amp;_82_redirect=%2Flportal%2Fweb%2Fguest%2Fhome&amp;amp;languageId=en_US" target="_blank"&gt;&lt;img class="imgleft" height="68" alt="chemtechlogo" src="http://lh4.ggpht.com/leniel/SLo0_BpdAzI/AAAAAAAAAXQ/yTS7oAtjGio/chemtechlogo%5B5%5D.jpg?imgmax=800" width="240" border="0" /&gt;&lt;/a&gt;It's with great pleasure that I'm writing this post. I finally got a job after 5 months of eager expectation. I'm going to work at &lt;a href="http://www.chemtech.com.br/lportal/web/guest/home?p_p_id=82&amp;amp;p_p_action=1&amp;amp;p_p_state=normal&amp;amp;p_p_mode=view&amp;amp;p_p_col_pos=2&amp;amp;p_p_col_count=5&amp;amp;_82_struts_action=%2Flanguage%2Fview&amp;amp;_82_redirect=%2Flportal%2Fweb%2Fguest%2Fhome&amp;amp;languageId=en_US" target="_blank"&gt;Chemtech&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I've been sending lots of resumes to almost all IT related companies from Brazil and to some international companies since I got out of &lt;a href="http://lenielmacaferi.blogspot.com/2008/03/new-job-at-ita-petrobras.html"&gt;ITA-Petrobras&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Fortunately, on July 10 I received an e-mail from Chemtech asking for my grade transcripts related to the computer engineering course. I then sent the transcripts to them on July 30. On August 28 I was invited to participate in a in house interview that would take place the next day. On August 29 I went to Rio de Janeiro. During the interview conducted by two managers and one software developer, a job proposal for a Junior Analyst position was made and I accepted. The area of specialty is computer engineering.&lt;/p&gt;  &lt;p&gt;I dreamed about getting a job in a top technology company. From the moment I began the Computer Engineering course in 2003 my constant thought has been to get a position in a company that is attractive.&lt;/p&gt;  &lt;p&gt;Today what was a dream is now pure reality.&lt;/p&gt;  &lt;p&gt;I'm extremely motivated to be a part of the Chemtech team!&lt;/p&gt;  &lt;p&gt;I thank Jesus Christ for helping me to achieve this goal. After all, it's for Him that I live! :)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-1115078642980355239?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/itQftg_9Bf7c3YuIMgo8n8vo9ZQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/itQftg_9Bf7c3YuIMgo8n8vo9ZQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/itQftg_9Bf7c3YuIMgo8n8vo9ZQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/itQftg_9Bf7c3YuIMgo8n8vo9ZQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=LyL6NFGF"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=ZyggW9wx"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=ZyggW9wx" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=tcABBke3"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=tcABBke3" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=iJRUddAS"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=iJRUddAS" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=kbepfe5U"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=RXHok0Qs"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/lEA5m-NAyWs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/1115078642980355239/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2008/08/arriving-at-chemtech.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/1115078642980355239?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/1115078642980355239?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/lEA5m-NAyWs/arriving-at-chemtech.html" title="Arriving at Chemtech" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2008/08/arriving-at-chemtech.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UHSH85cSp7ImA9WxVSFUs.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-2847545542519347053</id><published>2008-07-10T12:58:00.001-03:00</published><updated>2009-01-10T02:20:39.129-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-10T02:20:39.129-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="oi" /><category scheme="http://www.blogger.com/atom/ns#" term="job interview" /><title>Systems Analyst job interview at Oi</title><content type="html">&lt;p&gt;&lt;a href="http://www.oi.com.br" target="_blank"&gt;&lt;img class="imgright" title="" height="77" alt="" src="http://lh5.ggpht.com/_W1dLiLjFqdw/SWgcXCvgukI/AAAAAAAAAdA/9lwd1ArrYck/LogoOi%5B1%5D.gif?imgmax=800" width="84" border="0" /&gt;&lt;/a&gt;On Tuesday, July 8, I went to Praia de Botafogo in Rio de Janeiro to take part in a &lt;a href="http://en.wikipedia.org/wiki/Job_interview" target="_blank"&gt;job interview&lt;/a&gt; scheduled for 2:00 P.M. I arrived there 1:45 P.M. During the trip (2 hours) the bus got backed up because there were some construction being carried out at &lt;a href="http://en.wikipedia.org/wiki/Via_Dutra"&gt;Via Dutra highway&lt;/a&gt;. I thought I wouldn't get there on time, but fortunately everything went OK. &lt;/p&gt;  &lt;p&gt;As I mentioned in the post &lt;a href="http://lenielmacaferi.blogspot.com/2008/06/network-analyst-job-interview-at-oi.html" target="_blank"&gt;Network Analyst job interview at Oi&lt;/a&gt;, I participated in the first interview for a &lt;a href="http://en.wikipedia.org/wiki/Network_Analyst" target="_blank"&gt;Network Analyst&lt;/a&gt; position.&lt;/p&gt;  &lt;p&gt;On Monday, June 30, I got a phone call from Oi's HR department offering me an interview for a &lt;a href="http://en.wikipedia.org/wiki/Systems_Analyst" target="_blank"&gt;Systems Analyst&lt;/a&gt; position. I told the girl called Sofia that I had already participated in an interview there and that I'd like to know the feedback first so that I could decide if I wanted to go for a second interview this time regarding a different position. She then told me that the systems analyst position would better fit my skills and that I would work directly in the &lt;a href="http://en.wikipedia.org/wiki/Information_technology" target="_blank"&gt;IT&lt;/a&gt; department. The department is responsible for the development and improvement of the tools. She asked me a few questions (technical skills) and said I wouldn't need to go for the first interview again with the HR department. The most intriguing question she asked was: How much do you wanna earn? I answered that this question is a filter and that if I said a high value they wouldn't let me go ahead in the recruiting process. She then took the time to say to me how much Oi could pay me (she said she was opening an exception for telling me the value they could pay). I then agreed with the value since the wage plus the benefits would sum a great amount for someone who is just beginning his professional life. Sofia said that she would forward my name for the second round of interviews (the whole process is comprised of 3 interviews). This second interview is the one that would assess my technical skills. I asked when would this interview take place. She answered that there was no scheduled time.&lt;/p&gt;  &lt;p&gt;On Monday, July 7, I got a phone call from the manager of the area I would work for. He is called Juscelino. I was being called for an interview on the next day.&lt;/p&gt;  &lt;p&gt;I was interviewed by three guys. The other two are professionals already working on the IT department. Juscelino conducted the interview. I was asked about how I started my career in the IT area. I told the complete story starting in August 1997 when I first got a computer then passing to the computer technician course from 1999 to 2002 and then the computer engineering course from 2003 to 2007. He asked some questions about my experience on the previous jobs I had and other questions related to technical skills such as &lt;a href="http://en.wikipedia.org/wiki/Object-oriented_programming" target="_blank"&gt;object oriented programming&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Databases" target="_blank"&gt;databases&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" target="_blank"&gt;UML&lt;/a&gt;, etc. The focus on this job will be &lt;a href="http://en.wikipedia.org/wiki/PHP" target="_blank"&gt;PHP&lt;/a&gt; + &lt;a href="http://en.wikipedia.org/wiki/MySQL" target="_blank"&gt;MySQL&lt;/a&gt;. One thing that I emphasized is that if you know well one programming language and a database technology it gets easy to learn a new one, that is, you already know the basic concepts and that the rest of the work is to manage to learn the intrinsic syntax of the different programming language or database technology. At the end Juscelino asked me if I had any doubts regarding the technical details of the job. I said no. Then they asked me non technical questions as: What's your hobby?, Where do you see yourself in the future? Things like that. Juscelino ended the interview and said or no (I don't remember exactly) that I would be contacted for the last interview. While I was heading to the exit door he said: we'll talk more latter. I think this is a good signal. The interview lasted only 15-20 minutes.&lt;/p&gt;  &lt;p&gt;Let's see what happens next. If it happens I'll post here some notes about the third part of the interview process.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-2847545542519347053?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p1ddCENUeX5W_rBZ3KVUBV1fiJI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p1ddCENUeX5W_rBZ3KVUBV1fiJI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p1ddCENUeX5W_rBZ3KVUBV1fiJI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p1ddCENUeX5W_rBZ3KVUBV1fiJI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=uhhQE54A"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=tTuXVivU"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=tTuXVivU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=RPDVpZuA"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=RPDVpZuA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=LIXjhi8n"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=LIXjhi8n" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=0SYXPvYp"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=rf4pHLNo"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/iS7n4-BxQYQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/2847545542519347053/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2008/07/systems-analyst-job-interview-at-oi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/2847545542519347053?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/2847545542519347053?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/iS7n4-BxQYQ/systems-analyst-job-interview-at-oi.html" title="Systems Analyst job interview at Oi" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2008/07/systems-analyst-job-interview-at-oi.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYHRXc8fSp7ImA9WxdWEk0.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-7226002426997441468</id><published>2008-07-04T15:56:00.003-03:00</published><updated>2008-07-04T17:25:34.975-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-04T17:25:34.975-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="technology" /><category scheme="http://www.blogger.com/atom/ns#" term="society" /><category scheme="http://www.blogger.com/atom/ns#" term="nanotechnology" /><category scheme="http://www.blogger.com/atom/ns#" term="computer engineering bachelor's degree" /><title>Nanotechnology and the future of technology</title><content type="html">&lt;img class="imgleft" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="160" alt="Nanotech" src="http://lh3.ggpht.com/leniel/SG6Fdr0iF3I/AAAAAAAAAXM/ke9VCzyTGU4/Nanotech%5B18%5D.jpg?imgmax=800" width="240" border="0" /&gt; &lt;a href="http://en.wikipedia.org/wiki/Nanotechnology" target="_blank"&gt;Nanotechnology&lt;/a&gt;&lt;/a&gt; refers to a field of applied science and technology whose theme is the control of matter on the atomic and molecular scale, generally 100 nanometers (billionths of meters) or smaller, and the fabrication of devices or materials that lie within that size range. Is any technology that is based on the placement or manipulation of single atoms.   &lt;br /&gt;  &lt;br /&gt;Many innovations will come to light, which will make extensive use of nanotechnology. We know little about the natural phenomena that are surrounding us. In truth everything is already made and is near us, but we just can&amp;#8217;t see because we need in the course of time develop our science and create new tools that will make us capable of discovering new chemical elements.   &lt;br /&gt;  &lt;br /&gt;There is a famous maxim from French chemist &lt;a href="http://en.wikipedia.org/wiki/Lavoisier" target="_blank"&gt;Lavoisier&lt;/a&gt; that is:   &lt;br /&gt;  &lt;blockquote class="tr_bq"&gt;In nature nothing is lost, nothing is created, everything is transformed.&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;We are in a constant process of evolution and development.     &lt;br /&gt;    &lt;br /&gt;With the discovering of new chemical elements and inherent natural phenomena, we&amp;#8217;ll be capable of creating new types of materials what on the other hand will bring over more and more discoveries. Discoveries lead to innovations.     &lt;br /&gt;    &lt;br /&gt;If we think that we are working with minuscule particles and that the smaller particle hasn&amp;#8217;t been discovered yet, we can assert that we have a lot to learn. In truth it wasn&amp;#8217;t long since that the first chemical elements were discovered.     &lt;br /&gt;    &lt;br /&gt;Now it&amp;#8217;s interesting to catch sight of how many nice opportunities there are to use nanotechnology. As an example: the manufacturing process of computer &lt;a href="http://en.wikipedia.org/wiki/Processors" target="_blank"&gt;processors&lt;/a&gt;. I just can&amp;#8217;t wait to have a super fast computer. To that end it&amp;#8217;s necessary that nanotechnology evolves. For a faster processor it is necessary that billions of small electrical components called &lt;a href="http://en.wikipedia.org/wiki/Transistor" target="_blank"&gt;transistors&lt;/a&gt; be placed in a microchip. The smaller the transistors the greater amount of them can be put in a single chip. There&amp;#8217;s a law specific to this subject called &lt;a href="http://en.wikipedia.org/wiki/Moore%27s_Law" target="_blank"&gt;Moore's law&lt;/a&gt;.     &lt;br /&gt;    &lt;br /&gt;New techniques can also be applied in the medicine field with the development of robots invisible to the human eyes that can flow within the human body fighting against all sorts of diseases.     &lt;br /&gt;    &lt;br /&gt;At last, nanotechnology is a really important and promising technology and I expect that it evolves rapidly for the sake of men&amp;#8217;s well being of course because other forms of use also exists. I won&amp;#8217;t comment about them here. I think that the reader caught what I want to express with this. If not, try to remember about war technologies.     &lt;br /&gt;    &lt;br /&gt;I can foresee that in a time period of 40 years (approximately 2050) we&amp;#8217;ll be in a new baseline and nanotechnology will be a completely forgotten technology. As a matter of fact, it always happens with technologies.     &lt;br /&gt;    &lt;br /&gt;As of the date of this post we already have &lt;a href="http://en.wikipedia.org/wiki/11_nanometer" target="_blank"&gt;11 nanometers&lt;/a&gt; technology. For comparison, the processor &lt;a href="http://en.wikipedia.org/wiki/Core_Duo" target="_blank"&gt;Intel Core Duo&lt;/a&gt; that is the one I use today is manufactured with a &lt;a href="http://en.wikipedia.org/wiki/65_nm" target="_blank"&gt;65 nanometers&lt;/a&gt; technology.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4926735770070291800-7226002426997441468?l=www.leniel.net'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-6PXsUIe0KeDHhxjbJN9UWOxxns/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-6PXsUIe0KeDHhxjbJN9UWOxxns/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-6PXsUIe0KeDHhxjbJN9UWOxxns/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-6PXsUIe0KeDHhxjbJN9UWOxxns/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/leniel?a=sr45dA8s"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=Xq0Pp4mX"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=Xq0Pp4mX" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=8EwAr1Wv"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=8EwAr1Wv" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=IieejYP4"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?i=IieejYP4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=M7sYaMV3"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/leniel?a=56WXcB6x"&gt;&lt;img src="http://feeds.feedburner.com/~f/leniel?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/leniel/~4/B7L8bdcI1bo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.leniel.net/feeds/7226002426997441468/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.leniel.net/2008/07/nanotechnology-future-of-technology.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/7226002426997441468?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4926735770070291800/posts/default/7226002426997441468?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/leniel/~3/B7L8bdcI1bo/nanotechnology-future-of-technology.html" title="Nanotechnology and the future of technology" /><author><name>Leniel Macaferi</name><uri>http://www.blogger.com/profile/17950821674268154143</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03351735922737092016" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.leniel.net/2008/07/nanotechnology-future-of-technology.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MMQn08cCp7ImA9WxdXFkU.&quot;"><id>tag:blogger.com,1999:blog-4926735770070291800.post-7672931231953590148</id><published>2008-06-27T19:47:00.002-03:00</published><updated>2008-06-28T17:38:03.378-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-28T17:38:03.378-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="public contest" /><category scheme="http://www.blogger.com/atom/ns#" term="Petrobras" /><category scheme="http://www.blogger.com/atom/ns#" term="system analyst" /><title>Petrobras 2008 public contest - Junior System Analyst</title><content type="html">&lt;style id="Classifica&amp;#231;&amp;#227;o_10089_Styles"&gt;

&lt;!--table
	{mso-displayed-decimal-separator:"\.";
	mso-displayed-thousand-separator:"\,";}
.xl6315763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	mso-background-source:auto;
	mso-pattern:auto;
	white-space:nowrap;}
.xl6415763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	mso-background-source:auto;
	mso-pattern:auto;
	white-space:normal;}
.xl6515763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:11.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	mso-background-source:auto;
	mso-pattern:auto;
	white-space:normal;}
.xl6615763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#ddd9c3;
	mso-pattern:black none;
	white-space:normal;}
.xl6715763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#c5d9f1;
	mso-pattern:black none;
	white-space:normal;}
.xl6815763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#f2dddc;
	mso-pattern:black none;
	white-space:normal;}
.xl6915763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#e5e0ec;
	mso-pattern:black none;
	white-space:normal;}
.xl7015763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#fde9d9;
	mso-pattern:black none;
	white-space:normal;}
.xl7115763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#ffffcc;
	mso-pattern:black none;
	white-space:normal;}
.xl7215763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#f2dddc;
	mso-pattern:black none;
	white-space:nowrap;}
.xl7315763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#ccffcc;
	mso-pattern:black none;
	white-space:normal;}
.xl7415763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:left;
	vertical-align:bottom;
	background:#f2f2f2;
	mso-pattern:black none;
	white-space:normal;}
.xl7515763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#ccffcc;
	mso-pattern:black none;
	white-space:normal;}
.xl7615763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#ddd9c3;
	mso-pattern:black none;
	white-space:normal;}
.xl7715763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#c5d9f1;
	mso-pattern:black none;
	white-space:normal;}
.xl7815763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#e5e0ec;
	mso-pattern:black none;
	white-space:normal;}
.xl7915763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#ffffcc;
	mso-pattern:black none;
	white-space:normal;}
.xl8015763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#f2dddc;
	mso-pattern:black none;
	white-space:normal;}
.xl8115763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#fde9d9;
	mso-pattern:black none;
	white-space:normal;}
.xl8215763
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:windowtext;
	font-size:10.0pt;
	font-weight:700;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:center;
	vertical-align:middle;
	background:#f2f2f2;
	mso-pattern:black none;
	white-space:normal;}
--&gt;&lt;/style&gt;&lt;a href="http://www.petrobras.com" target="_blank"&gt;&lt;img class="imgright" src="http://www2.petrobras.com.br/minisite/marcaspetrobras/images/generico/thumb/thumb_petrobrashc.gif" /&gt;&lt;/a&gt;   &lt;p&gt;On June 7 I went to Rio de Janeiro to take a test on the next day regarding a &lt;a href="http://en.wikipedia.org/wiki/Public_contest" target="_blank"&gt;public contest&lt;/a&gt; where I was disputing one of 36 vacancies for a Junior Systems Analyst - Infrastructure position at &lt;a href="http://www.petrobras.com" target="_blank"&gt;Petrobras&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The test started at 9:00 A.M. and ended at 1:00 P.M and took place at &lt;a href="http://www.estacio.br/campus/presidente_vargas/conheca.asp" target="_blank"&gt;Estácio de Sá university - Campus Uruguaiana&lt;/a&gt; at Presidente Vargas Avenue that is located downtown. I stayed at a hotel called Planalto. It is located near the place where I did the test.&lt;/p&gt;  &lt;p&gt;Petrobras is one of the major companies of the world. As of May 19, Petrobras became the world's sixth-largest company by market value. Its market value was $295.6 billion. Microsoft for example has a market value of $274.0 billion. You can see more details reading this new at Bloomberg site: &lt;a href="http://www.bloomberg.com/apps/news?sid=afc6lxRruQ9g&amp;amp;pid=20601086" target="_blank"&gt;Petrobras Tops Microsoft, Is Sixth-Biggest Company&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Petrobras's field of operation has a high demand because its principal product is petroleum. Yesterday the oil barrel achieved the highest price in history as can be read in &lt;a href="http://money.cnn.com/2008/06/26/markets/oil/index.htm?eref=edition" target="_blank"&gt;Oil sets record above $140 a barrel on supply concerns&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Getting back to the public contest. Petrobras's test is in my humble opinion one of the hardest ones in Brazil in my area of specialization. Maybe it is the hardest one. :-) This was the second time that I participated in such public contests.&lt;/p&gt;  &lt;p&gt;An organizing institution is responsible for the test creation and collection of the registration tax. The organizing institution responsible for the first test I did in 2007 was &lt;a href="http://www.cespe.unb.br/" target="_blank"&gt;CESPE&lt;/a&gt; and this time the organizing institution was &lt;a href="http://www.cesgranrio.org.br/" target="_blank"&gt;CESGRANRIO&lt;/a&gt;. I had to pay R$ 40,00 Brazilian Reais that is approximately $ 25,00 for the registration tax. I'm considering $1 dollar = R$ 1.60 as of the date of this post.&lt;/p&gt;  &lt;p&gt;The test was comprised of 70 questions in the multiple choice form. From these 20 questions were about basic knowledge (BK) (10 Portuguese questions and 10 English questions). The other 50 questions were about specific knowledge (SK) related to system analysis - infrastructure.&lt;/p&gt;  &lt;p&gt;The content that should be studied is described in the following table:&lt;/p&gt;  &lt;div id="Ementa_15763" align=center x:publishsource="Excel"&gt;  &lt;table border=0 cellpadding=0 cellspacing=0 width="100%" style='border-collapse:collapse;'&gt;  &lt;col class=xl6515763&gt;  &lt;col class=xl6415763&gt;  &lt;tr class=xl6315763&gt;  &lt;td rowspan=9 class=xl7715763  &gt;Computer Network and Distributed Systems&lt;/td&gt;  &lt;td class=xl6715763&gt;Computer Network Architectures&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;Topologies&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;Connection and Transmission devices&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;QOS&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;ISO OSI model&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;TCP/IP Architecture and Protocols&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;TCP/IP Application layer: DNS, FTP, NFS, TELNET, SMTP, HTTP, LDAP, DHCP, IPSEC, SSH, SNMP and NAT&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;Basic notions about IPv6&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6715763&gt;Storage concepts (NAS and SAN)&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td rowspan=4 class=xl7815763  &gt;UNIX Environment&lt;/td&gt;  &lt;td class=xl6915763&gt;Installation and support to  TCP/IP, DHCP, DNS, NIS, CIFS, NFS, network printing services&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl6915763&gt;Installation and configuration of Apache server&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl6915763&gt;Integration with Windows environment&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl6915763&gt;Script languages&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td rowspan=5 class=xl7915763&gt;Microsoft Windows 2000/2003 environment&lt;/td&gt;   &lt;td class=xl7115763&gt;Installation and support to TCP/IP, DHCP, DNS&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763 &gt;  &lt;td class=xl7115763&gt;Active Directory, IIS, Terminal Service&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;  &lt;td class=xl7115763&gt;File services and network printing&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7115763&gt;Integration with Unix environment&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7115763&gt;Script languages&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td rowspan=6 class=xl8015763&gt;Information Security&lt;/td&gt;   &lt;td class=xl7215763&gt;Physical and logical security&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7215763 &gt;Firewall and proxies&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7215763&gt;Cryptography&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7215763&gt;VPN&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7215763 &gt;Malicious software (Virus, Spywares, Rootkit, etc)&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7215763&gt;Intrusion detection systems&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td rowspan=9 class=xl7515763&gt;Computer Architecture and High Performance Computing HPC &lt;/td&gt;   &lt;td class=xl7315763&gt;RISC and CISC architectures&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Processor organization&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Memory organization&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Concurrency concepts, parallelism and distributed computing&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Flynn taxonomy&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Distributed systems architecture: SMP and MPP&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Basic concepts about agglomerate computing (Cluster) and grid computing (Grids)&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Load balancing&lt;/td&gt;  &lt;/tr&gt;  &lt;tr class=xl6315763&gt;   &lt;td class=xl7315763&gt;Performance profiling &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=4 class=xl7615763  &gt;Project Management&lt;/td&gt;   &lt;td class=xl6615763  style=''&gt;Basic concepts&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6615763&gt;Resources allocation&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6615763&gt;Chronogram;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6615763&gt;Analytical structure&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=7 class=xl8115763&gt;Operating Systems&lt;/td&gt;   &lt;td class=xl7015763&gt;OS structure&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7015763&gt;Processor management&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7015763&gt;Memory management&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7015763&gt;File systems&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7015763&gt;Input and Output&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7015763&gt;Basic concepts about compilers&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7015763&gt;RAID&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=9 class=xl8215763&gt;Databases&lt;/td&gt;   &lt;td class=xl7415763&gt;Data independency&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td class=xl7415763&gt;Relational approach&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763&gt;entity-relationship approach&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763&gt;Triggers  and Stored Procedures&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763&gt;SQL language&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763&gt;High availability concepts&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763&gt;Transactions management&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763  &gt;Locks management&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7415763&gt;Performance management&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=5 class=xl7915763&gt;Programming&lt;/td&gt;   &lt;td class=xl7115763&gt;Algorithms and data structures&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7115763&gt;Java code debugging&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7115763&gt;Notions about Software Engineering&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7115763&gt;Markup languages: HTML and XML&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl7115763&gt;Notions about Java programming  (JEE, Servelets, JSP and EJB)&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=2 class=xl7615763&gt;IT Service Management&lt;/td&gt;   &lt;td class=xl6615763&gt;Concepts about the  ITIL® library: Support and service delivery&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6615763&gt;COBIT processes domain&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=3 class=xl7715763&gt;Logical Reasoning&lt;/td&gt;   &lt;td class=xl6715763&gt;Sentential and first order logic&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td  class=xl6715763&gt;Enumeration by resources&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6715763&gt;Counting:   Additive and multiplicative principles&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td rowspan=4 class=xl8015763&gt;Information Security Management&lt;/td&gt;   &lt;td class=xl6815763&gt;General concepts&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6815763&gt;Information security policies&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6815763&gt;Information classification&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td class=xl6815763&gt;Norm ISO 27001:2005&lt;/td&gt;  &lt;/tr&gt;  &lt;![if supportMisalignedColumns]&gt;  &lt;tr height=0 style='display:none'&gt;   &lt;td  style=''&gt;&lt;/td&gt;   &lt;td  style=''&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;![endif]&gt; &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;The questions were graded according to the following table:&lt;/p&gt;  &lt;table class="custom3"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;th valign="top" colspan="2"&gt;         &lt;b&gt;Portuguese language&lt;/b&gt;       &lt;/th&gt;        &lt;th valign="top" colspan="2"&gt;         &lt;b&gt;English language&lt;/b&gt;       &lt;/th&gt;        &lt;th valign="top" colspan="2"&gt;         &lt;b&gt;Specific knowledge&lt;/b&gt;       &lt;/th&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;th valign="top"&gt;         Question       &lt;/th&gt;        &lt;th valign="top"&gt;         Points       &lt;/th&gt;        &lt;th valign="top"&gt;        Question       &lt;/th&gt;        &lt;th valign="top"&gt;         Points       &lt;/th&gt;        &lt;th valign="top"&gt;         Question       &lt;/th&gt;        &lt;th valign="top"&gt;         Points       &lt;/th&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         1 to 10       &lt;/td&gt;        &lt;td valign="top"&gt;         1.0       &lt;/td&gt;        &lt;td valign="top"&gt;        11 to 20       &lt;/td&gt;        &lt;td valign="top"&gt;        1.0       &lt;/td&gt;        &lt;td valign="top"&gt;        21 to 30       &lt;/td&gt;        &lt;td valign="top"&gt;         1.0       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;        &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         31 to 40       &lt;/td&gt;        &lt;td valign="top"&gt;         1.3       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         41 to 50       &lt;/td&gt;        &lt;td valign="top"&gt;         1.6       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         51 to 60       &lt;/td&gt;        &lt;td valign="top"&gt;         1.9       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         &amp;#160;       &lt;/td&gt;        &lt;td valign="top"&gt;         61 to 70       &lt;/td&gt;        &lt;td valign="top"&gt;         2.2       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Despite the difficulty I think I performed well if I take into account that this was my second try.&lt;/p&gt;  &lt;p&gt;Today I got the final result and my final grades were:&lt;/p&gt;  &lt;p&gt;Basic Knowledge = 15 points = 75% of BK test. &lt;/p&gt;  &lt;p&gt;I needed 12 points = 60% of BK test. &lt;/p&gt;  &lt;p&gt;Specific Knowledge = 41.3 points = 51.63% of SK test. &lt;/p&gt;  &lt;p&gt;I needed 48 points = 60% of SK test. &lt;/p&gt;  &lt;p&gt;Result = BK + SK = 15 + 41.3 = 56.3 points &lt;/p&gt;  &lt;p&gt;48 - 41.3 = 6.7 points to pass in the specific knowledge test.&lt;/p&gt;  &lt;p&gt;Bellow I show the grades obtained by the candidates that passed the public contest:&lt;/p&gt;  &lt;div id="Classifica&amp;#231;&amp;#227;o_10089" align="center" x:publishsource="Excel"&gt;   &lt;table style="table-layout: fixed; width: 197pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="262" border="0"&gt;&lt;colgroup&gt;&lt;col class="xl6553510089" style="width: 109pt; mso-width-source: userset; mso-width-alt: 5302" width="145" /&gt;&lt;col class="xl6553510089" style="width: 88pt; mso-width-source: userset; mso-width-alt: 4278" width="117" /&gt;&lt;/colgroup&gt;&lt;tbody&gt;       &lt;tr style="height: 64.5pt; mso-height-source: userset" height="86"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 700; font-size: 11pt; background: #4f81bd; border-left: white 0.5pt solid; width: 109pt; color: white; border-top-style: none; border-bottom: white 1.5pt solid; font-family: calibri; height: 64.5pt; text-decoration: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" width="145" height="86"&gt;Specific Knowledge test grade&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 700; font-size: 11pt; background: #4f81bd; width: 88pt; color: white; border-top-style: none; border-bottom: white 1.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" width="117"&gt;Classification&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;61.5&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;61.4&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;2&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;61.2&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;3&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;59.6&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;4&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;56.4&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;5&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;55.8&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;6&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;55.6&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;7&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;54.8&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;8&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;54.5&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;9&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;54.2&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;10&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;54.1&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;11&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;54.0&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;12&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;53.8&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;13&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;52.6&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;14&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;52.1&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;15&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;51.8&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;16&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;51.4&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;17&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;51.2&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;18&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.9&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;19&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.7&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;20&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.7&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;21&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.7&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;22&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.7&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;23&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.6&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;24&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.5&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;25&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.1&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;26&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.1&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;27&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.0&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;28&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;50.0&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;29&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;49.9&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;30&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;49.9&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;31&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;49.6&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;32&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none" height="20"&gt;49.6&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #b8cce4; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #b8cce4 none; text-underline-style: none; text-line-through: none"&gt;33&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #dbe5f1; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; height: 15pt; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none" height="20"&gt;49.5&lt;/td&gt;          &lt;td class="xl6553510089" style="font-weight: 400; font-size: 11pt; background: #dbe5f1; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri; border-right-style: none; border-left-style: none; text-decoration: none; mso-pattern: #dbe5f1 none; text-underline-style: none; text-line-through: none"&gt;34&lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="height: 15pt" height="20"&gt;         &lt;td class="xl6553510089" style="border-right: white 0.5pt solid; font-weight: 400; font-size: 11pt; background: #b8cce4; border-left: white 0.5pt solid; color: black; border-top-style: none; border-bottom: white 0.5pt solid; font-family: calibri;