Парсинг некоторых конкретных утверждений с antlr3 в C target - PullRequest
2 голосов
/ 25 мая 2010

У меня есть несколько вопросов о antlr3 с древовидной грамматикой в ​​target C.

Я почти выполнил свой интерпретатор (функции, переменные, логические и математические выражения в порядке), и я сохранил самые сложные выражения для конца (например, if, switch и т. Д.)

1) Я хотел бы интерпретировать простую инструкцию цикла:

repeat: ^(REPEAT DIGIT stmt);

Я видел много примеров, но ничего о обходчике дерева (здесь только тема с макросами MARK () / REWIND (m) + @init / @after, но не работает (у меня есть ошибки antlr: "неожиданный узел" со смещением 0 ")). Как я могу интерпретировать это утверждение в C?

2) Тот же вопрос с простым оператором if:

if: ^(IF condition stmt elseifstmt* elsestmt?);

Проблема в том, чтобы пропустить оператор, если условие ложно, и проверить другие операторы elseif / else.

3) У меня есть несколько утверждений, которые могут остановить сценарий (например, «break» или «exit»). Как я могу прервать ходок дерева и пропустить следующие токены?

4) При обнаружении ошибки лексера или синтаксического анализатора antlr возвращает ошибку. Но я хотел бы сделать свои домашние сообщения об ошибках. Как получить номер строки, в которой произошел сбой парсера?

Спросите меня, хотите ли вы больше подробностей.

Большое спасибо (и я прошу прощения за мой плохой английский)

1 Ответ

0 голосов
/ 27 мая 2010

Насчет повторения, я думаю, что нашел способ сделать это. В antlr.org я нашел полный интерпретатор языка C--, но сделанный на Java.

Я поместил здесь оператор while (немного по-другому, но путь тот же):

whileStmt
scope{
    Boolean breaked;
}
@after{
    CommonTree stmtNode=(CommonTree)$whileStmt.start.getChild(1);
    CommonTree exprNode=(CommonTree)$whileStmt.start.getChild(0);

    int test;

    $whileStmt::breaked=false;
    while($whileStmt::breaked==false){
            stream.push(stream.getNodeIndex(exprNode));
            test=expr().value;
            stream.pop();
            if (test==0) break;
            stream.push(stream.getNodeIndex(stmtNode));
            stmt();
            stream.pop();
        }

}
    : ^(WHILE . .)
    ;

Я пытался преобразовать этот код в язык C:

repeat 
scope {
    int breaked;
    int tours;
}
@after
{
    int test;

    pANTLR3_BASE_TREE repeatstmt = (pANTLR3_BASE_TREE)$repeat.start->getChild($repeat.start,1);
    pANTLR3_BASE_TREE exprstmt = (pANTLR3_BASE_TREE)$repeat.start->getChild($repeat.start,0);

    $repeat::breaked = 0;
    test = 1;

    while($repeat::breaked == 0)
    {
        TW_FOLLOWPUSH(exprstmt);
        TW_FOLLOWPOP();
        test++;
        if(test == $repeat::tours)
            break;
        TW_FOLLOWPUSH(repeatstmt);
        CTX->repeat(CTX);
        TW_FOLLOWPOP();
    }   
}
    :   ^(REPEAT DIGIT stmt)
        {           
            $repeat::tours = $DIGIT.text->toInt32($DIGIT.text);
        }

Но ничего не произошло (stmt разобрано только раз).

У вас есть идея об этом, пожалуйста?

О самодельных сообщениях об ошибках я нашел макрос GETLINE () в лексере. Он работает, когда происходит обход дерева, но antlr продолжает отображать сообщения об ошибках для ошибок лексера или анализатора.

Спасибо.

...