ошибка при генерации в ANTLRWorks 1.3.1 |
Здравствуйте, гость ( Вход | Регистрация )
ошибка при генерации в 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 |
16.3.2010, 22:54
Сообщение
#2
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
насчёт с++: насколько я знаю, модуля под ANTLR для с++ нет. есть только litbantlr3c для си. помнится, я не сразу нашла нужную версию. перекопала несколько разных, пока не собралось всё нормально. ещё какой-то патч нужен был. но с тех пор прошло уже порядком времени, так что, наверное, патч уже внесли в основную ветку.
а что си - ну так фиолетово: ничто не мешает собирать "разношёрстные" проекты. я так и делаю: ANTLR живёт себе в своих сишных файлах, остальное - на плюсах. компилер сам разбирается, нужно только взаимные вызовы из разных сишных деклараций разводить стандартно. всё работает без проблем. насчёт доков: есть ли на русском документация? честно говоря, хз: мне это ни к чему - у меня два родных языка: Си и английский технический есть книга хорошая, от автора ANTLR: "The Definitive ANTLR Reference.Building Domain-Specific Languages" Terence Parr (The Pragmatic Bookshelf,2007) но, опять же, на английском. это большая монография по ANTLR, 369 страниц. я её как-то давно ещё с трудом нарыла в сети. очень хорошая книга по ANTLR. полнее не бывает. а так, только разве что доки и примеры на сайте ANTLR. тоже на английском. но они довольно скудные и не поясняют саму суть работы. насчёт AST: это абстрактное синтаксическое дерево. чуть больше, чем просто граф, представляющий распарсенный текст. иногда удобно его использовать. но про это тоже лучше читать докуменацию. так объяснять - сильно многабукаф. это надо вникать в RewriteRules, грубо говоря, это дерево ссылок на данные и функции, которые их обрабатывают(к ним привязываются вызовы пользовательского кода), и оно позволяет вычислять значения выражений "на ходу". |
|
|
mannyz |
17.3.2010, 0:51
Сообщение
#3
|
Студент Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: 0 |
прикольно, ты девушка )). и тебе нравиться прогать. я, честно, сказать уже возненавидел это. бэээ.
за советы спасибо. по сайту лазил, но он, действительно, на английском )). книжку "The Definitive ANTLR Reference.Building Domain-Specific Languages" скачал, но не всегда все понятно. буду разбираться. |
|
|
mannyz |
17.3.2010, 2:27
Сообщение
#4
|
Студент Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: 0 |
а ты случайно встроенной хэш-таблицей ANTLR-овской пользовалась?
я имею в виду
я пытаюсь сделать что-то вроде: Раскрывающийся текст grammar Expr; options { language=C; } @header { #include <stdlib.h> } @members { pANTLR3_HASH_TABLE types = antlr3HashTableNew(11); } prog: state+ ; state : expr NEWLINE { printf("\%s\n",$expr.text->chars); } | ID '=' expr NEWLINE | NEWLINE ; expr : multExpr ( '+' multExpr | '-' multExpr )* ; multExpr : atom ('*' atom )* ; atom returns [int value] : INT { $value = atoi($INT.text->chars); printf("<\%s=\%d>",$INT.text->chars,$value); } | ID | '(' expr ')' ; ID : ('a'..'z'|'A'..'Z')+ ; INT : '0'..'9'+ ; NEWLINE:'\r'? '\n' ; WS : (' '|'\t')+ { SKIP(); }; компилятор выдает Цитата 1>d:\pradiswork\prepradis\modelica_api\hnja\hnja\hnja\exprparser.c(346) : error C2099: initializer is not a constant я пытался делать через scope как в примере, все компилилось, но при заупуске сразу выскакивала ошибка обращения к памяти (( как в примере, это я имел в виду примерно так (на раздел @members особо не обращай внимания): Раскрывающийся текст grammar Expr; options { language=C; } scope Symbols { pANTLR3_HASH_TABLE types; // only track types in order to get parser working } @header { #include <stdlib.h> } @members{ void addTypeDef(pANTLR3_HASH_TABLE *types, pANTLR3_COMMON_TOKEN typeDef) { // By the time we are traversing tokens here, it // does not matter if we play with the input stream. Hence // rather than use text or getText() on a token and have the // huge overhead of creating pANTLR3_STRINGS, then we just // null terminate the string that the token is pointing to // and use it directly as a key. // *((pANTLR3_UINT8)(typeDef->stop) + 1) = '\0'; if (*types == NULL) { *types = antlr3HashTableNew(10); } (*types)->put(*types, (pANTLR3_UINT8)typeDef->start, (pANTLR3_UINT8)(typeDef->start), NULL); } int isTypeName(pExprParser ctx, pANTLR3_COMMON_TOKEN name) { int a; // By the time we are traversing tokens here, it // does not matter if we play with the input stream. Hence // rather than use text or getText() on a token and have the // huge overhead of creating pANTLR3_STRINGS, then we just // null terminate the string that the token is pointing to // and use it directly as a key. // *((pANTLR3_UINT8)(name->stop) + 1) = '\0'; for (a = SCOPE_SIZE(Symbols) - 1; a >= 0; a--) { SCOPE_TYPE(Symbols) scope = SCOPE_INSTANCE(Symbols, a); pANTLR3_HASH_TABLE types = scope->types; pANTLR3_UINT8 symbol = NULL; if (types != NULL) { symbol = types->get(types, (pANTLR3_UINT8)(name->start)); } if (symbol != NULL) { return 1; } } return 0; } void ANTLR3_CDECL freetypes(SCOPE_TYPE(Symbols) symtab) { if (symtab->types != NULL) { symtab->types->free(symtab->types); symtab->types = NULL; } } } prog: state+ ; state : expr NEWLINE { printf("\%s\n",$expr.text->chars); } | ID '=' expr NEWLINE | NEWLINE ; expr : multExpr ( '+' multExpr | '-' multExpr )* ; multExpr : atom ('*' atom )* ; atom returns [int value] : INT { $value = atoi($INT.text->chars); printf("<\%s=\%d>",$INT.text->chars,$value); } | ID | '(' expr ')' ; ID : ('a'..'z'|'A'..'Z')+ ; INT : '0'..'9'+ ; NEWLINE:'\r'? '\n' ; WS : (' '|'\t')+ { SKIP(); }; это все компилится, только при запуске ошибка, о которой я уже говорил выше. |
|
|
Текстовая версия | Сейчас: 22.12.2024, 12:05 |