![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
mannyz |
![]()
Сообщение
#1
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 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 |
![]()
Сообщение
#2
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
похоже, это у тебя его от формата файла тошнит. возможно, редактировал чем-то таким, что наоставляло "хвостов" в конце строк. либо жаба где-то неправильно настроена.
я скопировала твои файлы, сохранила их через 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 |
![]()
Сообщение
#3
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
похоже, это у тебя его от формата файла тошнит. возможно, редактировал чем-то таким, что наоставляло "хвостов" в конце строк. либо жаба где-то неправильно настроена. я скопировала твои файлы, сохранила их через 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 |
![]()
Сообщение
#4
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
у меня под линём ANTLRWorks вполне нормально работает. попробуй поиграться со шрифтами и настройками редактора. может, и есть какие-то проблемы. но у меня их никогда не возникало пока что.
ANTLR действительно работает и очень удобен. существенно ускоряет процесс разработки, когда нужен парсинг чего угодно - от простых строк и командных файлов, до самописных языков программирования. багов в нём я пока тоже не встречала. |
|
|
mannyz |
![]()
Сообщение
#5
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 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"); } Но может есть что-то другое? а как перенаправить 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 |
![]()
Сообщение
#6
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
mannyz, не цитируй большими кусками.
О том, как цитировать только фрагментами, смотри тему Справка по кнопкам и тэгам форума |
|
|
Iron Bug |
![]()
Сообщение
#7
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Но может есть что-то другое? а то у меня это не работает (( что конкретно не работает? не создаётся входной поток из строки, полученной из cin? или твой парсер не может это прожевать? в любом случае надо читать документацию по вызову antlr3NewAsciiStringInPlaceStream, хотя вроде она создаёт стандартный входящий поток для лексера. попробуй читать для начала просто из файла - проверишь, что поток создался и твои лексер и парсер его могут схавать. а потом уже будешь ковырять cin. |
|
|
mannyz |
![]()
Сообщение
#8
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Но может есть что-то другое? а то у меня это не работает (( что конкретно не работает? не создаётся входной поток из строки, полученной из 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 |
![]()
Сообщение
#9
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
дык, под Си оно не намного сложнее. просто пишется чуть менее красиво, но сложного там нет ничего.
всё аналогично (у меня в примере проект называется dce и основной файл плюсовый): Раскрывающийся текст
собственно, дерево построено и дальше можно это дерево юзать. например, вот так: Раскрывающийся текст
плюс ещё обрати внимание на передачу параметров между разными декларациями если будешь компилить в одном проекте сишные и cpp-шные файлы. там при передаче параметров важно порядок передачи параметров соблюдать и прописывать, где это необходимо. Сообщение отредактировал Iron Bug - 16.3.2010, 20:27 |
|
|
mannyz |
![]()
Сообщение
#10
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
ага, спасибо. я так и делал.
кстати, а можно пояснить про AST, я то я не догнал окончательно, что это такое и зачем? и еще вопрос: я так понимаю поддержки с++ в antlr нэт? а то я пытался скомпилить код, где в *.g-файле есть классы и получаю фиг. а есть, вообще, документация на русском по antlr? |
|
|
Iron Bug |
![]()
Сообщение
#11
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
насчёт с++: насколько я знаю, модуля под 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 |
![]()
Сообщение
#12
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
прикольно, ты девушка )). и тебе нравиться прогать. я, честно, сказать уже возненавидел это. бэээ.
за советы спасибо. по сайту лазил, но он, действительно, на английском )). книжку "The Definitive ANTLR Reference.Building Domain-Specific Languages" скачал, но не всегда все понятно. буду разбираться. |
|
|
mannyz |
![]()
Сообщение
#13
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 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(); }; это все компилится, только при запуске ошибка, о которой я уже говорил выше. |
|
|
Iron Bug |
![]()
Сообщение
#14
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
мдя... я не юзала хэш-таблицы в ANTLR-овской реализации, но решила проверить, почему этот код не работает.
пришлось быть шаманом и прикончить весь запас пива в холодильнике, прежде чем великий дух программирования сжалился и дал мне просветление, чтобы просечь, как это сделать ![]() вот: Раскрывающийся текст grammar Expr; options { language=C; } @header { #include <stdlib.h> } @members { pANTLR3_HASH_TABLE types; } prog @init { types = antlr3HashTableNew(11); } :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(); }; вот только хрен знает почему нельзя просто так в глобальном пространстве объявлять эту переменную. суть этой проблемы пока мне не ясна. либо можно сделать так: объявлять переменную во внешнем файле, а в парсере только использовать, указав extern: Раскрывающийся текст grammar Expr; options { language=C; } @header { #include <stdlib.h> } @members { extern pANTLR3_HASH_TABLE types; } prog @init { types = antlr3HashTableNew(11); } :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(); }; на самом деле, инициализировать её тоже можно где угодно. главное, чтобы до использования. и вот ещё вариант с областями видимости: Раскрывающийся текст grammar Expr; options { language=C; } scope SomeScopeName { pANTLR3_HASH_TABLE types; } @header { #include <stdlib.h> } prog scope SomeScopeName; @init { $SomeScopeName::types= antlr3HashTableNew(11); } :statex+ ; statex : 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(); }; это типа сделано, чтобы различать области видимости и "разрешать" некоторым правилам доступ к конкретным внешним переменным. ну, что больше подходит - то и юзай. |
|
|
mannyz |
![]()
Сообщение
#15
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Цитата мдя... я не юзала хэш-таблицы в ANTLR-овской реализации, но решила проверить, почему этот код не работает. пиво вредно )).пришлось быть шаманом и прикончить весь запас пива в холодильнике, прежде чем великий дух программирования сжалился и дал мне просветление, чтобы просечь, как это сделать ![]() спасибо за подробные разъяснения. попробовал твои текста - заработало: все скомпилилось и ошибка не появлялась. здорово! но самое странное, что попробовал свои вчерашние текста (из своего сообщения, с которым ошибка памяти возникала) - тоже все прошло нормально. не понятно тогда, в чем вчера дело было ((. Цитата вот только хрен знает почему нельзя просто так в глобальном пространстве объявлять эту переменную. суть этой проблемы пока мне не ясна. да, получается, урезание в правах какое-то: ведь в ANTLR-книге приводятся примеры, где можно объявлять списки List или еще что-то в глобальном пространстве и потом просто так юзать их где попало и как попало. этоn пример, кстати, в главе про scope есть. проще показать:Цитата @members { String methodName; } method: type ID {methodName=$ID.text;} body ; body: '{' statement+ '}' ; statement : decl {...methodName...} ';' // ref value set in method | ... ; Видимо, это такая особенность этой хэш-таблицы или всего scope. если посмотришь ниже, в примере для Си, в области memebers рядом с пояснением к SCOPE_SIZE и т.п., они говорят что-то про стэк и все такое. только я окончательно ничего не понимать. В общем, если есть желание разобраться в этом, то вот код, а так ты уже и так помогла очень )). Раскрывающийся текст /** ANSI C ANTLR v3 grammar Adapted for C output target by Jim Idle - April 2007. Translated from Jutta Degener's 1995 ANSI C yacc grammar by Terence Parr July 2006. The lexical rules were taken from the Java grammar. Jutta says: "In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a matching Lex specification) for the April 30, 1985 draft version of the ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that original, as mentioned in the answer to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z. I intend to keep this version as close to the current C Standard grammar as possible; please let me know if you discover discrepancies. Jutta Degener, 1995" Generally speaking, you need symbol table info to parse C; typedefs define types and then IDENTIFIERS are either types or plain IDs. I'm doing the min necessary here tracking only type names. This is a good example of the global scope (called Symbols). Every rule that declares its usage of Symbols pushes a new copy on the stack effectively creating a new symbol scope. Also note rule declaration declares a rule scope that lets any invoked rule see isTypedef boolean. It's much easier than passing that info down as parameters. Very clean. Rule direct_declarator can then easily determine whether the IDENTIFIER should be declared as a type name. I have only tested this on a single file, though it is 3500 lines. This grammar requires ANTLR v3 (3.0b8 or higher) Terence Parr July 2006 */ grammar C; options { backtrack = true; memoize = true; k = 2; language = C; } scope Symbols { // Only track types in order to get parser working. The Java example // used the java.util.Set to keep track of these. The ANTLR3 runtime // has a number of useful 'objects' we can use that act very much like // the Java hashtables, Lists and Vectors. You have finer control over these // than the Java programmer, but they are sometimes a little more 'raw'. // Here, for each scope level, we want a set of symbols, so we can use // a ANTLR3 runtime provided hash table, and then later we will see if // a symbols is stored in at any level by using the symbol as the // key to the hashtable and seeing if the table contains that key. // pANTLR3_HASH_TABLE types; } // While you can implement your own character streams and so on, they // normally call things like LA() via function pointers. In general you will // be using one of the pre-supplied input streams and you can instruct the // generated code to access the input pointers directly. // // For 8 bit inputs : #define ANTLR3_INLINE_INPUT_ASCII // For 16 bit UTF16/UCS2 inputs : #define ANTLR3_INLINE_INPUT_UTF16 // // If your compiled recognizer might be given inputs from either of the sources // or you have written your own character input stream, then do not define // either of these. // @lexer::header { #define ANTLR3_INLINE_INPUT_ASCII } @parser::includes { // Include our noddy C++ example class // #include <cpp_symbolpp.h> } // The @header specifier is valid in the C target, but in this case there // is nothing to add over and above the generated code. Here you would // add #defines perhaps that you have made your code reliant upon. // // Use @preincludes for things you want to appear in the output file // before #include <antlr3.h> // @includes to come after #include <antlr3.h> // @header for things that should follow on after all the includes. // // Hence, this java oriented @header is commented out. // // @header { // import java.util.Set; // import java.util.HashSet; // } // @members inserts functions in C output file (parser without other // qualification. @lexer::members inserts functions in the lexer. // // In general do not use this too much (put in the odd tiny function perhaps), // but include the generated header files in your own header and use this in // separate translation units that contain support functions. // @members { // This is a function that is small enough to be kept in the // generated parser code (@lexer::members puts code in the lexer. // // Note a few useful MACROS in use here: // // SCOPE_SIZE returns the number of levels on the stack (1 to n) // for the named scope. // SCOPE_INSTANCE returns a pointer to Scope instance at the // specified level. // SCOPE_TYPE makes it easy to declare and cast the pointer to // the structure typedef that the code generator declares. // // All functions (that need anything to do with the runtime, should // receive a parameter called ctx as the first parameter. ctx is a pointer // to the instance of the parser that is running and ensures thread safety // as well as easy access to all the parser elements etc. All MACROS assume // the presence of this parameter. This would be a pCLexer pointer if this // were a function to be called by the lexer (in which case this would be in // @lexer::members. // ANTLR3_BOOLEAN isTypeName(pCParser ctx, pANTLR3_UINT8 name) { int i; for (i = (int)SCOPE_SIZE(Symbols)-1 ; i >= 0; i--) { pANTLR3_HASH_TABLE symtab; pANTLR3_STRING symbol; SCOPE_TYPE(Symbols) symScope; // Aids in declaring the scope pointers // Pick up the pointer to the scope structure at the current level // We are descending from the inner most scope as that is how C type // scoping works. // symScope = (SCOPE_TYPE(Symbols))SCOPE_INSTANCE(Symbols, i); // The pointer we have is an instance of the dynamic global scope // called Symbols. Within there, as declared above, we have a pointer // to an ANTLR3_HASH_TABLE. We should really check for NULL etc, like all good C code // should. But, this is example code... // symtab = (pANTLR3_HASH_TABLE) symScope->types; // The following call shows that you cannot add a NULL pointer as the entry for // the hash table. You can always just add the pointer to the key and ignore it, but // when you return from this call, you want to test for a NULL pointer, which means // the entry was not found in the table. // symbol = (pANTLR3_STRING) (symtab->get(symtab, (void *)name)); // Did we find the symbol in the type lists? // This is generally used for semantic predicates, hence ANTLR3_TRUE or ANTLR3_FALSE // for the return // if (symbol != NULL) { return ANTLR3_TRUE; } } // We did not find the requested symbol in any of the scopes // that are currently in force. // return ANTLR3_FALSE; } // Because our dynamic scope contains an ANTLR3_HASH_TABLE, we need to free // it when it goes out of scope. When we create a new scope, we just set the // free pointer for the scope to point to this embedded function, which will be // called with a pointer to the scope instance that is to be freed, // from whence we take the table pointer, which we can then close :-) // void ANTLR3_CDECL freeTable(SCOPE_TYPE(Symbols) symtab) { // If we supplied an entry in the table with a free pointer, // then calling the table free function will call the free function // for each entry as it deletes it from the table. In this case however // we only stored things that were manufactured by internal factories, which // will be released anyway when the parser/lexer/etc are freed. // symtab->types->free(symtab->types); } } translation_unit scope Symbols; // The entire translation_unit (file) is a scope @init { // The code in @init is executed before the rule starts. Note that this // is C, hence we cannot guarantee to be able to both declare and initialize // variables at the same time. If you need to declare variables as local // to a rule, use the @declarations section and then initialize locals // separately in this @init section. // $Symbols::types = antlr3HashTableNew(11); // parameter is a rough hint for hash alg. as to size SCOPE_TOP(Symbols)->free = freeTable; // This is called when the scope is popped } : external_declaration+ ; /** Either a function definition or any other kind of C decl/def. * The LL(*) analysis algorithm fails to deal with this due to * recursion in the declarator rules. I'm putting in a * manual predicate here so that we don't backtrack over * the entire function. Further, you get a better error * as errors within the function itself don't make it fail * to predict that it's a function. Weird errors previously. * Remember: the goal is to avoid backtrack like the plague * because it makes debugging, actions, and errors harder. * * Note that k=1 results in a much smaller predictor for the * fixed lookahead; k=2 made a few extra thousand lines. ![]() * I'll have to optimize that in the future. */ external_declaration options { k=1; } : ( declaration_specifiers? declarator declaration* '{' )=> function_definition | declaration ; function_definition scope Symbols; // put parameters and locals into same scope for now @init { $Symbols::types = antlr3HashTableNew(11); SCOPE_TOP(Symbols)->free = freeTable; // This is called when the scope is popped } : declaration_specifiers? declarator ( declaration+ compound_statement // K&R style | compound_statement // ANSI style ) ; declaration scope { ANTLR3_BOOLEAN isTypedef; } @init { $declaration::isTypedef = ANTLR3_FALSE; } : 'typedef' declaration_specifiers? { $declaration::isTypedef=ANTLR3_TRUE; } init_declarator_list ';' // special case, looking for typedef | declaration_specifiers init_declarator_list? ';' ; declaration_specifiers : ( storage_class_specifier | type_specifier | type_qualifier )+ ; init_declarator_list : init_declarator (',' init_declarator)* ; init_declarator : declarator ('=' initializer)? ; storage_class_specifier : 'extern' | 'static' | 'auto' | 'register' ; type_specifier : 'void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | struct_or_union_specifier | enum_specifier | type_id ; type_id : {isTypeName(ctx, LT(1)->getText(LT(1))->chars) }? // Note how we reference using C directly IDENTIFIER { // In Java you can just use $xxx.text, which is of type String. // In C, .text returns an ANTLR3 'object' of type pANTLR3_STRING. // the pointer to the actual characters is contained in ->chars and // the object has lots of methods to help you with strings, such as append and // insert etc. pANTLR3_STRING is also auto managed by a string factory, which // will be released when you ->free() the parser. // // printf("'\%s' is a type", $IDENTIFIER.text->chars); } ; struct_or_union_specifier options { k=3; } scope Symbols; // structs are scopes @init { $Symbols::types = antlr3HashTableNew(11); SCOPE_TOP(Symbols)->free = freeTable; // This is called when the scope is popped } : struct_or_union IDENTIFIER? '{' struct_declaration_list '}' | struct_or_union IDENTIFIER ; struct_or_union : 'struct' | 'union' ; struct_declaration_list : struct_declaration+ ; struct_declaration : specifier_qualifier_list struct_declarator_list ';' ; specifier_qualifier_list : ( type_qualifier | type_specifier )+ ; struct_declarator_list : struct_declarator (',' struct_declarator)* ; struct_declarator : declarator (':' constant_expression)? | ':' constant_expression ; enum_specifier options { k=3; } : 'enum' '{' enumerator_list '}' | 'enum' IDENTIFIER '{' enumerator_list '}' | 'enum' IDENTIFIER ; enumerator_list : enumerator (',' enumerator)* ; enumerator : IDENTIFIER ('=' constant_expression)? ; type_qualifier : 'const' | 'volatile' ; declarator : pointer? direct_declarator | pointer ; direct_declarator : ( IDENTIFIER { if (SCOPE_TOP(declaration) != NULL && $declaration::isTypedef) { pANTLR3_STRING idText; // When adding an element to a pANTLR3_HASH_TABLE, the first argument // is the hash table itself, the second is the entry key, the third is // a (void *) pointer to a structure or element of your choice (cannot // be NULL) and the 4th is a pointer to a function that knows how to free // your entry structure (if this is needed, give NULL if not) when the table // is destroyed, or the entry is deleted from the table. // idText = $IDENTIFIER.text; $Symbols::types->put($Symbols::types, idText->chars, idText, NULL); #ifdef __cplusplus // If you compile the generated C source as C++, then you can embed // C++ code in your actions. The runtime is still C based and everything // is tagged properly for linking and so on, but because you are using the // C++ compiler, it will happilly accept classes and so on for things like // scopes. This class is defined entirely in the header file C.h, if "compile // as C++ is set for CParser.c and CLexer.c" It is just a silly example // of course and I don't do anythign with this class, just create and delete it. // symbolpp *mySymClass; mySymClass = new symbolpp($IDENTIFIER.line, idText); delete mySymClass; #endif // Note that we must escape the percent sign here from ANTLR expression // parsing. It is not seen in the generated C code. // printf("define type \%s\n", $IDENTIFIER.text->chars); } } | '(' declarator ')' ) declarator_suffix* ; declarator_suffix : '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' ; pointer : '*' type_qualifier+ pointer? | '*' pointer | '*' ; parameter_type_list : parameter_list (',' '...')? ; parameter_list : parameter_declaration (',' parameter_declaration)* ; parameter_declaration : declaration_specifiers (declarator | abstract_declarator)* ; identifier_list : IDENTIFIER (',' IDENTIFIER)* ; type_name : specifier_qualifier_list abstract_declarator? ; abstract_declarator : pointer direct_abstract_declarator? | direct_abstract_declarator ; direct_abstract_declarator : ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix* ; abstract_declarator_suffix : '[' ']' | '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' ; initializer : assignment_expression | '{' initializer_list ','? '}' ; initializer_list : initializer (',' initializer)* ; // E x p r e s s i o n s argument_expression_list : assignment_expression (',' assignment_expression)* ; additive_expression : (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)* ; multiplicative_expression : (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)* ; cast_expression : '(' type_name ')' cast_expression | unary_expression ; unary_expression : postfix_expression | '++' unary_expression | '--' unary_expression | unary_operator cast_expression | 'sizeof' unary_expression | 'sizeof' '(' type_name ')' ; postfix_expression : primary_expression ( '[' expression ']' | '(' ')' | '(' argument_expression_list ')' | '.' IDENTIFIER | '*' IDENTIFIER | '->' IDENTIFIER | '++' | '--' )* ; unary_operator : '&' | '*' | '+' | '-' | '~' | '!' ; primary_expression : IDENTIFIER | constant | '(' expression ')' ; constant : HEX_LITERAL | OCTAL_LITERAL | DECIMAL_LITERAL | CHARACTER_LITERAL | STRING_LITERAL | FLOATING_POINT_LITERAL ; ///// expression : assignment_expression (',' assignment_expression)* ; constant_expression : conditional_expression ; assignment_expression : lvalue assignment_operator assignment_expression | conditional_expression ; lvalue : unary_expression ; assignment_operator : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ; conditional_expression : logical_or_expression ('?' expression ':' conditional_expression)? ; logical_or_expression : logical_and_expression ('||' logical_and_expression)* ; logical_and_expression : inclusive_or_expression ('&&' inclusive_or_expression)* ; inclusive_or_expression : exclusive_or_expression ('|' exclusive_or_expression)* ; exclusive_or_expression : and_expression ('^' and_expression)* ; and_expression : equality_expression ('&' equality_expression)* ; equality_expression : relational_expression (('=='|'!=') relational_expression)* ; relational_expression : shift_expression (('<'|'>'|'<='|'>=') shift_expression)* ; shift_expression : additive_expression (('<<'|'>>') additive_expression)* ; // S t a t e m e n t s statement : labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement ; labeled_statement : IDENTIFIER ':' statement | 'case' constant_expression ':' statement | 'default' ':' statement ; compound_statement scope Symbols; // blocks have a scope of symbols @init { $Symbols::types = antlr3HashTableNew(11); SCOPE_TOP(Symbols)->free = freeTable; // This is called when the scope is popped } : '{' declaration* statement_list? '}' ; statement_list : statement+ ; expression_statement : ';' | expression ';' ; selection_statement : 'if' '(' expression ')' statement (('else')=> 'else' statement)? | 'switch' '(' expression ')' statement ; iteration_statement : 'while' '(' expression ')' statement | 'do' statement 'while' '(' expression ')' ';' | 'for' '(' expression_statement expression_statement expression? ')' statement ; jump_statement : 'goto' IDENTIFIER ';' | 'continue' ';' | 'break' ';' | 'return' ';' | 'return' expression ';' ; IDENTIFIER : LETTER (LETTER|'0'..'9')* ; fragment LETTER : '$' | 'A'..'Z' | 'a'..'z' | '_' ; CHARACTER_LITERAL : '\'' ( EscapeSequence | ~('\''|'\\') ) '\'' ; STRING_LITERAL : '"' STRING_GUTS '"' ; fragment STRING_GUTS : ( EscapeSequence | ~('\\'|'"') )* ; HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ; DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ; OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ; fragment HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ; fragment IntegerTypeSuffix : ('l'|'L') | ('u'|'U') ('l'|'L')? ; FLOATING_POINT_LITERAL : ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix? | '.' ('0'..'9')+ Exponent? FloatTypeSuffix? | ('0'..'9')+ ( Exponent FloatTypeSuffix? | FloatTypeSuffix) ; fragment Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; fragment FloatTypeSuffix : ('f'|'F'|'d'|'D') ; fragment EscapeSequence : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | OctalEscape ; fragment OctalEscape : '\\' ('0'..'3') ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ; fragment UnicodeEscape : '\\' 'u' HexDigit HexDigit HexDigit HexDigit ; WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} ; COMMENT : '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} ; LINE_COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} ; // ignore #line info for now LINE_COMMAND : '#' (' ' | '\t')* ( 'include' (' ' | '\t')+ '"' file = STRING_GUTS '"' (' ' | '\t')* '\r'? '\n' { pANTLR3_STRING fName; pANTLR3_INPUT_STREAM in; // Create an initial string, then take a substring // We can do this by messing with the start and end // pointers of tokens and so on. This shows a reasonable way to // manipulate strings. // fName = $file.text; printf("Including file '\%s'\n", fName->chars); // Create a new input stream and take advantage of built in stream stacking // in C target runtime. // in = antlr3AsciiFileStreamNew(fName->chars); PUSHSTREAM(in); // Note that the input stream is not closed when it EOFs, I don't bother // to do it here (hence this is leaked at the program end), // but it is up to you to track streams created like this // and destroy them when the whole parse session is complete. Remember that you // don't want to do this until all tokens have been manipulated all the way through // your tree parsers etc as the token does not store the text it just refers // back to the input stream and trying to get the text for it will abort if you // close the input stream too early. // } | (('0'..'9')=>('0'..'9'))+ ~('\n'|'\r')* '\r'? '\n' ) {$channel=HIDDEN;} ; |
|
|
mannyz |
![]()
Сообщение
#16
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
кстати, в том примере для Си, который я выше привел, последний мой "раскрывающийся текст", есть пояснения как все-таки можно обеспечить поддержку C++. надо только еще добавить cpp-файл с описанием класса для примера:
Раскрывающийся текст #ifndef _SYMBOLPP_H #define _SYMBOLPP_H // A simple demonstration class purely to show that the C target // output is C++ compilable. Note that this is the output files that // can be compiled as C++, not the runtime library code itself, which // is purest C, though it has very few things that are incompatible. There is // however no need for the C runtime library to be compiled as C++, as it // just links in trivially as a library on any system, which is more than // can be said for C++ ;_). // // Later the C output may be extended to give some nice convenience classes // for C++ people. For now though, use C for interactions and instantiate your // own classes and so on. // #ifdef __cplusplus class symbolpp { public: symbolpp(int aline, pANTLR3_STRING aname) { line = aline; name = aname; printf("Created a symbolpp class\n"); } private: pANTLR3_STRING name; int line; public: inline int getLine() { return line; } inline const char * getName() { return (const char *)(name->chars); } }; #endif #endif скажи пожалуйста, может быть, ты случайно знаешь как можно задавать в ANTLR цифрами количество раз повторений подряд того или иного токена/подправила? Например, как в других средствах описание регулярных выражений: Таким образом, subrule-ы должны встретиться от min до max количества раз подряд. Подскажешь?
|
|
|
Iron Bug |
![]()
Сообщение
#17
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
пишут, что разве что так.
(взято с http://www.antlr.org/pipermail/antlr-inter...rch/011591.html - там весь раздув, правда, дико устаревшая переписка) вроде в третьем собирались это реализовать какими-то встроенными средствами, но я пока нифига не нашла на этот счёт. |
|
|
mannyz |
![]()
Сообщение
#18
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
ясненько. спасибо )
|
|
|
mannyz |
![]()
Сообщение
#19
|
Студент ![]() Группа: Новичок Сообщений: 18 Регистрация: 13.3.2010 Пользователь №: 1529 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
IronBug, скажи, пожалуйста, можно ли в варианте для Си (я так понял, что под Java можно) указать или поменять тип значения, возвращаемого парсером. Под Java они используют опцию superClass = имя_класса, таким образом делая, чтобы сам генерируемый класс парсера был расширен от superClass. Но в Си это не прокатывает.
Можно ли указать тип возвращаемого значения парсера, структуру или еще чего? |
|
|
Iron Bug |
![]()
Сообщение
#20
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
не знаю. не задумывалась над этим. читай доки, смотри реализацию libantlr3c.
|
|
|
Балалайка |
![]()
Сообщение
#21
|
Новичок Группа: Новичок Сообщений: 2 Регистрация: 20.12.2010 Пользователь №: 2284 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
граждане, только 2ой день с ANTLR знаком. Не пойму как компилятором сделать Си. На яве всё хорошо идёт, но только пишу, language = С, парсер и лексер переводятся в си, но вылазиит ошибка, что javac не видит файла __Test__.java. Сишный подобный файл не генерируется. В настройках компиляции стоит javac. Я не пойму, нужно выбрать какойнибудь сишный компилятор?
|
|
|
Iron Bug |
![]()
Сообщение
#22
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
точно сейчас не скажу, но примерно так:
1. в коде должно быть:
2. в переменной окружения CLASSPATH для жабы должны быть пути до пакетов ANTLR. система должна находить либо пакетник, который чего-то-там-full называется, либо развёрнутый пакет должен быть установлен в стандартные каталоги жабы. об этом написано в википедии ANTLR на их сайте (например, тут: http://www.antlr.org/wiki/pages/viewpage.action?pageId=728). плюс вроде бы для Си ему нужен ещё Java JDK (не только JRE). 3. <имя файла>.g должно быть таким же, как имя парсера (не знаю, зачем такая дурь, но вот требуется ему это). рекомендую поставить ANTLRWorks, если ещё не поставил. в нём проще, он диагностирует всякие неполадки и выводит более-менее читабельные сообщения. к тому же в последнем ANTLRWorks дополнено некое подобие визарда для простейших проектиков. Сообщение отредактировал Iron Bug - 20.12.2010, 14:42 |
|
|
Балалайка |
![]()
Сообщение
#23
|
Новичок Группа: Новичок Сообщений: 2 Регистрация: 20.12.2010 Пользователь №: 2284 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Ну language = C; я ставлю.
Дело в том, что с Java я знаком также второй день. И так, вот что я делал: 1) Я установил себе java-машину - sun jvm 2) Установил себе jdk 3) Скачал antlrworks-1.4.2.jar 4) в настройках компиляции antlrworks выбрал javac и указал путь до папки jdk1.6.0_18 (есть ещё папка jre6, но там нет файла javac) У меня был тестовый проект antl, где всё работает (в antlrworks): лексер, парсер и вызов сем. подпрограмм написанных на java. Так что вроде бы всё работает. После этого я создал лексер, парсер, и выбрал язык java. Жму debug (в antlrworks всё это) и всё нормально, дерево разбора создаётся, подключённый java файл генерирует файл (просто для теста). Далее изменяю язык на Си: options { language = C;}, удаляю папку output и жму ещё раз degug и вылазеет ошибка и в консоле текст: [19:54:53] warning(200): Pascal.g:71:4: Decision can match input such as "'else'" using multiple alternatives: 1, 2 Цитата As a result, alternative(s) 2 were disabled for that input [19:54:53] warning(200): D:\TR2_lab#7\Pascal.g:71:4: Decision can match input such as "'else'" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input [19:54:54] javac: file not found: D:\TR2_lab#7\output\PascalParser.java [19:54:54] Usage: javac <options> <source files> [19:54:54] use -help for a list of possible options При этом в папке output создаётся парсер, лексер - всё на языке си. Понять не могу, зачем требует antlrworks файл PascalParser.java? Также не могу понять, зачем в меню Run пункт Edit *.g Test Rig for C И кстати при компиляции на java создаётся файл __Test__.java, а при указании языка Си , аналогичный файл (__Test__.с) не создаётся |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 28.5.2025, 22:28 |