ANTLR4:如何在gramar中查找根规则,它可能用于查找开始规则
我一直在看位于以下位置的语法: 我一直在使用AntlRworks2查看它们,但是我发现很难找到整个语法的开始规则ANTLR4:如何在gramar中查找根规则,它可能用于查找开始规则,antlr4,antlrworks2,Antlr4,Antlrworks2,我一直在看位于以下位置的语法: 我一直在使用AntlRworks2查看它们,但是我发现很难找到整个语法的开始规则 我认为开始规则的定义是一个没有其他指向它的指针的节点,有没有人能找到这些语法的开始规则的有效解决方案?要找到根/开始规则,我已经实现了一个ANTLR树侦听器,它创建了ANTLR语法中所有规则的邻接列表,并检查是否没有其他语法规则引用它。这将提示开始规则可能是什么 要运行此程序,您需要从 以下是侦听器实现: (RootFinder.java) 从技术上讲,您可以使用任何解析器规则作为
我认为开始规则的定义是一个没有其他指向它的指针的节点,有没有人能找到这些语法的开始规则的有效解决方案?要找到根/开始规则,我已经实现了一个ANTLR树侦听器,它创建了ANTLR语法中所有规则的邻接列表,并检查是否没有其他语法规则引用它。这将提示开始规则可能是什么 要运行此程序,您需要从 以下是侦听器实现: (RootFinder.java)
从技术上讲,您可以使用任何解析器规则作为开始规则。它只取决于要解析的语法的哪一部分(在代码中,调用哪个方法)。但通常你会在语法领域中寻找更抽象的组合,通常类似于
程序
,文档
或查询
。没有硬规则。是的:(我想要一种不用手动查找的方法。我想要AST的根节点。它不需要很长时间,但是能够检测根节点是很方便的。根节点取决于你用来开始解析的规则。这只是一个定义你认为开始规则的问题。作为一个经验法则:通常情况下。(但并非总是如此)最常用的入口规则位于语法文件的顶部。我可以看到混乱,我所追求的特定开始规则是可以用来解析文件中所有结构的规则。因此,如果你使用语法,它可以用来识别该语言的任何文件,而不是文件的子集。我不知道下面是术语,但我所追求的是语法文件中可能的最高根。另一个困惑是我没有试图找到开始规则,我试图找到一个定义整个语言开始的特定开始规则。我在这里使用的开始术语与“开始规则”相冲突
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class RootFinder extends ANTLRv4ParserBaseListener {
private Set<String> rules = new HashSet<String>( );
public Map<String, Set<String>> adjacencyList = new LinkedHashMap<String, Set<String>>( );
public void enterParserRuleSpec(ANTLRv4Parser.ParserRuleSpecContext ctx)
{
rules = new HashSet<String>( );
}
public void exitParserRuleSpec(ANTLRv4Parser.ParserRuleSpecContext ctx)
{
if(ctx != null)
{
adjacencyList.put(ctx.RULE_REF().getText(), rules);
}
}
public void exitRuleref(ANTLRv4Parser.RulerefContext ctx) {
if(ctx != null)
{
rules.add(ctx.getText());
}
}
public List<String> leafNodes( )
{
List<String> leafs = new ArrayList<String>( );
for(Entry<String, Set<String>> entry : adjacencyList.entrySet())
{
if( entry.getValue().size() == 0)
{
leafs.add(entry.getKey());
}
}
return leafs;
}
public Set<String> rootNodes( )
{
Set<String> roots = new HashSet<String>( );
Collection<Set<String>> values = adjacencyList.values();
for(Entry<String, Set<String>> entry : adjacencyList.entrySet())
{
boolean found = false;
for(Set<String> vals : values)
{
if(vals.contains(entry.getKey()))
{
found = true;
}
}
if(found == false)
{
roots.add(entry.getKey());
}
}
return roots;
}
}
import java.io.IOException;
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
public class Main {
public static void main(String[] args) throws IOException {
String filename = args[0];
ANTLRInputStream reader = new ANTLRFileStream(filename);
ANTLRv4Lexer lexer = new ANTLRv4Lexer(reader);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
ANTLRv4Parser parser = new ANTLRv4Parser(tokenStream);
RootFinder rootfinder = new RootFinder();
parser.addParseListener(rootfinder);
ParseTree tree = parser.grammarSpec();
System.out.println(rootfinder.leafNodes());
System.out.println(rootfinder.rootNodes());
}
}