Грамматика языка Pascal

Материал из Вики проекта PascalABC.NET
Перейти к навигацииПерейти к поиску

--Венцко Александр Зиновьевич 21:11, 21 сентября 2011 (UTC)

Новый вариант

И грамматика и сканер парсятся,готовые классы я выдам завтра на паре, возможны изменения, т.к. общей структуры, пока нет.

Замечание: рабочая группа (Найденов С. Баштанова Д.) сделайте библиотеку, а не консольный проект (это не сложно - 5 минут), так же не смог закачать вашу диаграмму... Рекомендую посмотреть пост создания автоматической документации проекта на Visual Studio 2010 (в старых версиях, тоже есть) [1], чтобы не рисовать каждый раз диаграмму, куда проще делать это на автомате, да и быстрее!

Грамматика

%{
    Dictionary<string,double> vars = new Dictionary<string,double>();
%}
%union { 
	 public int iVal; 
	 public double dVal; 
         public string sVal; 
         public ExprNode eVal;
         public List<ExprNode> elVal;
         public TreeNode tVal;
         public BlockNode lVal;
         public List<string> lsVal;
	 public GreatType dtVal;
       }
%output=PascalYacc.cs 
%using System.IO
%using Syntax_node_tree
%namespace LexScanner
%start progr

%token kBEGIN kEND kIF kTHEN kELSE kWHILE kDO kVAR
%token ASSIGN SEMICOLUMN LPAREN RPAREN COLUMN COLON POINT  
%token PLUS MINUS MULT DIVIDE 
%token AND OR NOT LT GT EQ NE LE GE DIV MOD
%token <iVal> INTNUM 
%token <dVal> REALNUM 
%token <sVal> STRINGLITERAL
%token <sVal> ID
%token <dtVal> kREAL kINTEGER 

%type <eVal> expr
%type <tVal> operator elsepart
%type <lVal> listoperator progr 
%type <lsVal> ident 
%type <elVal> exprlist 
%type <dtVal> ktype kSimpleType

%left LT GT LE GE EQ NE
%left MINUS PLUS OR
%left MULT DIVIDE AND DIV MOD
%left UMINUS NOT

%%

progr   : {}
	| defss kBEGIN listoperator kEND {}
	| error 
	{ 
		System.Console.WriteLine("BAD TEXT!!!");
		break;
	} 
	;

defss : defs 
	|defss defs
	|
	;
	
defs : kVAR ident COLON ktype SEMICOLUMN {}
	;	

ident   : ID {}	
        |ident COLUMN ID {}
	;
	
listoperator    :   operator {}
	|   listoperator SEMICOLUMN operator {}
        ;

ktype : kSimpleType
	| error 
	{ 
		System.Console.WriteLine("BAD GREATE TYPE");
		break;
	}
	;

kSimpleType : kREAL {} 
	| kINTEGER {}
	;

operator: {}
	| ID ASSIGN expr {}
	| kWHILE expr kDO operator {}
	operator {}
	| kIF expr kTHEN operator elsepart {}
	| kBEGIN listoperator kEND {}
        ;

elsepart: {}
	| kELSE operator {}
	;

exprlist : expr {}
	| exprlist COLUMN expr {}
	;

expr:    INTNUM {}
        | REALNUM {}
        | STRINGLITERAL {}
        | ID {}    
    	| expr PLUS expr {}
    	| expr MINUS expr {}
    	| expr MULT expr {}
    	| expr DIVIDE expr {}
    	| expr DIV expr {}
    	| expr MOD expr {}
    	| expr AND expr {}
    	| expr OR expr {}
    	| expr LT expr {}
    	| expr GT expr {}
    	| expr LE expr {}
    	| expr GE expr {}
    	| expr EQ expr {}
    	| expr NE expr {}
    	| NOT expr {}
     	| MINUS expr %prec UMINUS {} 
    	| LPAREN expr RPAREN {}
	;

%%

Сканер

%namespace LexScanner
%using Syntax_node_tree;

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

%x COMMENT
%x COMMENT1

%%

"{" { BEGIN(COMMENT);}
<COMMENT> "}" { BEGIN(INITIAL);}
<COMMENT> <<EOF>> { Console.WriteLine("Комментарий не закрыт");}
"(*" { BEGIN(COMMENT1);}
<COMMENT1> "*)" { BEGIN(INITIAL);}
<COMMENT1> <<EOF>> { Console.WriteLine("Комментарий не закрыт");}

":=" { return (int)Tokens.ASSIGN; }
";" { return (int)Tokens.SEMICOLUMN; }
"-" { return (int)Tokens.MINUS; }
"+" { return (int)Tokens.PLUS; }
"*" { return (int)Tokens.MULT; }
"/" { return (int)Tokens.DIVIDE; }
"<" { return (int)Tokens.LT; }
">" { return (int)Tokens.GT; }
"<=" { return (int)Tokens.LE; }
">=" { return (int)Tokens.GE; }
"=" { return (int)Tokens.EQ; }
"<>" { return (int)Tokens.NE; }
"(" { return (int)Tokens.LPAREN; }
")" { return (int)Tokens.RPAREN; }
"," { return (int)Tokens.COLUMN; }
":" { return (int)Tokens.COLON; }
"." { return (int)Tokens.POINT;  }


\'[^']*\' {
  yylval.sVal = yytext.Substring(1,yytext.Length-2);
  return (int)Tokens.STRINGLITERAL;
}

{ID}  { 
  int res = ScannerHelper.GetIDToken(yytext);
  string s = yytext.ToLower();
  if (s=="integer")
    yylval.dtVal.DType=DataType.INTTYPE;
  if (s == "real")
      yylval.dtVal.DType =DataType.DOUBLETYPE;
  if (res == (int)Tokens.ID)
	yylval.sVal = yytext;
  return res;
}

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

{REALNUM} { 
  yylval.dVal = double.Parse(yytext,new System.Globalization.CultureInfo("en-US")); 
  return (int)Tokens.REALNUM; 
}

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

%%

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

  static ScannerHelper() 
  {
    keywords = new Dictionary<string,int>();
    keywords.Add("var",(int)Tokens.kVAR);
    keywords.Add("real",(int)Tokens.kREAL);
    keywords.Add("integer",(int)Tokens.kINTEGER);
    keywords.Add("begin",(int)Tokens.kBEGIN);
    keywords.Add("end",(int)Tokens.kEND);
    keywords.Add("if",(int)Tokens.kIF);
    keywords.Add("then",(int)Tokens.kTHEN);
    keywords.Add("else",(int)Tokens.kELSE);
    keywords.Add("do",(int)Tokens.kDO);
    keywords.Add("while",(int)Tokens.kWHILE);
    keywords.Add("div",(int)Tokens.DIV);
    keywords.Add("mod",(int)Tokens.MOD);
    keywords.Add("and",(int)Tokens.AND);
    keywords.Add("or",(int)Tokens.OR);
    keywords.Add("not",(int)Tokens.NOT);				
  }
  public static int GetIDToken(string s)
  {
    s = s.ToLower();
	if (keywords.ContainsKey(s))
	{ 
	  return keywords[s];
	}  
	else
      return (int)Tokens.ID;
  }
  
}