Skip to content

Instantly share code, notes, and snippets.

@elleryq
Created February 8, 2012 10:38
Show Gist options
  • Save elleryq/1768037 to your computer and use it in GitHub Desktop.
Save elleryq/1768037 to your computer and use it in GitHub Desktop.
ANTLR expr sample
/*
1. Visit http://www.antlr.org/wiki/display/ANTLR3/Antlr3CSharpReleases and download antlr-dotnet-tool-xxx.7z
2. unzip the 7z file.
3. Create solution in Visual Studio and add the following reference for the project: antlr3.runtime.dll.
4. Copy this file as program.cs
5. In unziped files, you can find antlr3.exe. Use it to generate necessary cs files: antlr3.exe expr.g3.
6. Add generated cs files to project.
7. Create folder 'sample' in the project and add a text file named Expr1.txt
8. Place the follow content in Expr1.txt, then change the property 'Copy to Output Directory' to "Copy always".
1+1
x=2
y=3
x+y
9. Build and run!
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr.Runtime;
namespace expr
{
class Program
{
static int calc(string input)
{
ANTLRStringStream stream = new ANTLRStringStream(input);
var lexer = new exprLexer( stream );
var tokens = new CommonTokenStream(lexer);
var parser = new exprParser( tokens );
var result = parser.expr().value;
return result;
}
static void standardTest()
{
ANTLRFileStream input = new ANTLRFileStream("sample\\Expr1.txt");
var lexer = new exprLexer( input );
var tokens = new CommonTokenStream(lexer);
var parser = new exprParser( tokens );
parser.prog();
var result = parser.expr().value;
Console.WriteLine("Result = {0}", result);
}
static void Main(string[] args)
{
standardTest();
Console.WriteLine("calc( '1+2' )={0}", calc("1+2"));
Console.WriteLine("calc( '100+200' )={0}", calc("100+200"));
Console.WriteLine("calc( '1000+2000' )={0}", calc("1000+2000"));
Console.WriteLine("calc( '10000+20000' )={0}", calc("10000+20000"));
Console.WriteLine("Parse done.");
Console.ReadLine();
}
}
}
grammar expr;
options {
language=CSharp3;
TokenLabelType=CommonToken;
output=AST;
ASTLabelType=CommonTree;
}
@lexer::namespace{expr}
@parser::namespace{expr}
@header {
using System;
}
@members {
/** Map variable name to Integer object holding value */
Dictionary<string, int> memory = new Dictionary<string, int>();
}
public prog: stat+ ;
stat: expr NEWLINE {Console.WriteLine( "{0}", $expr.value);}
| ID '=' expr NEWLINE
{memory.Add($ID.text, Convert.ToInt32($expr.value));}
| NEWLINE
;
public expr returns [int value]
: e=multExpr {$value = $e.value;}
( '+' e=multExpr {$value += $e.value;}
| '-' e=multExpr {$value -= $e.value;}
)*
;
multExpr returns [int value]
: e=atom {$value = $e.value;} ('*' e=atom {$value *= $e.value;})*
;
atom returns [int value]
: INT {$value = Convert.ToInt32($INT.text);}
| ID
{
int v;
if( memory.TryGetValue( $ID.text, out v ) )
$value = v;
else
Console.WriteLine( "undefined variable {0}", $ID.text );
}
| '(' expr ')' {$value = $expr.value;}
;
ID : ('a'..'z'|'A'..'Z')+ ;
INT : '0'..'9'+ ;
NEWLINE:'\r'? '\n' ;
WS : (' '|'\t')+ {Skip();} ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment