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

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(SimpleYacc.yacc)
Строка 3: Строка 3:
 
[http://pascalabc.net/downloads/CompilerConstruction/SimplePas0.zip Комплект разработчика парсеров]
 
[http://pascalabc.net/downloads/CompilerConstruction/SimplePas0.zip Комплект разработчика парсеров]
  
SimpleLex.lex
+
===SimpleLex.lex===
  
<pre>%namespace LexScanner
+
<pre>%namespace SimpleScanner
 +
 
 +
%using SimpleParser;
 +
%using QUT.Gppg;
  
 
Alpha [a-zA-Z_]
 
Alpha [a-zA-Z_]
Строка 16: Строка 19:
 
":=" { return (int)Tokens.ASSIGN; }
 
":=" { return (int)Tokens.ASSIGN; }
 
";" { return (int)Tokens.SEMICOLON; }
 
";" { return (int)Tokens.SEMICOLON; }
 +
"-=" { return (int)Tokens.ASSIGNMINUS; }
 +
"+=" { return (int)Tokens.ASSIGNPLUS; }
 +
"*=" { return (int)Tokens.ASSIGNMULT; }
  
 
{ID}  {  
 
{ID}  {  
Строка 28: Строка 34:
 
   return (int)Tokens.INTNUM;  
 
   return (int)Tokens.INTNUM;  
 
}
 
}
 +
 +
%{
 +
  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
 +
%}
  
 
%%
 
%%
Строка 50: Строка 60:
 
   }
 
   }
 
    
 
    
}</pre>
+
}
 
 
 
 
 
 
 
 
===SimpleYacc.yacc===
 
 
 
<pre>%{
 
// Эти объявления добавляются в класс 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); }
 
;
 
 
%%
 
 
</pre>
 
</pre>

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

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

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

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