Russian Qt Forum

Qt => Вопросы новичков => Тема начата: gil9red от Декабрь 13, 2012, 22:47



Название: Помогите с RegExp
Отправлено: gil9red от Декабрь 13, 2012, 22:47
Здрасьте! :)
Пишу лексический анализатор языка с++ (не по свое воле, конечно :D),
и для сохранения нервов, воспользовался регулярными выражениями, только мало опыта и знаний, а сдавать уже очень скоро, помогите с регулярными выражениями, для поиска:
  • целых чисел
  • вещественных чисел
  • имен (переменные, функции, классы, структур и т.п.)

для чисел нужен учитывать знак, а также суффиксы F,f, L, l
для вещественных мантиссу
также то, что вещественные могут записаны например так:
Код:
10. 
.023

чтобы не считали, что я обнаглел, скину регулярки, которые сделал (и те, что работают, и те, что не работают :) первые два выражения вроде бы работают):
  • 16-ые числа: -?0[x,X][a-fA-F0-9]+
  • булевые числа: true|false (:D)
  • вещественные и целые числа: -?[0-9]+\.?[0-9]+
  • имена: [_a-zA-Z]+|[a-zA-Z]+[a-zA-Z0-9]+

Спасибо :)


Название: Re: Помогите с RegExp
Отправлено: kambala от Декабрь 13, 2012, 23:01
имена: [_a-zA-Z][_a-zA-Z\d]*
десятичные: -?0|[1-9]\d*(?:L|l){0,2}
восьмеричные: -?0[1-7]+(?:L|l){0,2}

а вообще, синтаксические анализаторы не пишут через регулярки.

P.S. тут знаменитая шутка про решение проблем регулярками.


Название: Re: Помогите с RegExp
Отправлено: gil9red от Декабрь 13, 2012, 23:23
Мой препод предлагал 2 варианта: регулярные выражения или используя генераторы лексических анализаторов, посмотрев на второй вариант, решил что лучше регулярные :)
и проше написать одно регулярное выражение, чем полсотни if else или switch case  :)


Название: Re: Помогите с RegExp
Отправлено: gil9red от Декабрь 13, 2012, 23:38
имена: [_a-zA-Z][_a-zA-Z\d]*
десятичные: -?0|[1-9]\d*(?:L|l){0,2}

что то они не работают правильно О_о

я использую следующий код, для тестирования:
Код:
int main()
{
    float a = 3.2;
    double aa = .3;
    float _A = 1.0E+10;
    _A = 1.0E-10;
   
    bool bValue = true;
    bool bValue2 = false;

    short asb = 0Xaaa;
    asb = 0xAfAf;
    asb = -0xAfAf;

    a = 0.3;
    a = 3.;
    a = 3.0;
    a = -3.0;

    int b = 10;   
    b = -10;
    int bb = 0x10;
                   
                                                                   
   
short ghdfhfd32323j2hkhadjfhskjhKJGHGdsldfkdaslkKPOUHJKNLM223232323 = 0xFFFF;


short 23fdfdfdfdfdfdf = 777;
short чувак1 = 0001;

    char *name = "Bla-bla-bla";
    char n = '\A';

    char m[] = {'/B/0',
                '0xAA'};

    char b[] = {
                '/D/0',
                '0xFF'
               };

    int c = b + bb;
    c++;
    ++c;
    c = (c - c) / 2 * 4;
   
    return 0;     
}

например для имени bValue2, нашлось bValue, 2 куда то затерялась)
или ghdfhfd32323j2hkhadjfhskjhKJGHGdsldfkdaslkKPOUHJKNLM223232323,
нашлось как: ghdfhfd потом j потом hkhadjfhskjhKJGHGdsldfkdaslkKPOUHJKNLM
или 23fdfdfdfdfdfdf нашлось как fdfdfdfdfdfdf, а 23 тоже пропало...

тоже проблемы есть и для парсера десятичных...
похоже тот шаблон только для целых чисел, но и они криво проверились, например
число 10 было найдено как 1 и 0

Может я не точно описал свою просьбу? О_о


Название: Re: Помогите с RegExp
Отправлено: kambala от Декабрь 13, 2012, 23:52
bValue2 и то огромное саблайм нормально находит
23fdfdfdfdfdfdf — это невалидное имя (нельзя, чтобы начиналось с цифр). чтобы исключить такое, допиши в регулярку условие, чтобы первой не стояла цифра
десятичные целые лучше так: -?0|(?:[1-9]\d*)(?:L|l){0,2} , но надо ещё наставить условий, чтобы они не находились внутри дробных, других целых и именах

возможно и не получится создать такие универсальные регулярки


Название: Re: Помогите с RegExp
Отправлено: gil9red от Декабрь 14, 2012, 00:26
bValue2 и то огромное саблайм нормально находит

Все заработало, после того как изменил на [_a-zA-Z][_a-zA-Z0-9]*  :)


Название: Re: Помогите с RegExp
Отправлено: kambala от Декабрь 14, 2012, 00:36
это у тебя какой-то неправильный поисковик, раз \d не распознаёт. или ты забыл проэкранировать обратный слэш.


Название: Re: Помогите с RegExp
Отправлено: gil9red от Декабрь 14, 2012, 00:39
Да, точно, после добавления \ к \d, он начал восприниматься регуляркой :)