Не получается сделать даже простое правило 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();
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.