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

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Общие комментарии)
(Общие комментарии)
Строка 8: Строка 8:
 
  gplex.exe /unicode SimpleLex.lex
 
  gplex.exe /unicode SimpleLex.lex
 
  gppg.exe /no-lines /gplex SimpleYacc.y
 
  gppg.exe /no-lines /gplex SimpleYacc.y
Параметр /gplex здесь означает, что gppg -
+
Параметр /gplex здесь означает, что gppg работает в связке с gplex.
  
 
===Файл лексического анализатора SimpleLex.lex===
 
===Файл лексического анализатора SimpleLex.lex===

Версия 10:47, 17 августа 2014

К основной странице курса

Общие комментарии

  • В данном проекте мы создадим front-end компилятор с помощью генератора парсеров gppg.
  • Комплект для практического занятия скачиваем отсюда.
  • Для автоматического создания парсера создаются файлы SimpleLex.lex (описание лексического анализатора) и SimpleYacc.y (описание синтаксического анализатора).
  • Код лексического и синтаксического анализаторов создаются на C# запуском командного файла со следующим содержимым:
gplex.exe /unicode SimpleLex.lex
gppg.exe /no-lines /gplex SimpleYacc.y

Параметр /gplex здесь означает, что gppg работает в связке с gplex.

Файл лексического анализатора SimpleLex.lex

%using SimpleParser;
%using QUT.Gppg;
%using System.Linq;

%namespace SimpleScanner

Alpha 	[a-zA-Z_]
Digit   [0-9] 
AlphaDigit {Alpha}|{Digit}
INTNUM  {Digit}+
REALNUM {INTNUM}\.{INTNUM}
ID {Alpha}{AlphaDigit}* 

%%

{INTNUM} { 
  return (int)Tokens.INUM; 
}

{REALNUM} { 
  return (int)Tokens.RNUM;
}

{ID}  { 
  int res = ScannerHelper.GetIDToken(yytext);
  return res;
}

":=" { return (int)Tokens.ASSIGN; }
";"  { return (int)Tokens.SEMICOLON; }

[^ \r\n] {
	LexError();
	return (int)Tokens.EOF; // конец разбора
}

%{
  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol); // позиция символа (терминального или нетерминального), возвращаемая @1 @2 и т.д.
%}

%%

public override void yyerror(string format, params object[] args) // обработка синтаксических ошибок
{
  var ww = args.Skip(1).Cast<string>().ToArray();
  string errorMsg = string.Format("({0},{1}): Встречено {2}, а ожидалось {3}", yyline, yycol, args[0], string.Join(" или ", ww));
  throw new SyntaxException(errorMsg);
}

public void LexError()
{
	string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
    throw new LexException(errorMsg);
}

class ScannerHelper 
{
  private static Dictionary<string,int> keywords;

  static ScannerHelper() 
  {
    keywords = new Dictionary<string,int>();
    keywords.Add("begin",(int)Tokens.BEGIN);
    keywords.Add("end",(int)Tokens.END);
    keywords.Add("cycle",(int)Tokens.CYCLE);
  }
  public static int GetIDToken(string s)
  {
    if (keywords.ContainsKey(s.ToLower())) // язык нечувствителен к регистру
      return keywords[s];
    else
      return (int)Tokens.ID;
  }
}

Комментарии к файлу SimpleLex.lex