[PEG] Регистронезависимый парсинг
От: Ka3a4oK  
Дата: 03.05.11 11:36
Оценка:
В каком состоянии находится регистронезависимый парсинг?
Я хочу чтобы, например, строки ниже парсились одинаково.


Где and — ключевое слово.
Re: [PEG] Регистронезависимый парсинг
От: WolfHound  
Дата: 03.05.11 11:49
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>В каком состоянии находится регистронезависимый парсинг?

KK>Я хочу чтобы, например, строки ниже парсились одинаково.

Нужно придумать и сделать синтакис.
Или как вариант прилепить опцию которая сделает все строки регистро независимыми.
Все остальное давно есть.
Правда сейчас придет Влад и будет орать что так делать не надо. И что проще перевести строку в нужный регистр.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: [PEG] Регистронезависимый парсинг
От: Ka3a4oK  
Дата: 03.05.11 11:58
Оценка:
WH>Нужно придумать и сделать синтакис.
WH>Или как вариант прилепить опцию которая сделает все строки регистро независимыми.
WH>Все остальное давно есть.

Мне достаточно, чтобы в функцию TryParse передавался еще один параметр, по которому рещалось как парсить — регистрозависимо или регистронезависимо. Так сейчас сделано в boost::spirit.

WH>Правда сейчас придет Влад и будет орать что так делать не надо. И что проще перевести строку в нужный регистр.

Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.
Re[3]: [PEG] Регистронезависимый парсинг
От: alvas  
Дата: 03.05.11 12:12
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

WH>>Нужно придумать и сделать синтакис.

WH>>Или как вариант прилепить опцию которая сделает все строки регистро независимыми.
WH>>Все остальное давно есть.

KK>Мне достаточно, чтобы в функцию TryParse передавался еще один параметр, по которому рещалось как парсить — регистрозависимо или регистронезависимо. Так сейчас сделано в boost::spirit.


WH>>Правда сейчас придет Влад и будет орать что так делать не надо. И что проще перевести строку в нужный регистр.

KK>Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.

Можно просто в grammar занести два варианта "and" / "AND".
http://alvas.net — Аудио-инструменты для .Net разработчиков
Re[4]: [PEG] Регистронезависимый парсинг
От: Jack128  
Дата: 03.05.11 12:15
Оценка: +1
Здравствуйте, alvas, Вы писали:

A>Можно просто в grammar занести два варианта "and" / "AND".

а так же And и aNd и anD и ANd и aND ?? А не дай бог регистронезависимым окажется слово из 4 букв???
Re[3]: [PEG] Регистронезависимый парсинг
От: WolfHound  
Дата: 03.05.11 12:27
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.

В этом случае в TryParse не подходит. Ибо как ему сказать какое правило парсить регистро зависимо, а какое нет?
К тому же правила компилируются.
И если что-то передавать в TryParse то придется сгенерировать два парсера. Те в 2 раза больше сгенерированного кода, а его и так очень не мало получается.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: [PEG] Регистронезависимый парсинг
От: alvas  
Дата: 03.05.11 12:29
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Здравствуйте, alvas, Вы писали:


A>>Можно просто в grammar занести два варианта "and" / "AND".

J>а так же And и aNd и anD и ANd и aND ?? А не дай бог регистронезависимым окажется слово из 4 букв???

Ну тогда .ToUpper
http://alvas.net — Аудио-инструменты для .Net разработчиков
Re: [PEG] Регистронезависимый парсинг
От: hardcase Пират http://nemerle.org
Дата: 03.05.11 12:30
Оценка: 52 (2)
Здравствуйте, Ka3a4oK, Вы писали:

KK>В каком состоянии находится регистронезависимый парсинг?


Давно сделан.
См на примере Калькулятора из соседнего топика:

using System;
using System.Globalization.CultureInfo;
using System.Linq;
using System.Console;
using SCG = System.Collections.Generic;

using Nemerle.Peg;

[PegGrammar(Options = EmitDebugSource, start, 
grammar
{
  any                   = ['\u0000'..'\uFFFF'];
  s : void              = ' '*;
  num                   : float = ['0'..'9']+ ((',' / '.') ['0'..'9']+)? s;
  parenthesesExpr       : float = "("s expr ")"s;
  func                  : SCG.IEnumerable.[float] -> float = ("max" / "avg" / "sum")s;
  funcExpr              : float = func "("s expr (";"s expr)* ")"s;
  unaryExpr             : float = (("-" / "+")s)* (num / parenthesesExpr / funcExpr);
  multiplicationExpr    : float = unaryExpr ( ("*" / "/")s unaryExpr)*;
  additionExpr          : float = multiplicationExpr ( ("+" / "-")s multiplicationExpr)*;
  expr                  : float = additionExpr;
  start                 : float = s expr !any;
})]
public sealed class CalcParser
{
  private num(integerPart : NToken, floatPart : option[NToken * NToken]) : float
  {
    def number = match(floatPart)
    {
      | Some((_, floatPart)) =>
        GetText(integerPart)
        + InvariantCulture.NumberFormat.NumberDecimalSeparator
        + GetText(floatPart)
      | _ =>
        GetText(integerPart)
    };
    float.Parse(number, InvariantCulture)
  }

