crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V   1 2 3 >  
Ответить в данную темуНачать новую тему
> ошибка при генерации в ANTLRWorks 1.3.1
mannyz
  опции профиля:
сообщение 13.3.2010, 21:35
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 18
Регистрация: 13.3.2010
Пользователь №: 1529

Спасибо сказали: 0 раз(а)




Репутация:   0  


Добрый вечер, всем

Пришлось столкнутся с ANTLR и сразу у меня с ним как-то не сложилось.
Пытаюсь для начала сгенерировать простой пример (для Python) с помощью ANTLRWorks. Всего два файла, используемые для генерации.

Eval.g:
Цитата
tree grammar Eval;

options {
language=Python;
tokenVocab=Expr;
ASTLabelType=CommonTree;
}

@init {self.memory = {}}

// START:stat
prog: stat+ ;

stat: expr
{print $expr.value}
| ^('=' ID expr)
{self.memory[$ID.getText()] = int($expr.value)}
;
// END:stat

// START:expr
expr returns [value]
: ^('+' a=expr b=expr) {$value = a+b;}
| ^('-' a=expr b=expr) {$value = a-b;}
| ^('*' a=expr b=expr) {$value = a*b;}
| ID
{
k = $ID.getText()
if k in self.memory:
$value = self.memory[k]
else:
print >> sys.stderr, "undefined variable "+k
}
| INT {$value = int($INT.getText())}
;
// END:expr



и Expr.g:
Цитата
grammar Expr;

options {
language=Python;
output=AST;
ASTLabelType=CommonTree;
}

prog : ( stat {print $stat.tree.toStringTree();} )+ ;

stat : expr NEWLINE -> expr
| ID '=' expr NEWLINE -> ^('=' ID expr)
| NEWLINE ->
;

expr : multExpr (('+'^|'-'^) multExpr)*
;

multExpr
: atom ('*'^ atom)*
;

atom : INT
| ID
| '('! expr ')'!
;

ID : ('a'..'z'|'A'..'Z')+ ;

INT : '0'..'9'+ ;

NEWLINE : '\r'? '\n' ;

WS : (' '|'\t'|'\n'|'\r')+ {self.skip()} ;



Со вторым файлом Expr.g возникают проблемы. Причем тест на правильность грамматики (Ctrl+R в ANTLRWorks) говорит, что все хорошо. А вот при попытке генерации появляется следующая ошибка:
Цитата
[18:59:55] error(10): internal error: Exception Expr__.g:14:18: unexpected char: '\'@org.antlr.grammar.v2.ANTLRLexer.nextToken(ANTLRLexer.java:347): unexpected stream error from parsing Expr__.g

[18:59:55] error(150): grammar file Expr__.g has no rules
[18:59:55] error(100): Expr__.g:0:0: syntax error: assign.types: <AST>:0:0: unexpected end of subtree
[18:59:55] error(100): Expr__.g:0:0: syntax error: define: <AST>:0:0: unexpected end of subtree
[19:12:10] Checking Grammar Expr.g...
[19:18:09] error(10): internal error: Exception Expr__.g:14:18: unexpected char: '\'@org.antlr.grammar.v2.ANTLRLexer.nextToken(ANTLRLexer.java:347): unexpected stream error from parsing Expr__.g

[19:18:09] error(150): grammar file Expr__.g has no rules
[19:18:09] error(100): Expr__.g:0:0: syntax error: assign.types: <AST>:0:0: unexpected end of subtree
[19:18:09] error(100): Expr__.g:0:0: syntax error: define: <AST>:0:0: unexpected end of subtree



Поясните, пожалуйста, что к чему. Честно сказать, мне даже не понятно, откуда взялось название с двумя подчеркиваниями Expr__.g (как я понимаю, создается временный файл?). И как искать место ошибки? Потому что, если обращаться по адресу 14:18 в файле Expr.g
Цитата
internal error: Exception Expr__.g:14:18: unexpected char:

, то ничего токового не происходит. Оно и понятно, файл другой ведь указан
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 14.3.2010, 17:19
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


похоже, это у тебя его от формата файла тошнит. возможно, редактировал чем-то таким, что наоставляло "хвостов" в конце строк. либо жаба где-то неправильно настроена.
я скопировала твои файлы, сохранила их через ANTLR, они проверились и скомпилились без проблем.

У меня система Linux Debian, в основном Squeeze, плюс всякие новые экспериментальные пакеты.
ANTLR 1.3.1
Жаба:
java version "1.6.0_17"
Java™ SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot™ Server VM (build 14.3-b01, mixed mode)

