Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архив2 / курсовая docx200 / Kursovaya_rabota(23).docx
Скачиваний:
54
Добавлен:
07.08.2013
Размер:
190.22 Кб
Скачать

2.3 Лексический анализатор.

Для задания типа лексемы обычно используется перечисление, включающее в себя все возможные в исходном языке типы: ключевые слова, операторы, идентификаторы и числа.

public enum Lexems

{

None, Name, Number, Begin, End, Multiplication, Division,

Plus, Minus, Equal, NotEqual, Less, LessOrEqual, More, MoreOrEqual, Int,

Print, LeftBracket, RightBracket, Semi, Comma, EOF, Determine,

LongInt, Until, Do, EndUntil

}

Далее создаем отдельную структуру, описывающую данный тип лексемы:

/// <summary>

/// Ключевое слово

/// </summary>

internal struct KeyWord

{

public string word;

public Lexems lex;

}

public static void Initialize()

{

keywords = new KeyWord[10];

keywordPointer = 0;

currentLexem = 0;

currentName = null;

AddKeyword("Begin", Lexems.Begin);

AddKeyword("End", Lexems.End);

AddKeyword("Integer", Lexems.Int);

AddKeyword("Long Integer", Lexems.LongInt);

AddKeyword("Print", Lexems.Print);

AddKeyword("UNTIL", Lexems.Until);

AddKeyword("DO", Lexems.Do);

AddKeyword("ENDUNTIL", Lexems.EndUntil);

}

В рамках класса LexicalAnalyzer будем реализовывать методы лексического анализа: хранение ключевых слов языка и их распознавание, разбор текущей лексемы в зависимости от её типа.

/// <summary>

/// Лексический анализатор

/// </summary>

public static class LexicalAnalyzer

{

private static KeyWord[] keywords;

private static int keywordPointer;

private static string currentName;

private static Lexems currentLexem;

/// <summary>

/// Инициализировать

/// </summary>

public static void Initialize()

{

keywords = new KeyWord[10];

keywordPointer = 0;

currentLexem = 0;

currentName = null;

AddKeyword("Begin", Lexems.Begin);

AddKeyword("End", Lexems.End);

AddKeyword("Integer", Lexems.Int);

AddKeyword("Long Integer", Lexems.LongInt);

AddKeyword("Print", Lexems.Print);

AddKeyword("UNTIL", Lexems.Until);

AddKeyword("DO", Lexems.Do);

AddKeyword("ENDUNTIL", Lexems.EndUntil);

}

/// <summary>

/// Текущее имя

/// </summary>

public static string CurrentName

{

get

{

return currentName;

}

}

/// <summary>

/// Текущая лексема

/// </summary>

public static Lexems CurrentLexem

{

get

{

return currentLexem;

}

}

/// <summary>

/// Добавить ключевое слово

/// </summary>

/// <param name="keyword">слово</param>

/// <param name="lex">лексема</param>

/// <returns></returns>

public static bool AddKeyword(string keyword, Lexems lex)

{

if (keywordPointer < keywords.Length)

{

KeyWord kw = new KeyWord();

kw.word = keyword;

kw.lex = lex;

keywords[keywordPointer++] = kw;

return true;

}

return false;

}

/// <summary>

/// Получить ключевое слово

/// </summary>

/// <param name="keyword">слово</param>

/// <returns></returns>

public static Lexems GetKeyword(string keyword)

{

for (int i = keywordPointer - 1; i >= 0; i--)

{

if (keywords[i].word == keyword)

{

return keywords[i].lex;

}

}

return Lexems.Name;

}

/// <summary>

/// Разоьрать следующую лексему

/// </summary>

public static void ParseNextLexem()

{

while (char.IsWhiteSpace(Reader.CurrentChar))

Reader.ReadNextChar();

if (char.IsLetter(Reader.CurrentChar))

ParseIdentificator();

else if (char.IsDigit(Reader.CurrentChar))

ParseNumber();

else if (Reader.CurrentChar == '\n')

{

Reader.ReadNextChar();

currentLexem = Lexems.None;

}

else if (Reader.CurrentChar == '<')

{

Reader.ReadNextChar();

if (Reader.CurrentChar == '=')

{

Reader.ReadNextChar();

currentName = "<=";

currentLexem = Lexems.LessOrEqual;

}

else

{

currentName = "<";

currentLexem = Lexems.Less;

}

}

else if (Reader.CurrentChar == '>')

{

Reader.ReadNextChar();

if (Reader.CurrentChar == '=')

{

Reader.ReadNextChar();

currentName = ">=";

currentLexem = Lexems.MoreOrEqual;

}

else

{

currentName = ">";

currentLexem = Lexems.More;

}

}

else if (Reader.CurrentChar == '=')

{

Reader.ReadNextChar();

if (Reader.CurrentChar == '=')

{

Reader.ReadNextChar();

currentName = "==";

currentLexem = Lexems.Equal;

}

else

{

currentName = "=";

currentLexem = Lexems.Determine;

}

}

else if (Reader.CurrentChar == '!')

{

Reader.ReadNextChar();

if (Reader.CurrentChar == '=')

{

Reader.ReadNextChar();

currentName = "!=";

currentLexem = Lexems.NotEqual;

}

else

Errors.Error("Неизвестный символ");

}

else if (Reader.CurrentChar == '+')

{

Reader.ReadNextChar();

currentName = "+";

currentLexem = Lexems.Plus;

}

else if (Reader.CurrentChar == '*')

{

Reader.ReadNextChar();

currentName = "*";

currentLexem = Lexems.Multiplication;

}

else if (Reader.CurrentChar == '/')

{

Reader.ReadNextChar();

currentName = "/";

currentLexem = Lexems.Division;

}

else if (Reader.CurrentChar == ',')

{

Reader.ReadNextChar();

currentName = ",";

currentLexem = Lexems.Comma;

}

else if (Reader.CurrentChar == ';')

{

Reader.ReadNextChar();

currentName = ";";

currentLexem = Lexems.Semi;

}

else if (Reader.CurrentChar == '(')

{

Reader.ReadNextChar();

currentName = "(";

currentLexem = Lexems.LeftBracket;

}

else if (Reader.CurrentChar == ')')

{

Reader.ReadNextChar();

currentName = ")";

currentLexem = Lexems.RightBracket;

}

else if (Reader.CurrentChar == char.MinValue)

{

currentName = "EOF";

currentLexem = Lexems.EOF;

}

else

Errors.Error("Недопустимый символ!");

}

/// <summary>

/// Разобрать идентификатор

/// </summary>

private static void ParseIdentificator()

{

string identificator = string.Empty;

int count = 0;

do

{

identificator += Reader.CurrentChar;

if (identificator == "Long")

{

Reader.ReadNextChar();

identificator += Reader.CurrentChar;

count++;

}

Reader.ReadNextChar();

if (++count > 20)

Errors.Error("Chars overflow");

}

while (char.IsLetter(Reader.CurrentChar));

currentName = identificator;

currentLexem = GetKeyword(identificator);

}

/// <summary>

/// Разобрать число

/// </summary>

private static void ParseNumber()

{

string number = string.Empty;

do

{

number += Reader.CurrentChar;

Reader.ReadNextChar();

}

while (char.IsDigit(Reader.CurrentChar));

try

{

Int32.Parse(number);

}

catch (OverflowException)

{

Errors.Error("Не является числом");

}

currentName = number;

currentLexem = Lexems.Number;

}

}

Соседние файлы в папке курсовая docx200