2013-06-26 1 views
1

Я пишу простой парсер Verilog HDL, используя JAVACC для плагина Eclipse.Есть ли способ вызвать функцию, когда сканер соответствует SPECIAL_TOKEN в JAVACC?

В этом подключаемом модуле все параметры и провода зарегистрированы в виде схемы. Эта функция затрудняет поиск желаемого сигнала в представлении Outline, если в включенных файлах много объявлений. Чтобы сократить список контуров, я хочу собрать параметры (и другие сигналы) из включенного файла в подпапку.

Parser фактически работает в два прохода, это означает, что все производные компилятора сначала разрешаются, а результирующая строка передается в парсер Verilog (JAVACC).

По этой причине анализатор JAVACC не может знать начальное и конечное местоположение включенного файла.

Чтобы решить эту проблему, я добавил SPECIAL_TOKEN, в котором есть информация о включении.

Lexer обнаруживает SPECIAL_TOKEN правильно, однако я не мог найти способ вызвать функцию парсера из тела Prepecedure SPECIAL_TOKEN. (На самом деле, это разумно, потому что они расположены в разностных классах)

Я думаю, что я мог бы использовать решение, описанное в последнем разделе страницы (https://javacc.java.net/doc/tokenmanager.html). Однако, я должен добавить такой код ко всем появлениям обычных токенов, не так ли? Как вы знаете, грамматик Verilog настолько сложный, что я не мог принять решение выше.

Есть ли хорошее решение для решения этой проблемы?

ответ

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. Вот некоторые выдержки:

Когда анализатор должен знать исходные COORDS следующих маркеров, он называет 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 
}