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