我一直在查看位于:
的语法我一直在使用Antlrworks 2来查看它们,但是我发现很难找到整个语法的开始规则。
我认为启动规则的定义是一个没有其他指针的节点,是否有人有一个工作解决方案来查找这些语法的启动规则?
答案 0 :(得分:1)
为了找到root / start规则,我实现了一个ANTLR树监听器,它创建了一个ANTLR语法中所有规则的邻接列表,并检查是否没有其他语法规则引用它。这将提示启动规则可能是什么。
要运行此功能,您需要从Antlr 4 grammar
获取antlr语法以下是监听器实现:
(RootFinder.java)
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;
}
}
这是运行它的主程序
(Main.java)
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());
}
}