我正在为一个C语言(一个更简单的语言)构建一个编译器(不使用任何类似工具的lex或bison),并且已经超越了词法分析器和解析器。 我不确定我做解析器的方式是否正确。因为到目前为止要进行解析,即检查语法是否正确,我根本没有使用链表。 基本上,我的解析器看起来像这样: 假设语法是 -
<program> ::= <program_header> <program_body>
<program_header>::= program <identifier> is
<program_body> ::= (<declaration>;)*
begin
(<statement>;)*
end program
我的程序如下:
parser()
{
char *next_token;
next_token = get_token();
check_for_program(next_token);
}
check_for_program(next_token)
{
check_for_program_header(next_token);
if (header_found)
check_for_program_body();
}...
我基本上都有所有非终端的功能,并在适当的时候调用它们,我正在通过“strcmp”检查关键字。 这种方法好吗?
从这一点来说,如何进行语义分析?我应该从哪里开始构建符号表?
任何有关思考的建议或指针都很棒!非常感谢你
答案 0 :(得分:3)
一个常见且相当简单的方法是创建一个递归下降解析器,即创建与您的语法相对应的函数(您似乎已经开始这样做了):
e.g。
<program> ::= <program_header> <program_body>
<program_header>::= program <identifier> is
<program_body> ::= (<declaration>;)*
会对应像
这样的东西void program()
{
program_header();
program_body();
}
void program_header()
{
char* program_token = get_token();
char* identifier = get_token();
if (identifier==NULL) report_error();
...
}
void program_body()
{
declaration();
...
}
并在每个函数内部进行语义检查。您需要一个符号表,如果您不想处理范围或具有某种符号表堆栈,则该表是全局构造。
答案 1 :(得分:0)
是的,这是解析的一种方式,它被称为Recursive descent parser。这是一种非正式的解析方式,这意味着如果更改语法,则需要更改解析代码。
还有正式的解析方法,如LL和SLR,形式化方法有两个优点:你可以证明解析解析你的语法所定义的内容(这就是为什么它们被称为正式),它们是通用的,你可以编码一次并解析任何兼容的语法。