Сообщение отредактировал Iron Bug - 14.3.2010, 17:20
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mannyz
  опции профиля:
сообщение 14.3.2010, 21:12
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 18
Регистрация: 13.3.2010
Пользователь №: 1529

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 14.3.2010, 17:19) *
похоже, это у тебя его от формата файла тошнит. возможно, редактировал чем-то таким, что наоставляло "хвостов" в конце строк. либо жаба где-то неправильно настроена.
я скопировала твои файлы, сохранила их через ANTLR, они проверились и скомпилились без проблем.

У меня система Linux Debian, в основном Squeeze, плюс всякие новые экспериментальные пакеты.
ANTLR 1.3.1
Жаба:
java version "1.6.0_17"
Java™ SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot™ Server VM (build 14.3-b01, mixed mode)


ага, спасибо.
видимо косяки где-то в самом ANTLRWorks (приблуда с GUI). Если генерить файлы через обычный ANTLR, то все получается. Правда, я так и не смог запустить ни одни пример до конца, чтобы понять, что хоть что-то работает ))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 15.3.2010, 17:44
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


у меня под линём ANTLRWorks вполне нормально работает. попробуй поиграться со шрифтами и настройками редактора. может, и есть какие-то проблемы. но у меня их никогда не возникало пока что.
ANTLR действительно работает и очень удобен. существенно ускоряет процесс разработки, когда нужен парсинг чего угодно - от простых строк и командных файлов, до самописных языков программирования.
багов в нём я пока тоже не встречала.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mannyz
  опции профиля:
сообщение 16.3.2010, 17:49
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 18
Регистрация: 13.3.2010
Пользователь №: 1529

Спасибо сказали: 0 раз(а)




Репутация:   0  


а как перенаправить cin или stdin во входной поток для ANTLR в контексте Си?

пока набрел на такой вариант:
Цитата
char *inputQuery = (char *) malloc(4096);
//*must* be allocated dynamicaly/staticaly, but not on the stack!

pcqpLexer lexer;
pcqpParser parser;
cqpParser_query_return cqpAST;
pcqpTreeWalker treeWalker;
pANTLR3_INPUT_STREAM input;
pANTLR3_COMMON_TOKEN_STREAM tokenStream;
pANTLR3_COMMON_TREE_NODE_STREAM nodes;

