将语法转换为 LL(1)
我有这样的语法:
program ::= expr_list
expr_list ::= {LF} [expr {LF {LF} expr}] {LF}
lvalue ::= [expr DOT] NAME
call_param ::= [[NAME COLON] expr {COMMA [NAME COLON] expr}]
func_param ::= [NAME [COLON expr] {COMMA NAME [COLON expr]}]
expr ::= lvalue
| lvalue ASSIGN expr
| expr OPAREN call_param CPAREN
| FUNC func_param LF expr_list END
| IF expr LF expr_list {ELSEIF expr LF expr_list} [ELSE expr_list] ENDIF
| WHILE expr LF expr_list LOOP
| DO expr_list LOOP WHILE expr LF
| INTEGER
我部分地编写了一个递归下降解析器:
void Parser::ntProgram()
{
ntExprList();
}
void Parser::ntExprList()
{
// ???
}
void Parser::ntLvalue()
{
// ???
}
void Parser::ntCallParam()
{
// ???
}
void Parser::ntFuncParam()
{
if (accept(Lexer::NameTok)) {
if (accept(Lexer::ColonTok)) {
ntExpr();
}
}
while (accept(Lexer::CommaTok)) {
expect(Lexer::NameTok);
if (accept(Lexer::ColonTok)) {
ntExpr();
}
}
}
void Parser::ntExpr()
{
if (accept(Lexer::FuncTok))
{
ntFuncParam();
expect(Lexer::LfTok);
ntExprList();
expect(Lexer::EndTok);
}
else if (accept(Lexer::WhileTok))
{
ntExpr();
expect(Lexer::LfTok);
ntExprList();
expect(Lexer::LoopTok);
}
else if (accept(Lexer::DoTok))
{
ntExprList();
expect(Lexer::WhileTok);
expect(Lexer::LoopTok);
ntExpr();
expect(Lexer::LfTok);
}
else if (accept(Lexer::IfTok))
{
ntExpr();
expect(Lexer::LfTok);
ntExprList();
while (accept(Lexer::ElseifTok))
{
ntExpr();
expect(Lexer::LfTok);
ntExprList();
}
if (accept(Lexer::ElseTok))
{
ntExprList();
}
expect(Lexer::EndifTok);
}
else if (accept(Lexer::IntegerTok))
{
}
}
但我不知道在某些部分要做什么,例如 expr 可以是左值,其第一项可以是 expr。
I have this grammar:
program ::= expr_list
expr_list ::= {LF} [expr {LF {LF} expr}] {LF}
lvalue ::= [expr DOT] NAME
call_param ::= [[NAME COLON] expr {COMMA [NAME COLON] expr}]
func_param ::= [NAME [COLON expr] {COMMA NAME [COLON expr]}]
expr ::= lvalue
| lvalue ASSIGN expr
| expr OPAREN call_param CPAREN
| FUNC func_param LF expr_list END
| IF expr LF expr_list {ELSEIF expr LF expr_list} [ELSE expr_list] ENDIF
| WHILE expr LF expr_list LOOP
| DO expr_list LOOP WHILE expr LF
| INTEGER
I partially wrote a recursive descent parser:
void Parser::ntProgram()
{
ntExprList();
}
void Parser::ntExprList()
{
// ???
}
void Parser::ntLvalue()
{
// ???
}
void Parser::ntCallParam()
{
// ???
}
void Parser::ntFuncParam()
{
if (accept(Lexer::NameTok)) {
if (accept(Lexer::ColonTok)) {
ntExpr();
}
}
while (accept(Lexer::CommaTok)) {
expect(Lexer::NameTok);
if (accept(Lexer::ColonTok)) {
ntExpr();
}
}
}
void Parser::ntExpr()
{
if (accept(Lexer::FuncTok))
{
ntFuncParam();
expect(Lexer::LfTok);
ntExprList();
expect(Lexer::EndTok);
}
else if (accept(Lexer::WhileTok))
{
ntExpr();
expect(Lexer::LfTok);
ntExprList();
expect(Lexer::LoopTok);
}
else if (accept(Lexer::DoTok))
{
ntExprList();
expect(Lexer::WhileTok);
expect(Lexer::LoopTok);
ntExpr();
expect(Lexer::LfTok);
}
else if (accept(Lexer::IfTok))
{
ntExpr();
expect(Lexer::LfTok);
ntExprList();
while (accept(Lexer::ElseifTok))
{
ntExpr();
expect(Lexer::LfTok);
ntExprList();
}
if (accept(Lexer::ElseTok))
{
ntExprList();
}
expect(Lexer::EndifTok);
}
else if (accept(Lexer::IntegerTok))
{
}
}
But I don't know what to do in some parts, for example the way that an expr can be an lvalue, whose first item could be an expr.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了能够解析expr规则,你必须首先消除左递归。维基百科对此有很好的解释:
http://en.wikipedia.org/wiki/Left_recursion
In order to be able to parse the expr rule, you have to eliminate left recursion first. This is well explained on Wikipedia:
http://en.wikipedia.org/wiki/Left_recursion