如果您的解析器是静态的,那么只需将解析器函数设为静态即可。
如果解析器不是静态的,您可以安排令牌管理器有一个指向其解析器的指针。声明这个指针如下
TOKEN_MGR_DECLS : { VerlilogParser myParser ; }
然后只需确保在解析器开始解析之前设置此字段
VerilogParserTokenManager tokMan = new VerilogParserTokenManager(in) ;
VerlilogParser parser = new VerlilogParser(tokMan) ;
tokMan.myParser = parser ;
parser.start() ;
请记住,前瞻可能会导致令牌管理器远远领先于解析器。因此,您必须非常小心地从令牌管理器调用解析器。我解决在 C++ 中将预处理后的行号与预处理的行号和文件名相关联的方法是,我构建了一个表来表示从一个到另一个的映射。您可以在https://code.google.com/p/the-teaching-machine-jhigraph-and-webwriter-plus-plus/source/browse/trunk/trunk/tm/src/tm/cpp/parser中看到这一点/cplusplus.jj . 以下是一些摘录:
当解析器需要知道下一个标记的原始坐标时,它调用 getCoords(0) 定义如下:
// Coordinates
SourceCoords getCoords(int offset ) {
return pc.line_map.getCoords(getToken(offset).beginLine) ; }
line_map 表由令牌管理器使用以下代码填充。
SPECIAL_TOKEN :
{
// Line directives should have the form
// #line linenum filename
// or
// #line linenum
// In the latter case the previous file name is kept.
"#line" : LINE_DIRECTIVE
}
<LINE_DIRECTIVE> SPECIAL_TOKEN :
{
<LINE_NO : (["0"-"9"])+>
{ tokenLine = matchedToken.beginLine+1 ;
sourceLine = Integer.parseInt (matchedToken.image.trim()); }
|
<FILE_NM : "\"" (["0"-"9"])+ "\"">
{ file = fileMap.get( new Integer(matchedToken.image.substring(1, matchedToken.image.length()-1) ) );}
|
" "
|
"\n" { pc.line_map.add (tokenLine, sourceLine, file); } : DEFAULT
}