1

我正在为一个 Eclipse 插件使用 JAVACC 编写一个简单的 Verilog HDL 解析器。

在这个插件中,所有参数和连线都在大纲视图中注册。如果包含的文件中有大量错误,则此功能很难在大纲视图中找到所需的信号。为了缩短大纲列表,我想将包含文件中的参数(和其他信号)收集到子文件夹中。

Parser 实际上分两遍工作,这意味着首先解析所有编译器派生类,然后将生成的字符串传递给 Verilog 解析器 (JAVACC)。

由于这个原因,JAVACC 解析器无法知道包含文件的开始和结束位置。

为了解决这个问题,我添加了 SPECIAL_TOKEN,其中包含一些与包含相关的信息。

Lexer 正确检测到 SPECIAL_TOKEN,但是我找不到从 SPECIAL_TOKEN 的 preocedure 主体调用解析器函数的方法。(其实是合理的,因为它们位于不同的类中)

我想我可以使用页面最后部分描述的解决方案(https://javacc.java.net/doc/tokenmanager.html)。但是,我必须将此类代码添加到所有出现的常规标记中,不是吗?如您所知,Verilog 的语法非常复杂,我无法接受上述解决方案。

有没有解决这个问题的好办法?

4

1 回答 1

1

如果您的解析器是静态的,那么只需将解析器函数设为静态即可。

如果解析器不是静态的,您可以安排令牌管理器有一个指向其解析器的指针。声明这个指针如下

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
}
于 2013-06-27T13:53:08.170 回答