Грамматика языка 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; } }