Грамматика языка Pascal: различия между версиями
Материал из Вики проекта PascalABC.NET
Перейти к навигацииПерейти к поиску
AlexHit (обсуждение | вклад) мНет описания правки |
AlexHit (обсуждение | вклад) Нет описания правки |
||
Строка 123: | Строка 123: | ||
%% | %% | ||
</pre> | |||
'''Предварительный сканер''' | |||
<pre> | |||
%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; | |||
} | |||
} | |||
</pre> | </pre> |
Версия от 23:45, 21 сентября 2011
Новый вариант
%{ 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; } }