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.

No comments:

Post a Comment