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

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
м (SimpleYacc.yacc)
(SimpleYacc.yacc)
Строка 58: Строка 58:
  
 
<pre>%{
 
<pre>%{
    Dictionary<string,double> vars = new Dictionary<string,double>();
+
// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
     ProgrNode root;
+
     public ProgrNode root; // Корневой узел синтаксического дерева
 +
    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
 
%}
 
%}
  
 
%output = SimpleYacc.cs
 
%output = SimpleYacc.cs
  
%union { public double dVal;  
+
%union {  
        public int iVal;  
+
public double dVal;  
        public string sVal;  
+
public int iVal;  
        public Node nVal;
+
public string sVal;  
        public StatementList stlistVal ;
+
public Node nVal;
        }
+
public BlockNode blVal;
 +
public ProgrNode prVal;
 +
      }
  
%using System.IO
+
%using System.IO;
 +
%using ProgramTree;
  
 
+
%namespace SimpleParser
%namespace LexScanner
 
  
 
%start progr
 
%start progr
  
%token BEGIN END CYCLE ASSIGN SEMICOLON
+
%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON
 
%token <iVal> INTNUM  
 
%token <iVal> INTNUM  
 
%token <sVal> ID
 
%token <sVal> ID
  
%type <nVal> expr assign st comp cycl  
+
%type <nVal> expr assign st comp cycl ident
%type <stlistVal> stlist
+
%type <blVal> stlist comp
 
+
%type <prVal> progr
  
 
%%
 
%%
  
progr  : stlist {root = new ProgrNode(new BlockNode($1));}
+
progr  : stlist { root = new ProgrNode($1); }
;
+
;
  
stlist : st { $$ = new StatementList($1);}
+
stlist : st  
| stlist SEMICOLON st {$1.Add($3); $$=$1;}
+
{  
;
+
$$ = new BlockNode($1 as StatementNode);  
 +
}
 +
| stlist SEMICOLON st  
 +
{  
 +
$1.Add($3 as StatementNode);  
 +
$$ = $1;  
 +
}
 +
;
  
st : assign {$$=$1;}
+
st : assign { $$ = $1; }
| comp {$$=$1;}
+
| comp { $$ = $1; }
| cycl {$$=$1;}
+
| cycl { $$ = $1; }
 
;
 
;
  
assign : ID ASSIGN expr {$$ = new AssignNode($1 as IDNode,$3 as ExprNode,AssignOpType.lexAssign);}
+
ident : ID { $$ = new IdNode($1); }
 
;
 
;
 +
 +
assign : ident ASSIGN expr { $$ = new AssignNode($1 as IdNode,$3 as ExprNode,0); }
 +
;
  
expr : ID {$$ = new IDNode($1);}
+
expr : ident  { $$ = $1 as IdNode; }
| INTNUM {$$ = new NumNode($1);}
+
| INTNUM { $$ = new NumNode($1); }
;
+
;
  
comp : BEGIN stlist END {}
+
comp : BEGIN stlist END { $$ = $2; }
;
+
;
 
 
cycl : CYCLE expr st {}
 
;
 
  
 +
cycl : CYCLE expr st { $$ = new CycleNode($2 as ExprNode,$3 as StatementNode); }
 +
;
 +
 
%%
 
%%
 
 
</pre>
 
</pre>

Версия 10:00, 9 мая 2012

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

Комплект разработчика парсеров

SimpleLex.lex

%namespace LexScanner

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

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

%%

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