Blang/src/lib/src/parser.yy

114 lines
3.6 KiB
Plaintext

%{
#include <cstdio>
#include <iostream>
#include <Statements>
using namespace std;
int yylex(void);
void yyerror(const char * msg);
std::string filename;
SourceLocation createLocation(int line,int column);
extern FILE * yyin;
%}
%skeleton "lalr1.cc" /* -*- C++ -*- */
%require "3.0"
%defines
%define parser_class_name { Parser }
%define api.token.constructor
%define api.value.type variant
%define parse.assert
%locations
%define parse.trace
%define parse.error verbose
%left '-' '+'
%left '*' '/'
%token DO LPWHILE
%token WHILE WHILEEND
%token IF THEN ELSE IFEND
%token FOR TO STEP NEXT
%token GOTO LABEL
%token BREAK RETURN STOP
%token <std::string> STRING
%token <int> INTEGER;
%token <int> FLOAT;
%token <std::string> IDENTIFIER
%token <std::string> OPERATOR
%token ASSIGN IMPLIES EOL
%start program
%type <CompoundStatement*> stmtList;
%type <Statement*> stmt;
%type <IfStatement*> ifStmt;
%type <ForStatement*> forStmt;
%type <Expr*> expr;
%type <AssignStatement*> assignStmt;
%%
program : stmtList
;
stmtList : stmtList stmt { CompoundStatement* stmt = $1; stmt.setLastStatement($2); $$ = stmt; }
| stmt { CompoundStatement* stmt = new CompoundStatement(); stmt.setLastStatement($1); $$ = stmt; }
;
stmt : assignStmt
| ifStmt
| WHILE expr EOL stmtList EOL WHILEEND { $$ = new WhileStatement($2, $4, createLocation(@$.first_line, @$.first_column)); }
| DO EOL stmtList EOL LPWHILE expr { $$ = new DoStatement($3, $6, createLocation(@1.first_line, @1.first_column), createLocation(@6.first_line, @6.first_column)); }
| forStmt
| GOTO identifier
| LABEL identifier
| BREAK { $$ = new BreakStatement(createLocation(@$.first_line, @$.first_column)); }
| RETURN { $$ = new ReturnStatement(createLocation(@$.first_line, @$.first_column)); }
| STOP { $$ = new StopStatement(createLocation(@$.first_line, @$.first_column)); }
| expr
;
expr : identifier
| STRING { $$ = new StringLiteralExpr($1, createLocation(@1.first_line, @1.first_column)); }
| INTEGER { $$ = new IntegerLiteralExpr($1, createLocation(@1.first_line, @1.first_column)) }
| FLOAT { $$ = new FloatLiteralExpr($1, createLocation(@1.first_line, @1.first_column)) }
| expr OPERATOR expr { $$ = new BinaryOperatorExpr($1, $3, BinaryOperatorExpr::getStrOpcode($2)); }
;
identifier: IDENTIFIER
;
assignStmt : expr ASSIGN identifier
;
ifStmt : IF expr EOL THEN EOL stmtList EOL IFEND { $$ = new IfStatement(createLocation(@$.first_line, @$.first_column), $2, $6); }
| IF expr EOL THEN EOL stmtList EOL ELSE EOL stmtList EOL IFEND { $$ = new IfStatement(createLocation(@$.first_line, @$.first_column), $2, $6, createLocation(@10.first_line, @10.first_column), $10); }
| expr IMPLIES assignStmt { $$ = new IfStatement($1, $3); }
;
forStmt : FOR assignStmt TO expr EOL stmtList EOL NEXT { $$ = new ForStatement(createLocation(@$.first_line, @$.first_column), $2, $4, $6);}
| FOR assignStmt TO expr STEP expr EOL stmtList EOL NEXT { $$ = new ForStatement(createLocation(@$.first_line, @$.first_column), $2, $4, $8, $6);}
%%
void yyerror(const char * msg)
{
cerr << "line " << lineNumber << ": " << msg << endl;
}
SourceLocation createLocation(int line,int column)
{
return SourceLocation(filename, line, column);
}
AST* parse_str(std::string str)
{
if(argc>1)
yyin=fopen(argv[1],"r"); // check result !!!
lineNumber=1;
if(!yyparse())
cerr << "Success" << endl;
return(0);
}