%{
/*
* parser.y
*/
#include <iostream.h>
#include <string.h>
#define YYSTYPE PPTreeNodeCls
#include "p_tree.h"
#include "scanparse.h"
int yylex();
void yyerror(char*);
extern char* textline; //Defined in scanner.l
%}
%token PROGRAMTK
%token BEGINTK
%token ENDTK
%token SCTK
%token ASGTK
%token DOTTK
%token IDENTIFIERTK
%token NUMLITERALTK
%token WRITETK
%token LPARENTK
%token RPARENTK
%token VARTK
%token ARRAYTK
%token RANGETK
%token OFTK
%token LOOPTK
%token IFTK
%token THENTK
%token ELSETK
%token EXITTK
%token COMMATK
%token COLONTK
%token LBRACKTK
%token RBRACKTK
/* arithmetic operators */
%token PLUSTK
%token MINUSTK
%token STARTK
%token SLASHTK
/* relational operators */
%token LTTK
%token LETK
%token EQTK
%token NETK
%token GETK
%token GTTK
%token INTEGERTK
%nonassoc ASSIGNTK
%nonassoc LTTK LETK EQTK NETK GETK GTTK
%left PLUSTK MINUSTK
%left STARTK SLASHTK
%start Program
%%
Program:
PROGRAMTK Identifier SCTK
DeclarationBlock Block
{PProgramCls pgm = new ProgramCls($2,$5);}
;
DeclarationBlock:
VARTK DeclarationSeq
{$$ = $2;}
| /* empty */
{$$ = new DeclarationSeqCls();}
;
DeclarationSeq:
DeclarationSeq SCTK Declaration
{$$ = PDeclarationSeqCls($1)->append($3);}
| Declaration
{$$ = new DeclarationSeqCls($1);}
;
Declaration:
IdentifierSeq COLONTK DataType
{$$ = new DeclarationCls($1, $3, textline);}
| /* empty */
{$$ = new DeclarationCls();}
;
IdentifierSeq:
IdentifierSeq COMMATK Identifier
{$$ = PIdentSeqCls($1)->append($3);}
| Identifier
{$$ = new IdentSeqCls($1);}
;
DataType:
BasicType
| CompoundType
;
BasicType:
INTEGERTK
{$$ = new IntTypeCls();}
;
CompoundType:
ARRAYTK LBRACKTK Number RANGETK Number RBRACKTK OFTK DataType
{$$ = new ArrayTypeCls($3, $5, $8);}
;
Block:
BEGINTK
StatementSeq
ENDTK DOTTK
{$$ = new BlockCls($2);}
;
StatementSeq:
Statement
{$$ = new StatementSeqCls($1);}
| StatementSeq SCTK Statement
{$$ = PStatementSeqCls($1) -> append($3);}
;
Statement:
/* empty */
{$$ = new EmptyStmtCls;}
| AssignmentStmt
| WriteStmt
| LOOPTK StatementSeq ENDTK LOOPTK
{$$ = new LoopStmtCls($2);}
| EXITTK
{$$ = new ExitStmtCls();}
| IFTK Condition THENTK StatementSeq ElseBlock ENDTK IFTK
{$$ = new IfStmtCls($2, $4, $5);}
;
ElseBlock:
/* empty */
{$$ = new ElseStmtCls();}
| ELSETK StatementSeq
{$$ = new ElseStmtCls($2);}
;
Condition:
| Expr RelOp Expr
{$$ = new ConditionCls($1, $2, $3);}
;
RelOp:
LTTK
{$$ = new RelOpCls(RelOpCls::ltOp);}
| LETK
{$$ = new RelOpCls(RelOpCls::leOp);}
| EQTK
{$$ = new RelOpCls(RelOpCls::eqOp);}
| NETK
{$$ = new RelOpCls(RelOpCls::neOp);}
| GETK
{$$ = new RelOpCls(RelOpCls::geOp);}
| GTTK
{$$ = new RelOpCls(RelOpCls::gtOp);}
;
AssignmentStmt:
AssignmentSeq Expr
{$$ = new AssignmentStmtCls($1,$2,textline);}
;
AssignmentSeq:
AssignmentSeq DataItem ASGTK
{$$ = PAssignmentSeqCls($1)->append($2);}
| DataItem ASGTK
{$$ = new AssignmentSeqCls($1);}
;
WriteStmt:
WRITETK LPARENTK Expr RPARENTK
{$$ = new WriteStmtCls($3,textline);}
;
Expr:
Expr PLUSTK Expr
{$$ = new ArithmCls($1, $3, ArithmCls::PlusOp);}
| Expr MINUSTK Expr
{$$ = new ArithmCls($1, $3, ArithmCls::MinusOp);}
| Expr STARTK Expr
{$$ = new ArithmCls($1, $3, ArithmCls::MultOp);}
| Expr SLASHTK Expr
{$$ = new ArithmCls($1, $3, ArithmCls::DivOp);}
| Factor
| LPARENTK Expr RPARENTK
{$$ = $2;}
;
Factor:
Number
{$$ = new NumFactorCls($1);}
| DataItem
{$$ = new VarAccessFactorCls($1);}
;
DataItem:
Identifier
{$$ = new DataItemCls($1);}
/* | Identifier LBRAKTK Expr RBRACKTK */
| DataItem LBRACKTK Expr RBRACKTK
{$$ = new DataItemCls($1, $3);}
;
Identifier:
IDENTIFIERTK
{$$ = new IdentCls();}
;
Number:
NUMLITERALTK
{$$ = new NumLiteralCls();}
;
|