|
|
|
Грамматика. BNF
|
|||
|---|---|---|---|
|
#18+
Есть следующий кусочек грамматики: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Идентификатор (Id) может быть простым, т.е. начинаться с буквы и не содержать пробелов, национальных символов и т.д., либо может обрамляться 1 квадратными скобками 2 кавычками двойными " 3 одинарными ' и тогда может содержать в себе все что угодно. Т.е. варианты 2 и 3 -- это строка, StringLiteral. Так как я записал, грамматика компилируется без ошибок. Когда выполняю тест, то если использовать квадратные скобки, то все хорошо. Если идентификатор записать, как строку, т.е. в кавычках, то парсер выдает ошибку "Токен StringLiteral найден, ожидался Id". Как правильно грамматику записать для такого случая? P.S. Пользуюсь Gold Parser ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.11.2007, 08:39 |
|
||
|
Грамматика. BNF
|
|||
|---|---|---|---|
|
#18+
Серж wrote: > Есть следующий кусочек грамматики: > > {String Ch *1*} = {Printable National} - ["] > {String Ch *2*} = {Printable National} - [''] > {Id Ch Standard} = {Alphanumeric} + [_] > {Id Ch Extended} = {Printable National} - ['['] - [']'] > > StringLiteral = '"'{String Ch *1*}*'"' | ''{String Ch *2*}*'' > IntegerLiteral = {Digit}+ > RealLiteral = {Digit}+'.'{Digit}+ > > Id = ({Letter}{Id Ch Standard}* | '['{Id Ch Extended}+']' | StringLiteral) > > > Идентификатор (Id) может быть простым, т.е. начинаться с буквы и не > содержать пробелов, национальных символов и т.д., либо может обрамляться > 1 квадратными скобками > 2 кавычками двойными " > 3 одинарными ' > и тогда может содержать в себе все что угодно. > > Т.е. варианты 2 и 3 -- это строка, StringLiteral. > > Так как я записал, грамматика компилируется без ошибок. Когда выполняю > тест, то если использовать квадратные скобки, то все хорошо. Если > идентификатор записать, как строку, т.е. в кавычках, то парсер выдает > ошибку "Токен StringLiteral найден, ожидался Id". > GOLD-ом не пользуюсь. Поэтому из общих соображений, опыта с lex/yacc b и того, но в грамматике видимо присутствует конфликт между StringLiteral и Id. Конфликт возникает либо на уровне лексического анализа (если Id считается терминалом): определение Id через StringLiteral, в этом случае StringLiteral и Id неразличимы, и парсер отдает приоритет первому (например, так делает lex. Причем молча). Либо на уровне синтаксического анализа (если Id - нетерминал): тогда в выражениях будет возникать конфликт между действиями одинакового типа (перенос-перенос, свертка-свертка). Yacc в этих случаях ругается, но парсер генерит, так-же отдавая приоритет первому правилу. > Как правильно грамматику записать для такого случая? > Это зависит от того как используются StringLiteral и Id в грамматике. Из общих соображений и того, что присутствуют правила вида (даже косвенно, с учетом LR(0) ситуаций) Primary = StringLiteral | Id ; Id можно разбить на два независимых терминала, и трансформировать StringLiteral в Id на уровне правила обработки. Или использовать предикаты, если поддерживаются в GOLD. Или внести предикат на уровень лексического анализа. Подобная проблема возникает, например, при использовании LALR(1) в языках типа в C/C++ - конфликт между типом и идентификатором. Разрешается обычно на уровне лексического анализатора, скажем в lex: [_a-zA-Z][_a-zA-Z0-9]* { return is_type_name(yytext) ? TYPE_NAME : IDENT; } Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.11.2007, 13:01 |
|
||
|
Грамматика. BNF
|
|||
|---|---|---|---|
|
#18+
Спасибо. Понятно, но смутно :) Ид и СтрингЛитерал оба терминалы. И действительно получаются неразличимы. teras, а с lemon'ом не работал? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.11.2007, 15:54 |
|
||
|
Грамматика. BNF
|
|||
|---|---|---|---|
|
#18+
Серж wrote: > Спасибо. Понятно, но смутно :) Ид и СтрингЛитерал оба терминалы. И > действительно получаются неразличимы. Вот смотри, рассмотрим такой пример: идентификатор ([a-zA-Z_][a-zA-Z_0-9]*) и ключевое слово (например, while) в типичном языке. Очевидно, что ключевое слово так-же является идентификатором. То есть грамматика содержащий два этих правила в принципе неоднозначна. Другими словами следующий две грамматики lex, читающие со входа "while" вернут разный результат: ======== while return WHILE; [a-zA-Z_][a-zA-Z_0-9]* return IDENT; ======== [a-zA-Z_][a-zA-Z_0-9]* return IDENT; while return WHILE; ======== Во второй грамматике правило для WHILE не сработает никогда. Поэтому, и применяются правила разрешения конфликтов по принципу более раннего объявления. Кстати, flex об этом предупреждает. А вот, скажем, lex - нет. > > teras, а с lemon'ом не работал? Приходилось немного. А что? Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.11.2007, 18:10 |
|
||
|
Грамматика. BNF
|
|||
|---|---|---|---|
|
#18+
Теперь понятнее. У меня есть файлик grammar.y для lemon'а, но посмотрев в него и почитав справку на сайте автора я так и не понял как его использовать. А вообще мне надо представить выражение в каком-либо структурированном виде (дерево, например), чтобы можно было про нему пройти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.11.2007, 18:33 |
|
||
|
Грамматика. BNF
|
|||
|---|---|---|---|
|
#18+
Серж wrote: > Теперь понятнее. > > У меня есть файлик grammar.y для lemon'а, но посмотрев в него и почитав > справку на сайте автора я так и не понял как его использовать. А что именно непонятно? lemon поддерживает только синтаксический анализ. Лексический анализатор к нему нужно писать отдельно. То есть делаешь функцию, читающую файл и разбирающую поток на отдельные лексемы - те самые while, if, ident, number, string, и т.д (или можно каким-нибудь flex). Затем, компилируешь грамматику lemon. Он делает функцию, воспринимающую на входе лексемы (и значения), и производящую синтаксический анализ, в соответствии с грамматикой. Достигнув конца потока эта функция вызывается в последний раз с лексемой 0 (ноль). > > А вообще мне надо представить выражение в каком-либо структурированном > виде (дерево, например), чтобы можно было про нему пройти. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.11.2007, 23:39 |
|
||
|
|

start [/forum/topic.php?fid=16&fpage=154&tid=1345729]: |
0ms |
get settings: |
6ms |
get forum list: |
18ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
42ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
36ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 357ms |

| 0 / 0 |
