java - 使用 Antlr 解析代码后如何检测 for 循环块?
问题描述
解决方案
您没有提供足够的代码/语法来重现您所描述的内容。因此,我将演示如何使用ANTLR 存储库中的 C++ 语法来解决它。
我只稍微改变了 1 条规则。代替:
iterationstatement
: While '(' condition ')' statement
| Do statement While '(' expression ')' ';'
| For '(' forinitstatement condition? ';' expression? ')' statement
| For '(' forrangedeclaration ':' forrangeinitializer ')' statement
;
我给它添加了一些标签:
iterationstatement
: While '(' condition ')' statement #WhileStatement
| Do statement While '(' expression ')' ';' #DoWhileStatement
| For '(' forinitstatement condition? ';' expression? ')' statement #ClassicForStatement
| For '(' forrangedeclaration ':' forrangeinitializer ')' statement #ForEachStatement
;
通过这些更改,以下演示类:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
public class Main {
public static void main(String[] args) throws Exception {
String source = "#include <iostream>\n" +
"using namespace std;\n" +
"int main()\n" +
"{\n" +
" for (int i = 0; i <= 5; i++)\n" +
" {\n" +
" for (int j = 0; j <= 5; j++) {\n" +
" cout << i << j << \" \\t\";\n" +
" }\n" +
" cout << \"\\n\";\n" +
" }\n" +
" for (int i = 0; i < 100; i++)\n" +
" {\n" +
" cout<<\"Test\"<<endl;\n" +
" } return 0;\n" +
"}";
CPP14Lexer lexer = new CPP14Lexer(CharStreams.fromString(source));
CPP14Parser parser = new CPP14Parser(new CommonTokenStream(lexer));
ParseTreeWalker.DEFAULT.walk(new ForListener(), parser.translationunit());
}
}
class ForListener extends CPP14BaseListener {
private int forLevel = 0;
@Override
public void enterClassicForStatement(CPP14Parser.ClassicForStatementContext ctx) {
this.forLevel++;
printInfo("classic", ctx);
}
@Override
public void exitClassicForStatement(CPP14Parser.ClassicForStatementContext ctx) {
this.forLevel--;
}
@Override
public void enterForEachStatement(CPP14Parser.ForEachStatementContext ctx) {
this.forLevel++;
printInfo("each", ctx);
}
@Override
public void exitForEachStatement(CPP14Parser.ForEachStatementContext ctx) {
this.forLevel--;
}
private void printInfo(String forType, ParserRuleContext ctx) {
System.out.printf("%s %s for-statement on line %d.%n",
this.forLevel == 1 ? "OUTER" : "INNER", forType, ctx.getStart().getLine());
}
}
将提供以下输出:
OUTER classic for-statement on line 5.
INNER classic for-statement on line 7.
OUTER classic for-statement on line 12.
推荐阅读
- java - layeredPane 中同一位置的 2 个 MouseListener
- json - 在arduino中反序列化json中的json
- ruby-on-rails - 如何检查用户是否已经评价了一本书
- reactjs - 标签列表未显示在图表中?
- jquery - 如何阻止我的 jquery 可拖动克隆远离鼠标指针?
- ruby - 全屏模式在 selenium chromedriver 无头模式下不起作用
- jquery - 显示一个 div 内容并在另一个 div 中显示
- symfony - Twig - 带有原始标签的 Bootstrap 4 布局
- c# - EF Core - 复合主键删除一个索引
- java - 正则表达式没有从模式中删除下划线