Создание парсеров на основе GPLEX+GPPG — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(SimpleYacc.yacc)
(SimpleYacc.yacc)
Строка 139: Строка 139:
  
 
'''Задание 1'''. Визуализировать дерево программы, добавив в каждый узел синтаксического дерева метод ToString
 
'''Задание 1'''. Визуализировать дерево программы, добавив в каждый узел синтаксического дерева метод ToString
 +
 
'''Задание 2.''' Для каждого узла синтаксического дерева реализовать метод Execute, интерпретирующий соответствующее поддерево программы. Таким образом, parser.root.Execute будет интерпретировать всю программу. Для вычисления выражений в каждом узле, производном от ExprNode, реализовать метод Eval, возвращающий целое. Для вычисления значений переменных  
 
'''Задание 2.''' Для каждого узла синтаксического дерева реализовать метод Execute, интерпретирующий соответствующее поддерево программы. Таким образом, parser.root.Execute будет интерпретировать всю программу. Для вычисления выражений в каждом узле, производном от ExprNode, реализовать метод Eval, возвращающий целое. Для вычисления значений переменных  
 
описать
 
описать

Версия 08:36, 10 мая 2012

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

Данный компилятор в виде проекта Visual Studio

SimpleLex.lex

%namespace SimpleScanner

%using SimpleParser;
%using QUT.Gppg;

Alpha 	[a-zA-Z_]
INTNUM  [0-9]+
REALNUM {INTNUM}\.{INTNUM}
ID [a-zA-Z_][a-zA-Z0-9_]* 

%%

":=" { return (int)Tokens.ASSIGN; }
";" { return (int)Tokens.SEMICOLON; }
"-=" { return (int)Tokens.ASSIGNMINUS; }
"+=" { return (int)Tokens.ASSIGNPLUS; }
"*=" { return (int)Tokens.ASSIGNMULT; }

{ID}  { 
  int res = ScannerHelper.GetIDToken(yytext);
  if (res == (int)Tokens.ID)
	yylval.sVal = yytext;
  return res;
}

{INTNUM} { 
  yylval.iVal = int.Parse(yytext); 
  return (int)Tokens.INTNUM; 
}

%{
  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
%}

%%

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;
  }
  
}

SimpleYacc.yacc

%{
// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
    public Dictionary<string,int> vars = new Dictionary<string,int>();
    public ProgrNode root; // Корневой узел синтаксического дерева 
    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
%}

%output = SimpleYacc.cs

%union { 
	public double dVal; 
	public int iVal; 
	public string sVal; 
	public Node nVal;
	public BlockNode blVal;
	public ProgrNode prVal;
       }

%using System.IO;
%using ProgramTree;

%namespace SimpleParser

%start progr

%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON
%token <iVal> INTNUM 
%token <sVal> ID

%type <nVal> expr assign st comp cycl ident
%type <blVal> stlist comp
%type <prVal> progr

%%

progr   : stlist { root = new ProgrNode($1); }
	;

stlist	: st 
	{ 
		$$ = new BlockNode($1 as StatementNode); 
	}
	| stlist SEMICOLON st 
	{ 
		$1.Add($3 as StatementNode); 
		$$ = $1; 
	}
	;

st	: assign { $$ = $1; }
	| comp  { $$ = $1; }
	| cycl  { $$ = $1; }
	;

ident : ID { $$ = new IdNode($1); }	
	;
	
assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode,$3 as ExprNode,0); }
	;

expr	: ident  { $$ = $1 as IdNode; }
	| INTNUM { $$ = new NumNode($1); }
	;

comp	: BEGIN stlist END { $$ = $2; }
	;

cycl	: CYCLE expr st { $$ = new CycleNode($2 as ExprNode,$3 as StatementNode); }
	;
	
%%

Задание 1. Визуализировать дерево программы, добавив в каждый узел синтаксического дерева метод ToString

Задание 2. Для каждого узла синтаксического дерева реализовать метод Execute, интерпретирующий соответствующее поддерево программы. Таким образом, parser.root.Execute будет интерпретировать всю программу. Для вычисления выражений в каждом узле, производном от ExprNode, реализовать метод Eval, возвращающий целое. Для вычисления значений переменных описать

    public Dictionary<string,int> vars = new Dictionary<string,int>();

и заносить значения переменных в этот словарь.

Для визуализации работы программы после окончания программы выводить значения всех переменных.