当我使用编译器时,我们必须编写一个简单语言的编译器。我不知道我是否完全按照您的问题中的语言定义进行了操作,或者您已经掌握了多少程度,但这是我们在解析语言时使用的方法。
首先,您需要一个词法分析器类,它只负责获取输入中的下一个标记。这基本上是通过代码进行的,每次调用GetNextToken()
都会返回代码中的下一个字符串。所以说你有下面的代码行:
PROCEDURE sum() RETURN INTEGER;
到GetNextToken()
的第一次调用将返回PROCEDURE
。第二次调用将返回sum
,第三个将返回(
然后)
然后RETURN
,INTEGER
,最后;
现在你需要一个句法分析器。这个想法是,你的语言定义最终应该终止令牌。这里是我的编译语言定义的小SNIPPIT:
<program> -> $UNIT <prog-identifier> $SEMICOLON
<block> $PERIOD
<block> -> [<label-declaration>]
{<variable-dec-sec>}*
{<procedure-declaration>}*
$LEFTBRACE <statement> {$SEMICOLON <statement>}*
$RIGHTBRACE
所以在分析我们调用一个函数Program()
。 Program()
会得到下一个令牌。如果该令牌是UNIT
,我们会得到另一个函数ProgIdentifier()
,它将再次调用GetNextToken()
。 ProgramIdentifier()
会查找标识符类型。看看Program()
,看下一个标记是否为;
。然后拨打Block()
,其工作方式与Program()
相同,然后查看您之后是否有.
。
关键是,在每个结束标记处,例如,;
,您将拥有if
语句。因此,对于Program()
简单的代码可能是这样的:
public int Program()
{
lex.GetNextToken();
if (lex.InternalCode == TokenTable.UNIT)
{
lex.GetNextToken();
ProgIdentifier();
if (lex.InternalCode == TokenTable.SEMICOLON)
{
lex.GetNextToken();
Block();
if (parseErrors)
{
//Drop out into Statement Level Parsing
//Statement Level Parsing just calls Statement() for <statement>
//until you have gone through the entire input.
//The point is to avoid getting many errors if you are missing a
//single token.
StatementLevelParse();
}
if (lex.InternalCode == TokenTable.PERIOD)
{
lex.GetNextToken();
if (lex.EndOfFile)
{
if (!parseFailed)
{
//Success
echo("Success");
}
else
{
echo("Parse Failed");
}
}
else
{
Error(lex.CurrentLine, 200, false, "Expected End Of File: Found " + lex.NextSymbol);
}
}
else
{
//Fail. Expected $PERIOD
Error(lex.CurrentLine, 200, false, "Expected \".\": Found " + lex.NextSymbol);
}
}
else
{
//Fail. Expected $SEMICOLON
Error(lex.CurrentLine, 200, false, "Expected \";\": Found " + lex.NextSymbol);
}
}
else
{
//Fail. Expected $UNIT
Error(lex.CurrentLine, 200, false, "Expected \"UNIT\": Found " + lex.NextSymbol);
}
EchoOutput("LEAVING PROGRAM");
return 0;
}
我现在看到,这是一个很大阅读。我不确定这是否是您的导师希望您采取或不需要的方法,但是如果您了解您的语言,我发现它非常简单易用。我不保证这是做这件事最有效或最有效的方法,只是我需要使用的方法。
我真的很希望我能正确理解你的问题...
我建议你找一本好的编译器设计教科书并阅读它。关于这件事还有一些不错的文章:http://www.pling.org.uk/cs/lsa.html&http://www.cs.huji.ac.il/course/2002/nand2tet/ docs/ch_10_compiler_I.pdf但是你需要做的是定义一个语法,获得代码标记,并开始分析令牌和它们进来的顺序。 – Cheesebaron 2013-03-24 14:13:12