try {
cin.getline(inputQuery, 4096);

input = antlr3NewAsciiStringInPlaceStream ((pANTLR3_UINT8) inputQuery,
(ANTLR3_UINT64) strlen(inputQuery), (pANTLR3_UINT8) "CQP Stream");
if (input == NULL) {
ANTLR3_FPRINTF(stderr, "Unable to set up input stream due to malloc()
failure1\n");
}


Но может есть что-то другое?

Цитата(mannyz @ 16.3.2010, 17:34) *
а как перенаправить cin или stdin во входной поток для ANTLR в контексте Си?

пока набрел на такой вариант:
Цитата
char *inputQuery = (char *) malloc(4096);
//*must* be allocated dynamicaly/staticaly, but not on the stack!

pcqpLexer lexer;
pcqpParser parser;
cqpParser_query_return cqpAST;
pcqpTreeWalker treeWalker;
pANTLR3_INPUT_STREAM input;
pANTLR3_COMMON_TOKEN_STREAM tokenStream;
pANTLR3_COMMON_TREE_NODE_STREAM nodes;

try {
cin.getline(inputQuery, 4096);

input = antlr3NewAsciiStringInPlaceStream ((pANTLR3_UINT8) inputQuery,
(ANTLR3_UINT64) strlen(inputQuery), (pANTLR3_UINT8) "CQP Stream");
if (input == NULL) {
ANTLR3_FPRINTF(stderr, "Unable to set up input stream due to malloc()
failure1\n");
}


Но может есть что-то другое?


а то у меня это не работает ((
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 16.3.2010, 17:52
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


mannyz, не цитируй большими кусками.
О том, как цитировать только фрагментами, смотри тему Справка по кнопкам и тэгам форума
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 16.3.2010, 18:44
Сообщение #7


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(mannyz @ 16.3.2010, 19:49) *
Но может есть что-то другое?
а то у меня это не работает ((


что конкретно не работает? не создаётся входной поток из строки, полученной из cin? или твой парсер не может это прожевать?
в любом случае надо читать документацию по вызову antlr3NewAsciiStringInPlaceStream, хотя вроде она создаёт стандартный входящий поток для лексера.
попробуй читать для начала просто из файла - проверишь, что поток создался и твои лексер и парсер его могут схавать. а потом уже будешь ковырять cin.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mannyz
  опции профиля:
сообщение 16.3.2010, 19:04
Сообщение #8


Студент
*

Группа: Новичок
Сообщений: 18
Регистрация: 13.3.2010
Пользователь №: 1529

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 16.3.2010, 18:44) *
Цитата(mannyz @ 16.3.2010, 19:49) *
Но может есть что-то другое?
а то у меня это не работает ((


что конкретно не работает? не создаётся входной поток из строки, полученной из cin? или твой парсер не может это прожевать?
в любом случае надо читать документацию по вызову antlr3NewAsciiStringInPlaceStream, хотя вроде она создаёт стандартный входящий поток для лексера.
попробуй читать для начала просто из файла - проверишь, что поток создался и твои лексер и парсер его могут схавать. а потом уже будешь ковырять cin.

да, я тоже решил для начала из файла почитать. Из файла читает хорошо ). Были проблемы с тем, чтобы сбрасывать считанные символы лексером (не передавать их парсеру), но уже разобралси - надо SKIP()(все верхним регистром написано) использовать. Сейчас буду набивать парсер, а потом уже займусь тем, как ему передавать инфу.

Кстати, в примере с Java очень просто реализуется считывание из стандартного потока:
i
Цитата
mport org.antlr.runtime.*;

public class Test {
public static void main(String[] args) throws Exception {
ANTLRInputStream input = new ANTLRInputStream(System.in);
ExprLexer lexer = new ExprLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExprParser parser = new ExprParser(tokens);
parser.prog();
}
}

Я думал, что, может, есть что-то подобное под Си.

с цитированием кода у меня опять косяк вышел - торопился очень
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 16.3.2010, 20:17
Сообщение #9


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


дык, под Си оно не намного сложнее. просто пишется чуть менее красиво, но сложного там нет ничего.
всё аналогично (у меня в примере проект называется dce и основной файл плюсовый):
Раскрывающийся текст

    pANTLR3_INPUT_STREAM        input; // входной поток
    pdceLexer                     lxr; // лексер
    pANTLR3_COMMON_TOKEN_STREAM        tstream; // промежуточный поток лексем
    pdceParser                psr; // парсер
    dceParser_program_return        dceAST; // дерево (если используется AST)  опции
                                                                 // output        = AST;
                                                                 // language    = C;
                                                                 // ASTLabelType    = pANTLR3_BASE_TREE;
    pANTLR3_COMMON_TREE_NODE_STREAM nodes; //་ узлы

    input    = antlr3AsciiFileStreamNew(fName); // это чтение из файла, по идее пофиг, откуда читать, главное - создать поток
    if ( input == NULL )
    {
.............
    }

    lxr        = dceLexerNew(input);        // создаётся новый лексер
    if ( lxr == NULL )
    {
.................
    }

    tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lxr)); // создаётся поток лексем
    if (tstream == NULL)
    {
.................
    }

    psr        = dceParserNew(tstream);  // создаётся парсер
    if (psr == NULL)
    {
................
    }
    
    dceAST = psr->program(psr); // вызывается точка входа в парсере (program)


собственно, дерево построено и дальше можно это дерево юзать. например, вот так:
Раскрывающийся текст

if (psr->pParser->rec->state->errorCount > 0)
    {
// были ошибки
    }
    else
    {
// можно вот так, к примеру, распечатать то, что получилось в итоге:
        printf("Tree : %s\n", dceAST.tree->toStringTree(dceAST.tree)->chars);

    }



плюс ещё обрати внимание на передачу параметров между разными декларациями если будешь компилить в одном проекте сишные и cpp-шные файлы. там при передаче параметров важно порядок передачи параметров соблюдать и прописывать, где это необходимо.

Сообщение отредактировал Iron Bug - 16.3.2010, 20:27
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mannyz
  опции профиля:
сообщение 16.3.2010, 20:49
Сообщение #10


Студент
*

Группа: Новичок
Сообщений: 18
Регистрация: 13.3.2010
Пользователь №: 1529

Спасибо сказали: 0 раз(а)




Репутация:   0  


ага, спасибо. я так и делал.
кстати, а можно пояснить про AST, я то я не догнал окончательно, что это такое и зачем?
и еще вопрос: я так понимаю поддержки с++ в antlr нэт? а то я пытался скомпилить код, где в *.g-файле есть классы и получаю фиг.

а есть, вообще, документация на русском по antlr?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V   1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 2:49