私は翻訳者と通訳者を作るための知識とスキルを持っています。しかし、すべての場合において、私は手書きのパーサーを使用しました。ここで、.NET 上の独自の仮想マシンを介して動作するインタープリターを作成して、そのリーチ API のいずれかを使用できるようにするという素晴らしいアイデアを思いつきました。ILへのコンパイラも登場するかもしれません。私は ANTLR を使用して開発速度を上げ、主に言語と VM コードに集中し、解析には集中しないことにしました。ANTLR - IDE があり、C# のパーサー コードを生成できることをウィキペディアで見つけたので、プログラムを作成するために選択しました。
いくつかの努力の後、コードのコンパイルを強制しました。C# コードは次のとおりです。
using System;
using System.Resources;
using System.Reflection;
using System.Globalization;
using System.Configuration;
using System.IO;
using Antlr.Runtime;
class AgathaInterpretter
{
static ResourceManager rm;
static CultureInfo ci;
static string GetString(string key)
{
try
{
return rm.GetString(key, ci);
}
catch (Exception)
{
return "Resource string not found.";
}
}
public static void Main(string[] args)
{
ci = new CultureInfo(ConfigurationManager.AppSettings["locale"]);
rm = new ResourceManager("Agatha.Messages", Assembly.GetExecutingAssembly());
switch (args.Length)
{
case 0:
Console.WriteLine(GetString("ERROR_COMMAND_LINE_ARGS_ZERO"));
return;
case 1:
break;
default:
Console.WriteLine(GetString("ERROR_COMMAND_LINE_ARGS_GREATER"));
return;
}
StreamReader streamReader;
try
{
streamReader = new StreamReader(args[0]);
}
catch (Exception)
{
Console.WriteLine(GetString("ERROR_SCRIPT_FILE_INACCESSIBLE"));
return;
}
string str = "";
while (!streamReader.EndOfStream)
str += streamReader.ReadLine() + "\n";
Console.WriteLine(str);
ANTLRStringStream Input = new ANTLRStringStream(str);
AgathaLexer Lexer = new AgathaLexer(Input);
CommonTokenStream Tokens = new CommonTokenStream(Lexer);
AgathaParser Parser = new AgathaParser(Tokens);
Parser.prog();
}
}
そして、ここに私の文法があります:
grammar Agatha;
options
{
language=CSharp2;
}
tokens {
PLUS = '+' ;
MINUS = '-' ;
MULT = '*' ;
DIV = '/' ;
LP = '(' ;
RP = ')' ;
SEMICOLON = ';' ;
ASSIGN = '=';
}
public prog: statement+ ;
statement: assignmentExpression | SEMICOLON ;
assignmentExpression : ID ASSIGN additiveExpression SEMICOLON| additiveExpression SEMICOLON ;
additiveExpression: multiplicativeExpression ( ( PLUS | MINUS ) multiplicativeExpression )* ;
multiplicativeExpression: unaryExpression ( ( MULT | DIV ) unaryExpression )* ;
unaryExpression : LP assignmentExpression RP | NUMBER | ID;
NUMBER : (DIGIT)+ ;
WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;
ID : ('a'..'z' |'A'..'Z' )+ ;
fragment DIGIT : '0'..'9' ;
有効なようで、パーサーが生成されます。最初に C# コードを投稿して、さまざまなファイルをロードし、prog() で解析しようとしました。ただし、間違ったソース、例外、コンソールへの出力を提供しても何も起こりません。最初にトレーニングを受けたいのですが、トレーニングを受けることができません。どこが間違っていますか?何が起こっていますか?