  private parenthesesExpr(_ : NToken, se : float, _ : NToken) : float
  {
    se
  }

  private func(name : NToken) : SCG.IEnumerable[float] -> float
  {
    def max(seq)
    {
      mutable acc = float.MinValue;
      foreach(x in seq)
        when(x > acc)
          acc = x;
      otherwise
        acc = float.NaN;
      acc
    }
    def avg(seq)
    {
      mutable acc = .0f;
      mutable count = 0;
      foreach(x in seq)
      {
        acc += x;
        count += 1;
      }
      if(count > 0)
        acc / count
      else
        float.NaN
    }
    def sum(seq)
    {
      mutable acc = .0f;
      foreach(x in seq)
        acc += x;
      otherwise
        acc = float.NaN;
      acc
    }
    match(GetText(name).ToLowerInvariant()) // из GetText приедет оригинальную строку
    {
      | "max" => max
      | "avg" => avg
      | "sum" => sum
      | _ => throw InvalidOperationException()
    }
  }
  
  private funcExpr(func : SCG.IEnumerable[float] -> float, _ : NToken, firstArg : float, tailArgs : SCG.List[NToken * float], _ : NToken) : float
  {
    func([firstArg].Concat(tailArgs.Select(t => t[1])))
  }

  private unaryExpr(unaryOps : SCG.List[NToken], value : float) : float
  {
    mutable acc = value;
    foreach(op in unaryOps)
    {
      match(GetText(op))
      {
        | "+" => ()
        | "-" => acc *= -1
        | _ => throw InvalidOperationException()
      }
    }
    acc
  }

  private multiplicationExpr(head : float, tail : SCG.List[NToken * float]) : float
  {
    mutable acc = head;
    foreach((op, value) in tail)
    {
      match(GetText(op))
      {
        | "*" => acc *= value
        | "/" => acc /= value
        | _ => throw InvalidOperationException()
      }
    }
    acc
  }

  private additionExpr(head : float, tail : SCG.List[NToken * float]) : float
  {
    mutable acc = head;
    foreach((op, value) in tail)
    {
      match(GetText(op))
      {
        | "+" => acc += value
        | "-" => acc -= value
        | _ => throw InvalidOperationException()
      }
    }
    acc
  }
}


module Program
{
  Main() : void
  {
    def parser = CalcParser();
    while(true)
    {
      def input = ReadLine();
      SourceSnapshot(input).WithText(input.ToLowerInvariant()) |> parser.Parse |> WriteLine; // магия!
    }
  }
}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: [PEG] Регистронезависимый парсинг
От: WolfHound  
Дата: 03.05.11 12:55
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Давно сделан.

H>См на примере Калькулятора из соседнего топика:

H>
H>  func                  : SCG.IEnumerable.[float] -> float = ("max" / "avg" / "sum")s;

H>    match(GetText(name).ToLowerInvariant()) // из GetText приедет оригинальную строку
H>    {
H>      | "max" => max
H>      | "avg" => avg
H>      | "sum" => sum
H>      | _ => throw InvalidOperationException()
H>    }
H>  }
H>

А ты проверил? Что-то мне как-то сомнительно что это работает.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: [PEG] Регистронезависимый парсинг
От: Ka3a4oK  
Дата: 03.05.11 12:59
Оценка:
H> SourceSnapshot(input).WithText(input.ToLowerInvariant()) |> parser.Parse |> WriteLine; // магия!

Нельзя ли пояснить, что это за синтаксис?
Re[3]: [PEG] Регистронезависимый парсинг
От: alvas  
Дата: 03.05.11 13:04
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А ты проверил? Что-то мне как-то сомнительно что это работает.


Я проверил — все работает
http://alvas.net — Аудио-инструменты для .Net разработчиков
Re[3]: [PEG] Регистронезависимый парсинг
От: hardcase Пират http://nemerle.org
Дата: 03.05.11 13:05
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А ты проверил? Что-то мне как-то сомнительно что это работает.


Я эту штуку сам и сделал. SourceSnapshot имеет два свойства: Text и OriginalText. Парсер ползет по тексту из Text, а GetText берет строку из OriginalText. В простейшем случае OriginalText и Text — это одна и та же строка. В примере Text заменен на приведенную к нижнему регистру строку, и парсер ползет по ней.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: [PEG] Регистронезависимый парсинг
От: hardcase Пират http://nemerle.org
Дата: 03.05.11 13:07
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

H>> SourceSnapshot(input).WithText(input.ToLowerInvariant()) |> parser.Parse |> WriteLine; // магия!


