Apr 30, 2008
Compiler generator CoCo/R for C#
During the preparation for a project bid for one of my customers I recently came across the CoCo/R compiler generator tool. Coco/R is a compiler generator, which takes an attributed grammar Backus-Naur-Form ( BNF) of a source language and generates a C# (and many other languages) scanner and a parser for this language.
To play around I created a small language that can speak and show message boxes. The grammer .ATG file looks the following:
COMPILER Talk
public System.Speech.Synthesis.SpeechSynthesizer ss = new System.Speech.Synthesis.SpeechSynthesizer();
void Say(string text)
{
ss.Speak(text);
}
void Show(string text)
{
System.Windows.Forms.MessageBox.Show(text);
}
IGNORECASE
// The $L option let you compile directly within your grammar
// You can comment and uncomment the line to fit your development requirements.
$LM
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
CHARACTERS
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
bslash = '\\'.
quote = '"'.
chars = ANY - digit - cr - lf - tab - bslash - quote.
TOKENS
string = quote { chars | digit} quote.
IGNORE cr + lf + tab
PRODUCTIONS
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
Show
=
"Show" string (. Show(t.val); .)
.
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
Say
=
"Say" string (. Say(t.val); .)
.
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
Statement
=
Show | Say
.
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
Statements
=
Statement ';' { Statement ';' }
.
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
Talk
=
Statements
.
END Talk.
Please note the so-called semantic actions, like (. Say(t.val); .) that is executed when the corresponding token is parsed.
The code I had to write was reduced to the following:
private void btnTalk_Click(object sender, RoutedEventArgs e)
{
Parser p = new Parser(this.tbTalk.Text);
p.Parse();
tbOutput.Text = p.errors.count.ToString() + " errors";
}
Nice and easy.
Apr 22, 2008
Microsoft.TeamFoundation.WorkItemTracking.Client
string workItemStore = ConfigurationManager.AppSettings["WorkItemStore"];
store = new WorkItemStore(workItemStore);
to connect to the TFS server and then
WorkItem m_workItem = store.GetWorkItem(int.Parse(this.tbID.Text));
if (m_workItem != null)
{
lblWorkItem.Text = m_workItem.Title;
foreach (Link link in m_workItem.Links)
{
RelatedLink rl = link as RelatedLink;
if (rl != null)
{
WorkItem realtedWorkItem = m_workItem.Store.GetWorkItem(rl.RelatedWorkItemId);
list.Add(realtedWorkItem);
}
}
}
dataGridView1.DataSource = list;
to list the linked work items in a simple grid.
When you want to query for WIs it should be possible to call:
// query retrieves all work items for the specified team project
string wiqlQuery = "SELECT [System.Id], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE [System.TeamProject] = '" + teamProjectName + "' ORDER BY [System.WorkItemType], [System.Id]";
// execute the query and retrieve a collection of workitems
WorkItemCollection workitems = store.Projects[0].Store.Query(wiqlQuery);
// loop through work items
if (workitems.Count > 0)
{
// select first Work Item
retWi = workitems[0];
}
Note: To get rid of the assembly load exception just reference the shared assemblies from the disk path and do not use the GAC ones!