ПОМОГИТЕ Лекический анализатор С
Моя первоначальная идея заключалась в создании таблицы указателей на все лексеммы языка, а затем за пару проходов вычислить все попадания этих лексемм и вывести все что надо. (с описанием как и задумывалось )
з.ы заранее спасибо всем кто прявит интерес и хоть чем - то поможет.
Если на С++ то IMHO лучше всего использовать map
А если на С, то нечто подобное придется творить самому.
А на чем?
Если на С++ то IMHO лучше всего использовать map
А если на С, то нечто подобное придется творить самому.
На С++. А разве есть разница? Если да то поясни, что ты хотел сказать? И что такое IMHO?
В С++ определена STL- Standard Template Library
Тебе нужны map и string
string и так понятно
map это аналог справочника - по ключу находишь значение
Если описание - одна строка, то может выглядеть примерно так
(Если описание многострочное, то будет выглядеть немного иначе)
#include <string>
#include <map>
using namespace std;
map<string, string > MyMap; // Определяешь тип
// Собственно таблица
// Заполняешь таблицу
MyMap.insert( make_pair((string)" лексема ", (string)" описание " )); // и так заряжаешь все
//********************************
string MyComment; //Описание
//Ищешь в тексте лексему
string MyLex = .. // То что нашел в тексте
//Проверяешь, лексема ли то что нашел
if ( MyMap.find( MyLex )!= MyMap.end() )
{
MyComment = MyMap[MyLex]; // вытаскиваешь описание
}
else
{
......
}
Вот у меня такие лексемы различает, если надо исходник выложу...
--------------------------------
#define DELIMITER 0x01 //Лексема разделитель
#define VARIABLE 0x02 //Переменная
#define NUMBER 0x04 //Число
#define COMMAND 0x08 //Команда
#define STRING 0x10 //Строка
#define QUOTE 0x20 //Строка в кавычках
#define FINISHED 0x40 // Досрочный конец
#define KEYWORD 0x80 //Ключевое слово
#define EOL 0x00
-------------------------------------
// формула - строка
// вместо CMemFile можно исп. CFile
memfile=new CMemFile;
memfile->SetLength(strlen(formula));
memfile->Write(formula,strlen(formula));
memfile->SeekToBegin();
parser = new CParser(memfile);
while (parser->token()!=toEOF)
{
switch (parser->token())
{
case toSymbol:
// строка - идентиф. или ключ. слово
// получаем через parser->TokenString();
break;
case toInteger:
// целое
// получаем через parser->TokenInt();
break;
case toFloat:
// веществ
// получаем через parser->TokenFloat();
break;
case '-':
case toString: case toWString:
// строка 'пример'
break;
default:
break;
}
parser->NextToken();
}
Есть простой класс по аналогии с дельфийским TParser, очень просто используется
// формула - строка
// вместо CMemFile можно исп. CFile
memfile=new CMemFile;
memfile->SetLength(strlen(formula));
memfile->Write(formula,strlen(formula));
memfile->SeekToBegin();
parser = new CParser(memfile);
while (parser->token()!=toEOF)
{
switch (parser->token())
{
case toSymbol:
// строка - идентиф. или ключ. слово
// получаем через parser->TokenString();
break;
case toInteger:
// целое
// получаем через parser->TokenInt();
break;
case toFloat:
// веществ
// получаем через parser->TokenFloat();
break;
case '-':
case toString: case toWString:
// строка 'пример'
break;
default:
break;
}
parser->NextToken();
}
Всем Спаисбо, буду работать, если что буду спрашивать, но вроде все понятно:)
Возьми интрепретатор Little C из книги Шилдта "Справочник по C" и немного переделай и все
Странно, а в моей книге Г. Шилда - Small Basic вроде...
IMHO это с англ. "По моему скромному мнению"
В С++ определена STL- Standard Template Library
Тебе нужны map и string
string и так понятно
map это аналог справочника - по ключу находишь значение
Если описание - одна строка, то может выглядеть примерно так
(Если описание многострочное, то будет выглядеть немного иначе)
#include <string>
#include <map>
using namespace std;
map<string, string > MyMap; // Определяешь тип
// Собственно таблица
// Заполняешь таблицу
MyMap.insert( make_pair((string)" лексема ", (string)" описание " )); // и так заряжаешь все
//********************************
string MyComment; //Описание
//Ищешь в тексте лексему
string MyLex = .. // То что нашел в тексте
//Проверяешь, лексема ли то что нашел
if ( MyMap.find( MyLex )!= MyMap.end() )
{
MyComment = MyMap[MyLex]; // вытаскиваешь описание
}
else
{
......
}
Я чего то никак понять не могу какой тип будет у My.Map? <string, string> он не съедает, я видимо чего то не так понял. Весь map перерыл запутался совсем.
Я вот так сделал видимо накасячил чего то? Никак разобраться не могу.
typedef map<string, string> PAIR;
void main (void)
{
MyMap.insert( PAIR((string)" asm ", (string)" key word " ));
MyMap.insert( PAIR((string)" auto ", (string)" key word " ));
MyMap.insert( PAIR((string)" break ", (string)" key word " ));
MyMap.insert( PAIR((string)" case ", (string)" key word " ));
и т.д
Я чего то никак понять не могу какой тип будет у My.Map? <string, string> он не съедает, я видимо чего то не так понял. Весь map перерыл запутался совсем.
Я вот так сделал видимо накасячил чего то? Никак разобраться не могу.
typedef map<string, string> PAIR;
void main (void)
{
MyMap.insert( PAIR((string)" asm ", (string)" key word " ));
MyMap.insert( PAIR((string)" auto ", (string)" key word " ));
MyMap.insert( PAIR((string)" break ", (string)" key word " ));
MyMap.insert( PAIR((string)" case ", (string)" key word " ));
и т.д
Где у тебя определен MyMap?
В insert д.б. make_pair, а не PAIR типа мар<string, string>
ДБ так:
#include <string>
#include <map>
using namespace std;
map<string, string > MyMap; // Определяешь тип
// Собственно таблица
// Заполняешь таблицу
MyMap.insert( make_pair((string)" asm ", (string)" key word " )); // и так заряжаешь все
Есть простой класс по аналогии с дельфийским TParser, очень просто используется
// формула - строка
// вместо CMemFile можно исп. CFile
memfile=new CMemFile;
memfile->SetLength(strlen(formula));
memfile->Write(formula,strlen(formula));
memfile->SeekToBegin();
parser = new CParser(memfile);
while (parser->token()!=toEOF)
{
switch (parser->token())
{
case toSymbol:
// строка - идентиф. или ключ. слово
// получаем через parser->TokenString();
break;
case toInteger:
// целое
// получаем через parser->TokenInt();
break;
case toFloat:
// веществ
// получаем через parser->TokenFloat();
break;
case '-':
case toString: case toWString:
// строка 'пример'
break;
default:
break;
}
parser->NextToken();
}
Что это за header такой: #include "obzhee.h" , что в нем?
Где у тебя определен MyMap?
В insert д.б. make_pair, а не PAIR типа мар<string, string>
ДБ так:
#include <string>
#include <map>
using namespace std;
map<string, string > MyMap; // Определяешь тип
// Собственно таблица
// Заполняешь таблицу
MyMap.insert( make_pair((string)" asm ", (string)" key word " )); // и так заряжаешь все
//Идея мне изначально очень понравилась, я даже уже сделал все как надо, вот только в моем случае это не подошло :). Мне необходима посимвольная обработка, а не пословная. А это уже автомат чистейшей воды :) (куча switchей и все такое). Все равно спасибо. Зато теперь знаю как mapом пользоваться.
//Идея мне изначально очень понравилась, я даже уже сделал все как надо, вот только в моем случае это не подошло :). Мне необходима посимвольная обработка, а не пословная. А это уже автомат чистейшей воды :) (куча switchей и все такое). Все равно спасибо. Зато теперь знаю как mapом пользоваться.
На последок.
я бы сделал следующее:
загнал ба все лексемы в map.
в тексте искал бы последовательность символов между двумя разделителями и найденную последовательность искал бы в map'е
if ( MyMap.find(... )!= MyMap.end() )
{
// Нашел
}
И ВСЕ!!!!
никаких тебе switch'ей и все такое
нужно лишь корректно определить разделители согласно синтаксису языка
Что это за header такой: #include "obzhee.h" , что в нем?
Совсем забыл...
В файле общее размещены классы CStack, CUserList и класс пользовательского исключения. Функции ChtenieIzCEdit вроде не нужны.
Прикрепляю полный файл.