Не получается сделать даже простое правило Peg :(
От: VinnyPuh  
Дата: 11.04.11 16:42
Оценка:
Привет всем.

Пытаюсь сделать простое правило Peg (полный код ниже), просто подставляющее в исходную строку вида "Identificator 987654321" префиксы, подтверждающие правильный парсинг, в виде "id:Identificator in:987654321"

Исходная строка такая "iasodurirsadrhf 983475"
Ожидается на выходе "id:iasodurirsadrhf in:983475"

Компилирую
ncc code/1.n -o bin/1.exe -r PowerPack/Nemerle.Peg.dll -r PowerPack/Nemerle.Peg.Macros.dll

Запускаю из консоли
C:\Nemerle>bin\1.exe
Some ( id:'iasodurirsadrhf' id:'983475')
Закончено

--------------------------
Неверное выделено жирным. Почему — понять не могу.

Предполагается, что выражение
start: string = (Identifier / integer)*;

парсит сначала идентификатор (например, начиная со строки "983475"), натыкаясь на правило
Identifier:string = !NotFirstIdentifierSymbol IdentifierSymbol+ s;

и, первым делом, проверяет невыполнение правила
NotFirstIdentifierSymbol = notAny / digit;


т.е. проверяет
!(notAny / digit)

т.е. проверяет, что первый символ '9' принадлежит notAny — нет, цифры не принадлежат notAny
затем проверяет что символ '9' принадлежит digit — да принадлежит
Правило истинно, а для продолжения выполнения правила
Identifier:string = !NotFirstIdentifierSymbol IdentifierSymbol+ s;

необходимо, чтобы NotFirstIdentifierSymbol было ложным. Значит, это не Identifier, но выводится всё равно с префиксом "id:"

Что я делаю не так?

Полный код:
using Nemerle.Collections;
using Nemerle.Peg;
using Nemerle.Text;
using Nemerle.Utility;
using Nemerle;

using System;
using System.Collections.Generic;
using SCG = System.Collections.Generic;

// ncc code/1.n -o bin/1.exe -r PowerPack/Nemerle.Peg.dll -r PowerPack/Nemerle.Peg.Macros.dll

namespace buildParser
{
  [PegGrammar(start,
  grammar
  {
    any                   = ['\u0000'..'\uFFFF'];
    s : void              = ' '*;
    digit                  = ('0' .. '9');
    integer:string          = digit+ s;

    notAny                  = ('\\'
                            / '|'
                            /  ','
                            / '.'
                            / '?'
                            / ';'
                            / ':'

                            / '['
                            / ']'
                            / '('
                            / ')'
                            / '{'
                            / '}'
                            
                            / '+'
                            / '-'
                            / '*'
                            / '/'
                            / '='
                            / '<'
                            / '>'

                            / '&'
                            / '^'
                            / '%'
                            / '$'
                            / '#'
                            / '@'
                            / '!'
                            / '~'
                            / '`'
                            / '\''
                            / '\"'
                            / '_'

                            / ' '
                            / '\t'

                            / '\r'
                            / '\n'
                            );

    NotFirstIdentifierSymbol    = notAny / digit;
    IdentifierSymbol            = (&'_' / !notAny) any;
    Identifier:string            = !NotFirstIdentifierSymbol IdentifierSymbol+ s;

    start: string                = (Identifier / integer)*;
  })]
    public class BuildParser
    {
        Identifier(token: NToken) : string
        {
            def s = GetText(token);
            $" id:'$s'";
        }

        integer(token:  NToken) : string
        {
            " in:'" + GetText(token) + "'";
        }

        start(strs: List[string]): string
        {
            def e = strs.GetEnumerator();
            def a(b)
            {
                match (e.MoveNext())
                {
                    | false => b
                    | _ => a(b + e.Current)
                }
            };

            a("")
        }
    }
}

    def bp = buildParser.BuildParser();
    Console.WriteLine(bp.Parse("iasodurirsadrhf 983475"));
    Console.Write("Закончено");
_ = Console.ReadLine();
Re: Сам разобрался
От: VinnyPuh  
Дата: 11.04.11 17:40
Оценка:
Здравствуйте, VinnyPuh, Вы писали:


VP>Что я делаю не так?


VP>Полный код:

VP>
VP>namespace buildParser
VP>{
VP>  [PegGrammar(start,
VP>  grammar
VP>  {
VP>    any                   = ['\u0000'..'\uFFFF'];
VP>    s : void              = ' '*;
VP>    digit                  = ('0' .. '9');
VP>    integer:string          = digit+ s;
VP>


надо

VP>
VP>namespace buildParser
VP>{
VP>  [PegGrammar(start,
VP>  grammar
VP>  {
VP>    any                   = ['\u0000'..'\uFFFF'];
VP>    s : void              = ' '*;
VP>    digit                  = ['0' .. '9'];
VP>    integer:string          = digit+ s;
VP>
Re: Не получается сделать даже простое правило Peg :(
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.11 17:51
Оценка:
Здравствуйте, VinnyPuh, Вы писали:

VP>Пытаюсь сделать простое правило Peg (полный код ниже), просто подставляющее в исходную строку вида "Identificator 987654321" префиксы, подтверждающие правильный парсинг, в виде "id:Identificator in:987654321"


Зачем делать все так через ухо? Для разбора указанной строки можно написать примитивнейшую грамматику.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Сам разобрался
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.11 17:52
Оценка:
Здравствуйте, VinnyPuh, Вы писали:

VP>>
VP>VP>    digit                  = ('0' .. '9');
VP>>

VP>надо
VP>>
VP>>    digit                  = ['0' .. '9'];
VP>>


При компиляции первого варианта сообщений об ошибках не было? Если, да, то это баг.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Не получается сделать даже простое правило Peg :(
От: catbert  
Дата: 11.04.11 18:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Зачем делать все так через ухо? Для разбора указанной строки можно написать примитивнейшую грамматику.


Регекс даже.
Re[3]: Не получается сделать даже простое правило Peg :(
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.11 19:02
Оценка:
Здравствуйте, catbert, Вы писали:

VD>>Зачем делать все так через ухо? Для разбора указанной строки можно написать примитивнейшую грамматику.


C>Регекс даже.


Регекс и есть грамматика, только записанная на нечеловеческом зыке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сам разобрался
От: VinnyPuh  
Дата: 12.04.11 10:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>При компиляции первого варианта сообщений об ошибках не было? Если, да, то это баг.


Влад, всё чисто компилировалось как в версии из дистрибутива с установщиком, так и в версии, которую я сам собрал из trunc
Re[2]: Не получается сделать даже простое правило Peg :(
От: VinnyPuh  
Дата: 12.04.11 10:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Зачем делать все так через ухо? Для разбора указанной строки можно написать примитивнейшую грамматику.


Ну я же не буду начинать со сложной грамматики: я просто изучаю возможности — раз уж с ней возникли проблемы, то что было бы, начни я сразу со сложной грамматики?
Re[4]: Сам разобрался
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.11 13:49
Оценка:
Здравствуйте, VinnyPuh, Вы писали:

VD>>При компиляции первого варианта сообщений об ошибках не было? Если, да, то это баг.


VP>Влад, всё чисто компилировалось как в версии из дистрибутива с установщиком, так и в версии, которую я сам собрал из trunc


В общем, это баг. Я уже его поправил.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Не получается сделать даже простое правило Peg :(
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.11 13:51
Оценка:
Здравствуйте, VinnyPuh, Вы писали:

VD>>Зачем делать все так через ухо? Для разбора указанной строки можно написать примитивнейшую грамматику.


VP>Ну я же не буду начинать со сложной грамматики: я просто изучаю возможности — раз уж с ней возникли проблемы, то что было бы, начни я сразу со сложной грамматики?


Я говорил про саму грамматику. Она исходит из того чем символ не является. При наличии в арсенале юникода нескольких десятков тысяч символов — это не очень разумный полход. Проще все же исходить из соображений "чем является идентификатор". Если нужна поддержка юникода, то для этого есть специальные средства (юникодные классы).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Не получается сделать даже простое правило Peg :(
От: VinnyPuh  
Дата: 12.04.11 14:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я говорил про саму грамматику. Она исходит из того чем символ не является. При наличии в арсенале юникода нескольких десятков тысяч символов — это не очень разумный подход. Проще все же исходить из соображений "чем является идентификатор". Если нужна поддержка юникода, то для этого есть специальные средства (юникодные классы).


В статье
Автор(ы): Чистяков Владислав Юрьевич
Дата: 07.06.2011
Макрос PegGrammar – это макрос Nemerle, позволяющий добавлять в приложения парсеры, описываемые в нотации PEG.
такого нет, а подробнее я пока не разбирался.
Re[5]: Не получается сделать даже простое правило Peg :(
От: hardcase Пират http://nemerle.org
Дата: 12.04.11 14:50
Оценка:
Здравствуйте, VinnyPuh, Вы писали:

VP>В статье
Автор(ы): Чистяков Владислав Юрьевич
Дата: 07.06.2011
Макрос PegGrammar – это макрос Nemerle, позволяющий добавлять в приложения парсеры, описываемые в нотации PEG.
такого нет, а подробнее я пока не разбирался.


Да как нет?

Ranges (диапазоны)

Список диапазонов символов или сокращений имен Unicode-категории.

Примеры:

['0'..'9']
['\u0000'..'\uFFFF']
['A'..'Z', 'a' .. 'z', '\u037F' .. '\u1FFF']
[Lu, Ll, Lt, Lm, Lo, Nl]

/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Не получается сделать даже простое правило Peg :(
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.11 14:59
Оценка: 1 (1)
Здравствуйте, VinnyPuh, Вы писали:

VP>В статье
Автор(ы): Чистяков Владислав Юрьевич
Дата: 07.06.2011
Макрос PegGrammar – это макрос Nemerle, позволяющий добавлять в приложения парсеры, описываемые в нотации PEG.
такого нет, а подробнее я пока не разбирался.


Ну, как же нет? Сделай поиск по слову Unicode. Единственное что... почему-то в HTML-версии статьи отвалилась ссылка на описания сокращений находящееся в МСДН-е. Вот эта ссылка:
http://msdn.microsoft.com/ru-ru/library/system.globalization.unicodecategory.aspx
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Не получается сделать даже простое правило Peg :(
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.11 15:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, как же нет? Сделай поиск по слову Unicode. Единственное что... почему-то в HTML-версии статьи отвалилась ссылка на описания сокращений находящееся в МСДН-е. Вот эта ссылка:

VD>http://msdn.microsoft.com/ru-ru/library/system.globalization.unicodecategory.aspx

Обновил статью. Так что теперь в ней есть ссылка.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.