在手写语法分析器中翻译语法文件
Translating a grammar file in a hand written parser
我一直在尝试为教育目的编写自己的编译器,但遇到了一个问题。我采用了递归下降的方法,之前我对lex和yacc/bison有一些了解。
到目前为止,我只是尝试处理解析方面,而不考虑AST的生成或代码生成。
我正在尝试为这个特定的语法文件部分编写表达式解析
primary_expression
: IDENTIFIER
| CONSTANT
| STRING_LITERAL
| '(' expression ')'
;
postfix_expression
: primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
| postfix_expression '.' IDENTIFIER
| postfix_expression PTR_OP IDENTIFIER
| postfix_expression INC_OP
| postfix_expression DEC_OP
;
到目前为止,我有这个代码
void Parser::primaryExpression()
{
if (accept(Token::eIdentifier))
{
}
else if (accept(Token::eIntNumber))
{
}
else if (accept('('))
{
expression();
expect(')');
}
}
void Parser::postfixExpression()
{
}
我在处理postfix_expression
的递归性时遇到了一些问题,我不知道如何继续使用postfixExpression
函数。
我的印象是,对于递归下降语法分析器,我可能应该以不同的方式排列语法。
有人能给我指正确的方向吗?
左递归在LL(递归下降)解析器中很难处理——您需要识别at并将其更改为循环,而不是递归调用。一般来说,您希望将左递归重构为
A→α|Aβ
然后你的回避下降程序变成
parseA() {
parseAlpha();
while (lookaheadMatchesBeta())
parseBeta();
}
请注意,这需要足够的前瞻性来区分FIRST(β)和FOLLOW(A),以便找到所有可以匹配β
这与LL语法中消除左递归的过程相同——您正在用有效地替换上面的规则
A→&阿尔法A'
A'→&ε;|&β;
然后用循环替换CCD_ 3中的尾部递归调用并将其内联到CCD_。
使用语法并使用上面代码使用的接受/期望技术,你会得到这样的东西:
void Parser::postfixExpression() {
primaryExpression();
while (true) {
if (accept('[')) {
expression();
expect(']');
} else if (accept('(')) {
if (accept(')')) {
} else {
argumentExpressionList();
expect(')'); }
} else if (accept('.')) {
nbsp nbsp nbsp nbsp nbsp nbsp nbsp #8942;
} else if (accept(Token::DEC_OP)) {
} else {
break;
}
}
}
请注意,postfix_expression
总是首先解析primary_expression
,因此业务的第一个顺序是primaryExpression()
。
然后,如果下一个字符是其余七个规则中遵循递归postfix_expression
的任何字符,则您正在解析postfix_expression
。这会给你带来另一个posfix_expression
,所以你再重复一遍。
我不会为您编写C++代码,但使用伪代码:
postfixExpression()
{
primaryExpression();
while (next character is any of the characters that follow
postfix_expression in the remaining seven rules)
{
parse_the_appropriate_rule();
}
}
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- QMetaObject invokeMethod的基于函数指针的语法
- 不同翻译单元中不可重载的非内联函数定义
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 单独定义模板化嵌套类方法的正确语法
- 需要将一行代码从C++ Qt翻译成PyQt
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 为什么未命名的结构内联变量在每个翻译单元中没有相同的地址?
- 为什么我会收到错误 C2143 语法错误:缺少"*"之前的';'?
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 使用基类指针调用基类的值构造函数的语法是什么?
- 很好的语法来获取对向量/数组数据的大小引用?
- 在手写语法分析器中翻译语法文件
- 导入:在C#下使用C 库的语法翻译
- P/调用语法 - 我是否在 C# 中正确翻译了我的C++函数