Грамматика C + Код: различия между версиями
Материал из Вики проекта PascalABC.NET
Перейти к навигацииПерейти к поиску
Extremall (обсуждение | вклад) (Новая: <source lang=""> progr: { $$ = new Program(@$); } | progr OperatorSequence { for (int i = 0; i < $2.list.Count) $1.list.Add($2.list[i]); $$ = $1; } ; Operator: def { $$ ...) |
Ksanderer (обсуждение | вклад) Нет описания правки |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 1: | Строка 1: | ||
C.Y | |||
<source lang=""> | <source lang=""> | ||
progr: { | %{ | ||
Dictionary<string,double> vars = new Dictionary<string,double>(); | |||
%} | |||
%output=Yacc.cs | |||
%union { | |||
public int iVal; | |||
public double dVal; | |||
public string sVal; | |||
public ExprNode eVal; | |||
public TreeNode tVal; | |||
public BlockNode lVal; | |||
public List<string> lsVal; | |||
public GreatType dtVal; | |||
} | |||
%using System.IO | |||
%using Syntax_node_tree | |||
%namespace LexScanner | |||
%start progr | |||
%token kBEGIN kEND kIF kTHEN kELSE kWHILE kWRITE | |||
%token ASSIGN SEMICOLUMN LPAREN RPAREN COLUMN | |||
%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 kBOOLEAN | |||
%type <eVal> expr | |||
%type <tVal> operator elsepart | |||
%type <lVal> listoperator progr | |||
%type <lsVal> ident | |||
%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 : | |||
{ | |||
$$ = new Program(@$); | $$ = new Program(@$); | ||
} | } | ||
| | | defss kBEGIN listoperator kEND | ||
{ | |||
$$ = $1; | $$ = $1; | ||
foreach (Operator oper in $3.list) | |||
$$.list.Add(oper); | |||
} | } | ||
| error | |||
{ | |||
System.Console.WriteLine("BAD TEXT!!!"); | |||
break; | |||
} | |||
; | ; | ||
defss : defs | |||
{ | |||
$$ = new BlockOperator(@$); | $$ = new BlockOperator(@$); | ||
$$.list.Add($1); | |||
} | } | ||
| | |defss defs { | ||
$1.list.Add($2); | $1.list.Add($2); | ||
$$ = $1; | $$ = $1; | ||
} | } | ||
| | |||
; | ; | ||
defs : ktype ident SEMICOLUMN | |||
{ | |||
TipType type; | TipType type; | ||
if ($1 == "int") | if ($1 == "int") | ||
Строка 52: | Строка 87: | ||
else | else | ||
{ | { | ||
// Error: unknown type | |||
} | } | ||
$$ = new VarDef(@$, $2, type); | $$ = new VarDef(@$, $2, type); | ||
} | } | ||
; | ; | ||
ident: ID | |||
{ | |||
if (GlobalStructures.isNameExists($1)) | if (GlobalStructures.isNameExists($1)) | ||
{ | { | ||
Строка 67: | Строка 103: | ||
$$ = new List<Ident>(); | $$ = new List<Ident>(); | ||
$$.Add(Id); | $$.Add(Id); | ||
} | } | ||
| | |ident COLUMN ID | ||
{ | |||
if (GlobalStructures.isNameExists($3)) | if (GlobalStructures.isNameExists($3)) | ||
{ | { | ||
// Error: this name is already used | |||
} | } | ||
Ident Id = new Ident($3, @3); | Ident Id = new Ident($3, @3); | ||
Строка 79: | Строка 116: | ||
} | } | ||
; | ; | ||
listoperator : operator | |||
{ | |||
$$ = new BlockOperator(@$); | |||
$$.list.Add($1); | |||
} | |||
| listoperator SEMICOLUMN operator { | |||
$1.list.Add($2); | |||
$$ = $1; | |||
} | |||
; | |||
ktype : kSimpleType | |||
| error | |||
{ | |||
System.Console.WriteLine("BAD GREATE TYPE"); | |||
break; | |||
} | |||
; | |||
kSimpleType : kREAL | |||
{ | |||
$$ = "double"; | |||
} | |||
| kINTEGER | |||
{ | |||
$$ = "int"; | |||
} | |||
| kBOOLEAN | |||
{ | |||
$$ = "bool" | |||
} | |||
; | |||
operator: {} | |||
| ID ASSIGN expr | |||
{ | |||
if (!GlobalStructures.isNameExists($1)) | if (!GlobalStructures.isNameExists($1)) | ||
{ | { | ||
// Error: Undeclarated identifier | // Error: Undeclarated identifier | ||
} | } | ||
Ident Id = GlobalStructures.getIdentByName($1); | |||
$$ = new Assign(Id, $3, @3); | |||
} | } | ||
; | | kWHILE LPAREN expr RPAREN operator | ||
{ | |||
expr | if ($2.getType()!=TypType.Boolean) | ||
{ | |||
if ( | // Error: Oneiaea aie?ii eiaou eiae?aneee oei | ||
} | |||
$$ = new While($2, $4, @$); | |||
} | |||
| kIF LPAREN expr RPAREN operator elsepart | |||
{ | |||
if ($2.getType()!=TypType.Boolean) | |||
{ | { | ||
// Error: | // Error: Oneiaea aie?ii eiaou eiae?aneee oei | ||
} | } | ||
$$ = new | $$=new If($2,$4,$5,@$); | ||
} | |||
| kBEGIN listoperator kEND | |||
{ | |||
$$ = $2; | |||
} | |||
| kWRITE LPAREN expr RPAREN | |||
{ | |||
System.Console.Write($3); | |||
} | |||
; | |||
elsepart: | |||
{ | |||
$$ = null; | |||
} | |||
| kELSE operator { | |||
$$ = $2; | |||
} | } | ||
; | |||
expr: INTNUM | |||
{ | |||
int i = int.Parse($1); | int i = int.Parse($1); | ||
$$ = new IntConst(i, @1); | $$ = new IntConst(i, @1); | ||
} | } | ||
| REALNUM { | | REALNUM | ||
{ | |||
double d = double.Parse($1); | double d = double.Parse($1); | ||
$$ = new DoubleConst(d, @1); | $$ = new DoubleConst(d, @1); | ||
} | } | ||
| | | STRINGLITERAL | ||
{ | |||
// Iao o ian oaeeo!!! | |||
} | } | ||
| | | ID | ||
{ | |||
if (!GlobalStructures.isNameExists($1)) | |||
if ( | |||
{ | { | ||
// Error: | // Error: Undeclarated identifier | ||
} | } | ||
$$ = new | $$ = new Ident($1, @1); | ||
} | } | ||
| | | expr PLUS expr | ||
{ | |||
$$ = new BinExpression($1, $3, Op.Plus, @$); | $$ = new BinExpression($1, $3, Op.Plus, @$); | ||
} | } | ||
| expr MINUS expr { | | expr MINUS expr | ||
{ | |||
$$ = new BinExpression($1, $3, Op.Minus, @$); | $$ = new BinExpression($1, $3, Op.Minus, @$); | ||
} | } | ||
| expr MULT expr { | | expr MULT expr | ||
{ | |||
$$ = new BinExpression($1, $3, Op.Mult, @$); | $$ = new BinExpression($1, $3, Op.Mult, @$); | ||
} | } | ||
| expr DIVIDE expr { | | expr DIVIDE expr | ||
{ | |||
$$ = new BinExpression($1, $3, Op.Divide, @$); | $$ = new BinExpression($1, $3, Op.Divide, @$); | ||
} | } | ||
| expr | | expr DIV expr | ||
{ | |||
// Ia iiaaa??eaaaony! | |||
} | } | ||
| expr | | expr MOD expr | ||
{ | |||
// Ia iiaaa??eaaaony! | |||
} | } | ||
| expr LT expr { | | expr AND expr | ||
{ | |||
if ($1.getType() != TipType.BoolType || $2.getType() != TipType.BoolType) | |||
{ | |||
// Error: only for bool types | |||
} | |||
$$ = new BinExpression($1, $3, Op.And, @$); | |||
} | |||
| expr OR expr | |||
{ | |||
if ($1.getType() != TipType.BoolType || $2.getType() != TipType.BoolType) | |||
{ | |||
// Error: only for bool types | |||
} | |||
$$ = new BinExpression($1, $3, Op.Or, @$); | |||
} | |||
| expr LT expr | |||
{ | |||
$$ = new BinExpression($1, $3, Op.Less, @$); | $$ = new BinExpression($1, $3, Op.Less, @$); | ||
} | } | ||
| expr LE expr { | | expr GT expr | ||
{ | |||
$$ = new BinExpression($1, $3, Op.More, @$); | |||
} | |||
| expr LE expr | |||
{ | |||
$$ = new BinExpression($1, $3, Op.LessEqual, @$); | $$ = new BinExpression($1, $3, Op.LessEqual, @$); | ||
} | } | ||
| expr | | expr GE expr | ||
$$ = new BinExpression($1, $3, Op. | { | ||
$$ = new BinExpression($1, $3, Op.MoreEqual, @$); | |||
} | |||
| expr EQ expr | |||
{ | |||
$$ = new BinExpression($1, $3, Op.Equal, @$); | |||
} | } | ||
| expr | | expr NE expr | ||
$$ = new BinExpression($1, $3, Op. | { | ||
$$ = new BinExpression($1, $3, Op.NotEqual, @$); | |||
} | } | ||
| NOT expr | |||
{ | |||
if ($2.getType() != TipType.BoolType) | |||
if ($ | |||
{ | { | ||
// Error: type is wrong. | |||
} | } | ||
$$=new | $$ = new UnarExpression($2, Op.Not, @2); | ||
} | } | ||
| MINUS expr %prec UMINUS | |||
{ | |||
if ($2.getType() != TipType.IntType && $2.getType() != TipType.DoubleType) | |||
| | |||
if ($ | |||
{ | { | ||
// Error: type is wrong. | |||
} | } | ||
$$ = new | $$ = new UnarExpression($2, Op.Minus, @2); | ||
}</source> | } | ||
| LPAREN expr RPAREN | |||
{ | |||
$$ = $2; | |||
} | |||
; | |||
%% | |||
</source> | |||
C.LEX | |||
<source lang=""> | |||
%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("Комментарий не закрыт");} | |||
"=" { 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.POINT; } | |||
\'[^']*\' { | |||
yylval.sVal = yytext.Substring(1,yytext.Length-2); | |||
return (int)Tokens.STRINGLITERAL; | |||
} | |||
{ID} { | |||
int res = ScannerHelper.GetIDToken(yytext); | |||
if (s=="int") | |||
yylval.dtVal.DType=DataType.INTTYPE; | |||
if (s == "double") | |||
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("double",(int)Tokens.kREAL); | |||
keywords.Add("int",(int)Tokens.kINTEGER); | |||
keywords.Add("bool",(int)Tokens.kBOOLEAN); | |||
keywords.Add("{",(int)Tokens.kBEGIN); | |||
keywords.Add("}",(int)Tokens.kEND); | |||
keywords.Add("if",(int)Tokens.kIF); | |||
keywords.Add("else",(int)Tokens.kELSE); | |||
keywords.Add("while",(int)Tokens.kWHILE); | |||
keywords.Add("cout",(int)Tokens.kWRITE); | |||
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) | |||
{ | |||
if (keywords.ContainsKey(s)) | |||
{ | |||
return keywords[s]; | |||
} | |||
else | |||
return (int)Tokens.ID; | |||
} | |||
} | |||
</source> |
Текущая версия от 14:12, 6 октября 2011
C.Y
%{
Dictionary<string,double> vars = new Dictionary<string,double>();
%}
%output=Yacc.cs
%union {
public int iVal;
public double dVal;
public string sVal;
public ExprNode eVal;
public TreeNode tVal;
public BlockNode lVal;
public List<string> lsVal;
public GreatType dtVal;
}
%using System.IO
%using Syntax_node_tree
%namespace LexScanner
%start progr
%token kBEGIN kEND kIF kTHEN kELSE kWHILE kWRITE
%token ASSIGN SEMICOLUMN LPAREN RPAREN COLUMN
%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 kBOOLEAN
%type <eVal> expr
%type <tVal> operator elsepart
%type <lVal> listoperator progr
%type <lsVal> ident
%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 :
{
$$ = new Program(@$);
}
| defss kBEGIN listoperator kEND
{
$$ = $1;
foreach (Operator oper in $3.list)
$$.list.Add(oper);
}
| error
{
System.Console.WriteLine("BAD TEXT!!!");
break;
}
;
defss : defs
{
$$ = new BlockOperator(@$);
$$.list.Add($1);
}
|defss defs {
$1.list.Add($2);
$$ = $1;
}
|
;
defs : ktype ident SEMICOLUMN
{
TipType type;
if ($1 == "int")
type = TipType.IntType;
else if ($1 == "double")
type = TipType.DoubleType;
else if ($1 == "bool")
type = TipType.BoolType;
else
{
// Error: unknown type
}
$$ = new VarDef(@$, $2, type);
}
;
ident: ID
{
if (GlobalStructures.isNameExists($1))
{
// Error: this name is already used
}
Ident Id = new Ident($1, @1);
listVars.Add(Id);
$$ = new List<Ident>();
$$.Add(Id);
}
|ident COLUMN ID
{
if (GlobalStructures.isNameExists($3))
{
// Error: this name is already used
}
Ident Id = new Ident($3, @3);
listVars.Add(Id);
$1.Add(Id);
$$ = $1;
}
;
listoperator : operator
{
$$ = new BlockOperator(@$);
$$.list.Add($1);
}
| listoperator SEMICOLUMN operator {
$1.list.Add($2);
$$ = $1;
}
;
ktype : kSimpleType
| error
{
System.Console.WriteLine("BAD GREATE TYPE");
break;
}
;
kSimpleType : kREAL
{
$$ = "double";
}
| kINTEGER
{
$$ = "int";
}
| kBOOLEAN
{
$$ = "bool"
}
;
operator: {}
| ID ASSIGN expr
{
if (!GlobalStructures.isNameExists($1))
{
// Error: Undeclarated identifier
}
Ident Id = GlobalStructures.getIdentByName($1);
$$ = new Assign(Id, $3, @3);
}
| kWHILE LPAREN expr RPAREN operator
{
if ($2.getType()!=TypType.Boolean)
{
// Error: Oneiaea aie?ii eiaou eiae?aneee oei
}
$$ = new While($2, $4, @$);
}
| kIF LPAREN expr RPAREN operator elsepart
{
if ($2.getType()!=TypType.Boolean)
{
// Error: Oneiaea aie?ii eiaou eiae?aneee oei
}
$$=new If($2,$4,$5,@$);
}
| kBEGIN listoperator kEND
{
$$ = $2;
}
| kWRITE LPAREN expr RPAREN
{
System.Console.Write($3);
}
;
elsepart:
{
$$ = null;
}
| kELSE operator {
$$ = $2;
}
;
expr: INTNUM
{
int i = int.Parse($1);
$$ = new IntConst(i, @1);
}
| REALNUM
{
double d = double.Parse($1);
$$ = new DoubleConst(d, @1);
}
| STRINGLITERAL
{
// Iao o ian oaeeo!!!
}
| ID
{
if (!GlobalStructures.isNameExists($1))
{
// Error: Undeclarated identifier
}
$$ = new Ident($1, @1);
}
| expr PLUS expr
{
$$ = new BinExpression($1, $3, Op.Plus, @$);
}
| expr MINUS expr
{
$$ = new BinExpression($1, $3, Op.Minus, @$);
}
| expr MULT expr
{
$$ = new BinExpression($1, $3, Op.Mult, @$);
}
| expr DIVIDE expr
{
$$ = new BinExpression($1, $3, Op.Divide, @$);
}
| expr DIV expr
{
// Ia iiaaa??eaaaony!
}
| expr MOD expr
{
// Ia iiaaa??eaaaony!
}
| expr AND expr
{
if ($1.getType() != TipType.BoolType || $2.getType() != TipType.BoolType)
{
// Error: only for bool types
}
$$ = new BinExpression($1, $3, Op.And, @$);
}
| expr OR expr
{
if ($1.getType() != TipType.BoolType || $2.getType() != TipType.BoolType)
{
// Error: only for bool types
}
$$ = new BinExpression($1, $3, Op.Or, @$);
}
| expr LT expr
{
$$ = new BinExpression($1, $3, Op.Less, @$);
}
| expr GT expr
{
$$ = new BinExpression($1, $3, Op.More, @$);
}
| expr LE expr
{
$$ = new BinExpression($1, $3, Op.LessEqual, @$);
}
| expr GE expr
{
$$ = new BinExpression($1, $3, Op.MoreEqual, @$);
}
| expr EQ expr
{
$$ = new BinExpression($1, $3, Op.Equal, @$);
}
| expr NE expr
{
$$ = new BinExpression($1, $3, Op.NotEqual, @$);
}
| NOT expr
{
if ($2.getType() != TipType.BoolType)
{
// Error: type is wrong.
}
$$ = new UnarExpression($2, Op.Not, @2);
}
| MINUS expr %prec UMINUS
{
if ($2.getType() != TipType.IntType && $2.getType() != TipType.DoubleType)
{
// Error: type is wrong.
}
$$ = new UnarExpression($2, Op.Minus, @2);
}
| LPAREN expr RPAREN
{
$$ = $2;
}
;
%%
C.LEX
%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("Комментарий не закрыт");}
"=" { 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.POINT; }
\'[^']*\' {
yylval.sVal = yytext.Substring(1,yytext.Length-2);
return (int)Tokens.STRINGLITERAL;
}
{ID} {
int res = ScannerHelper.GetIDToken(yytext);
if (s=="int")
yylval.dtVal.DType=DataType.INTTYPE;
if (s == "double")
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("double",(int)Tokens.kREAL);
keywords.Add("int",(int)Tokens.kINTEGER);
keywords.Add("bool",(int)Tokens.kBOOLEAN);
keywords.Add("{",(int)Tokens.kBEGIN);
keywords.Add("}",(int)Tokens.kEND);
keywords.Add("if",(int)Tokens.kIF);
keywords.Add("else",(int)Tokens.kELSE);
keywords.Add("while",(int)Tokens.kWHILE);
keywords.Add("cout",(int)Tokens.kWRITE);
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)
{
if (keywords.ContainsKey(s))
{
return keywords[s];
}
else
return (int)Tokens.ID;
}
}