for(int k = 0 ; k < 5.25;k++)
{
cout<<"hello"<<endl;
}
return 0;
Я пишу C ++ программу для лексического анализа на простой текстовый файл, содержащий
С ++ код. Например
Затем, после того как программа извлечет код из файла, она выведет
консоль:
for: keyword
(: separator
int: keyword
k: identifier
=: operator
0: integer
;: separator
k: identifier
<: operator
5.25: real
and so forth.
I already have "(\\w+)" for words, "(\\d+)" for integers, however I don't
know how to write any of the rest.
Чтобы дать вам представление о том, как мой настоящий код выглядит для регулярного выражения, вот оно.
void lexical_integer(string seq)
{
regex digits("(\\d+)");
regex_iterator<string::iterator> itd(seq.begin(), seq.end(), digits);
regex_iterator<string::iterator> end;
for (; itd != end; ++itd)
{
cout << itd->str() <<" " <<" integer"<< endl;
}
}
Я ищу регулярные выражения, которые я могу использовать с регулярным выражением в C ++
так
слова: «(\ w +)» целые числа: «(\ d +)» разделители:?
операторы:
вещественные числа: ?
С Regex будет трудно разобраться, потому что существует некоторое состояние / контекст, который необходимо поддерживать во время tokenizng. Лучше всего, чтобы вы читали ввод за символом и строили токены вручную.
Вот что будет работать для C (подробнее о C ++ позже):
Если ты видишь /
тогда вам нужно смотреть в будущее, и если есть еще /
Пропускаешь все до конца строки.
Если /
сопровождается *
пропускаешь все до другого *
, если следующий после *
символ не /
возвращаешься к пропущенным *
, вы заканчиваете, когда вы подходите к открытию /*
с закрытием */
,
С чем-то подобным вы пропускаете все комментарии.
Если это /
не сопровождается /
или же *
необходимо дополнительно проверить, сопровождается ли =
различать /
а также /=
,
Если вы видите что-то из этого, это токен: ,;?:()[]{}
,
Если ты видишь !
вам нужно смотреть в будущее, потому что это может быть либо !
или же !=
,
Если ты видишь *
вам нужно смотреть в будущее, потому что это может быть либо *
или же *=
,
Если ты видишь %
вам нужно смотреть в будущее, потому что это может быть либо %
или же %=
,
Если ты видишь ^
вам нужно смотреть в будущее, потому что это может быть либо ^
или же ^=
,
Если ты видишь ~
вам нужно смотреть в будущее, потому что это может быть либо ~
или же ~=
,
Если ты видишь +
вам нужно смотреть в будущее, потому что это может быть либо +
или же ++
или же +=
,
Если ты видишь -
вам нужно смотреть в будущее, потому что это может быть либо -
или же --
или же -=
или же ->
,
Если ты видишь <
вам нужно смотреть в будущее, потому что это может быть либо <
или же <=
или же <<
или же <<=
,
Если ты видишь >
вам нужно смотреть в будущее, потому что это может быть либо >
или же >=
или же >>
или же >>=
,
Если ты видишь &
вам нужно смотреть в будущее, потому что это может быть либо &
или же &&
или же &=
,
Если ты видишь |
вам нужно смотреть в будущее, потому что это может быть либо |
или же ||
или же |=
,
Если ты видишь L
(или строчные l
) вам нужно смотреть в будущее, потому что он может начинать буквальный символ или строковую константу L'c'
или же L"string"
, В противном случае это начало некоторого идентификатора.
Если ты видишь _
или ASCII письмо от a
в z
или из A
в Z
это начало некоторого идентификатора. После этого может следовать произвольное количество знаков подчеркивания, букв или десятичных цифр. Обработанные таким образом идентификаторы должны быть дополнительно проверены на соответствие зарезервированным ключевым словам, таким как int
, const
, if
, switch
и т. д.
Если вы видите десятичную цифру от 0
в 9
, у вас есть несколько вариантов: восьмеричная целочисленная константа, десятичная целочисленная константа, шестнадцатеричная целочисленная константа, константа с плавающей точкой. Вы должны быть в состоянии понять, как анализировать их, как описано выше. Помните, что константы могут быть дополнены U
, UL
, ULL
, L
, LL
а также F
,
Если ты видишь .
вам нужно смотреть в будущее, потому что это может быть либо .
или же ...
или что-то вроде .5
,
Я не собираюсь описывать синтаксический анализ и токенизацию буквенных констант или символьных констант, внутри есть еще немного логики с escape-последовательностями и многое другое.
Теперь в C ++ вы должны дополнительно проанализировать такие вещи, как: ::
(продление :
синтаксический анализ), .*
(продление .
синтаксический анализ), ->*
(продление -
разбор) и многие другие зарезервированные слова (например, new
, virtual
и т. д. и т. п. and
, bitor
а также not_eq
).
И есть сюрприз в C ++. Теперь угловые скобки шаблонов могут соединяться без пробелов:
X<Y<Z> >
теперь может быть юридически написано как:
X<Y<Z>>
и синтаксический анализатор должен понимать достаточно этого шаблона бизнеса, чтобы выяснить, что последний >>
это два отдельных >
«S.
Есть также некоторые токены препроцессора (например, #
а также ##
, include
, ifdef
, if
, undef
и т. д.) и уродливые триграфические последовательности. И, конечно же, есть конкатенация строк с \
,
Это забавный маленький (или не очень маленький) проект, который вы можете делать без особых проблем, особенно если вы ограничиваете приемлемое разнообразие входных данных.
В любом случае, вам действительно необходимо внедрить некоторые конечные автоматы в процесс, какими бы простыми они ни были (и большинство из них будут простыми).
Других решений пока нет …