我在翻译和口译方面有一些知识和技能。但在每种情况下我都使用手写的解析器。现在我有一个好主意,可以在.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()解析它们。但如果我还提供错误的源,没有例外,没有输出到控制台,则没有任何反应。我想先接受一些训练,但不能得到任何训练。我哪里错了?发生了什么事?