KK>Нельзя ли пояснить, что это за синтаксис?


Это совершеннейший аналог:
WriteLine(parser.Parse(SourceSnapshot(input).WithText(input.ToLowerInvariant())))


SourceSnapshot — это класс, инкапсулирующий разбираемую парсером строку.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: [PEG] Регистронезависимый парсинг
От: WolfHound  
Дата: 03.05.11 13:20
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Я эту штуку сам и сделал. SourceSnapshot имеет два свойства: Text и OriginalText. Парсер ползет по тексту из Text, а GetText берет строку из OriginalText. В простейшем случае OriginalText и Text — это одна и та же строка. В примере Text заменен на приведенную к нижнему регистру строку, и парсер ползет по ней.

Это страшный костыль ибо:

Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.

(С)
Автор: Ka3a4oK
Дата: 03.05.11
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: [PEG] Регистронезависимый парсинг
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 14:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Это страшный костыль ибо:

WH>

WH>Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.

WH>(С)
Автор: Ka3a4oK
Дата: 03.05.11


На фиг это никому не нужно. Или язык регистронезависимый или зависимый.

В прочем, можешь потом реализовать и свой вариант. От этого хуже не будет. А этот решает проблемы тех кто парсит регистро-независимые языки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [PEG] Регистронезависимый парсинг
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 14:52
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

WH>>Правда сейчас придет Влад и будет орать что так делать не надо. И что проще перевести строку в нужный регистр.

KK>Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.

Владу ходить не нужно. Хардкейс давно все сделал. Регистр тоже никуда не теряется, так как используется две строки. По одной ведется парсинг, а по второй формируются подстроки. Вторая, естественно, является исходной строкой с не измененным регистром, а в первой регистр приводится к нижнему или верхнему регистру.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [PEG] Регистронезависимый парсинг
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 14:57
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Давно сделан.

H>См на примере Калькулятора из соседнего топика:

H>
H>    match(GetText(name).ToLowerInvariant()) // из GetText приедет оригинальную строку
H>    {
H>      | "max" => max
H>      | "avg" => avg
H>      | "sum" => sum
H>      | _ => throw InvalidOperationException()
H>    }
H>  }
H>


А может сделать еще возможность получать доступ и к строке что используется для парсинга? Ну, там придумать еще одну функцию — GetParseText().
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [PEG] Регистронезависимый парсинг
От: alvas  
Дата: 03.05.11 15:22
Оценка:
  func                  : SCG.IEnumerable.[float] -> float = ("max" / "avg" / "sum")s;
  funcExpr              : float = func "("s expr (";"s expr)* ")"s;


Твой код для функции, которая принимает 1..n параметров. Я правильно понял?

Я сделал для функции с 0 параметров и для функции с 1 параметром

  func0                 : void -> float = ("pi" / "rnd")s;
  funcExpr0             : float = func0;
  func1                 : float -> float = ("round")s;
  funcExpr1             : float = func1 "("s expr ")"s;



  private func0(name : NToken) : void -> float
  {
    def pi()
    {
        Math.PI :> float
    }
      
    def rnd()
    {
        Random().NextDouble() :> float
    }

    match(GetText(name).ToLowerInvariant()) // из GetText приедет оригинальную строку
    {
      | "pi" => pi
      | "rnd" => rnd
      | _ => throw InvalidOperationException()
    }
  }

  private funcExpr0(func0 : void -> float) : float
  {
    func0()
  }
  
  private func1(name : NToken) : float -> float
  {
    def round(x)
    {
      //Math.Round(x)
        11.1f;//test
    }
    
    match(GetText(name).ToLowerInvariant()) // из GetText приедет оригинальную строку
    {
      | "round" => round
      | _ => throw InvalidOperationException()
    }
  }

  private funcExpr1(func1 : float -> float, _ : NToken, firstArg : float, _ : NToken) : float
  {
    func1(firstArg)
  }


Все компилится, но не вызывается Подскажи, пожалуйста, что не так
http://alvas.net — Аудио-инструменты для .Net разработчиков
Re[5]: [PEG] Регистронезависимый парсинг
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 15:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Это страшный костыль ибо:

WH>

WH>Тогда мы потеряем регистр там где он важен. В вышеприведенном примере — для строк One и Two.

WH>(С)
Автор: Ka3a4oK
Дата: 03.05.11


Регист идентификаторов никуда не пропадает. Их значения берутся с исходной строки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: [PEG] Регистронезависимый парсинг
От: IT Россия linq2db.com
Дата: 03.05.11 15:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>На фиг это никому не нужно. Или язык регистронезависимый или зависимый.


Взять, например, Sybase T-SQL. Все ключевые слова и, если не ошибаюсь, именя некоторых системных функций регистронезависимые. Имена таблиц, полей, вью, пользовательский функций регистрозависимые.
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.