Home
 

parser.y

parser.y

%{
/*
 *  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();}
    ;