├── .gitignore ├── Api.cpp ├── Dnlang ├── DnLexer.cpp ├── DnParser.cpp ├── Dnlang.bnf ├── IR │ ├── 3_addr.syntax │ ├── AST.cpp │ ├── AST.syntax │ └── ASTVisitor.cpp ├── Lexer.cpp ├── Parser.cpp ├── Scope.cpp ├── Symbol.cpp ├── Symbols.cpp ├── Token.cpp ├── runtime │ ├── DnInLexer.cpp │ ├── DnInParser.cpp │ └── Interprter.cpp └── sample │ ├── enemy.dn │ └── test01.dn ├── Dnscript.cpp ├── Dntest ├── Event.cpp ├── Frame.cpp ├── Game.cpp ├── Game ├── Bullet.cpp ├── Clear.cpp ├── Enemy.cpp ├── Load.cpp ├── Menu.cpp ├── Play.cpp └── Player.cpp ├── Keyboard.cpp ├── LICENSE ├── Main.cpp ├── Makefile ├── Object.cpp ├── README.md ├── Select.cpp ├── Title.cpp ├── doc └── api_list.md ├── img ├── CutinReimu.png ├── Enemy.png ├── ExRumia.png ├── Reimu.png ├── Rumia.png ├── bullet.png ├── bullets.png ├── circle.png ├── demo.png ├── load.png ├── play.jpg ├── select.png └── title.png ├── include ├── AST.hpp ├── ASTVisitor.hpp ├── Action.hpp ├── Api.hpp ├── Bullet.hpp ├── Clear.hpp ├── DnInLexer.hpp ├── DnInParser.hpp ├── DnLexer.hpp ├── DnParser.hpp ├── Dnscript.hpp ├── Enemy.hpp ├── Event.hpp ├── Frame.hpp ├── Game.hpp ├── Interprter.hpp ├── Keyboard.hpp ├── Lexer.hpp ├── Load.hpp ├── Menu.hpp ├── Object.hpp ├── Parser.hpp ├── Play.hpp ├── Player.hpp ├── Register.hpp ├── Scope.hpp ├── Select.hpp ├── Symbol.hpp ├── Symbols.hpp ├── Title.hpp ├── Token.hpp ├── Utility.hpp ├── Window.hpp └── test │ ├── enemy_test.hpp │ └── player_test.hpp └── test ├── dnlang_test01.cpp ├── enemy_test.cpp └── player_test.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # Backup file 31 | *~ -------------------------------------------------------------------------------- /Api.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "Object.hpp" 11 | #include "Api.hpp" 12 | #include "Dnscript.hpp" 13 | #include "Window.hpp" 14 | #include "Interprter.hpp" 15 | #include "Play.hpp" 16 | 17 | 18 | Api* Api::mInstance = 0; 19 | 20 | Api* Api::instance(){ 21 | return mInstance; 22 | } 23 | 24 | void Api::create(){ 25 | try{ 26 | if(mInstance) throw "[*ERROR*] Api::create() cannnot create instance twice"; 27 | mInstance = new Api(); 28 | }catch(const char *error){ 29 | fprintf(stderr,"%s\n",error); 30 | abort(); 31 | } 32 | } 33 | 34 | void Api::destroy(){ 35 | delete mInstance; 36 | mInstance = 0; 37 | } 38 | 39 | Api::Api(){ 40 | keyboard = Keyboard::instance(); 41 | } 42 | /* ### API list ### */ 43 | /* Graphics */ 44 | void Api::LoadGraphic(Object* target,std::string filename){ 45 | target->set_image(IMG_Load(filename.c_str())); 46 | } 47 | 48 | void Api::SetTexture(Object* target,std::string filename){ 49 | SDL_Renderer* renderer = Window::renderer; 50 | SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer,target->get_image()); 51 | target->set_texture(tex); 52 | } 53 | 54 | void Api::SetGraphicRect(Object* target,Uint32 sx,Uint32 sy,Uint32 dx,Uint32 dy){ 55 | Uint32 width = dx - sx; 56 | Uint32 height = dy - sy; 57 | target->set_obj_rect(sx,sy,width,height); 58 | } 59 | 60 | void Api::SetGraphicAngle(Object* target,Uint32 angle){ 61 | rotozoomSurface(target->get_image(),angle,1,1); 62 | SetTexture(target,"dummy"); //rebind 63 | } 64 | 65 | void Api::DrawGraphic(Object* target,Uint32 x,Uint32 y){ 66 | target->set_obj_pos(x,y); 67 | SDL_Renderer* renderer = Window::renderer; 68 | SDL_Rect *src = target->get_obj_rect(); 69 | SDL_Rect * dest = target->get_obj_pos(); 70 | SDL_RenderCopy(renderer, target->get_texture(),src,dest); 71 | } 72 | 73 | /* Status*/ 74 | void Api::SetSpeed(Object* target,int speed){ 75 | target->set_speed(speed); 76 | } 77 | void Api::SetLife(Object* target,int life){ 78 | target->set_life(life); 79 | } 80 | void Api::SetX(Object* target,int x){ 81 | target->set_x(x); 82 | } 83 | void Api::SetY(Object* target,int y){ 84 | target->set_y(y); 85 | } 86 | int Api::GetPlayerX(Object* target){ 87 | return target->get_x(); 88 | } 89 | int Api::GetPlayerY(Object* target){ 90 | return target->get_y(); 91 | } 92 | int Api::GetSpeedX(Object* target){ 93 | return target->get_dx(); 94 | } 95 | int Api::GetSpeedY(Object* target){ 96 | return target->get_dy(); 97 | } 98 | int Api::GetX(Object* target){ 99 | return target->get_x(); 100 | } 101 | int Api::GetY(Object* target){ 102 | return target->get_y(); 103 | } 104 | int Api::GetMX(Object* target){ 105 | return target->get_mx(); 106 | } 107 | int Api::GetMY(Object* target){ 108 | return target->get_my(); 109 | } 110 | int Api::GetW(Object* target){ 111 | return target->get_width(); 112 | } 113 | int Api::GetH(Object* target){ 114 | return target->get_height(); 115 | } 116 | int Api::GetCenterX(){ 117 | return Play::win_rect.w / 2; 118 | } 119 | int Api::GetCenterY(){ 120 | return Play::win_rect.h / 2; 121 | } 122 | 123 | /* Danmaku */ 124 | void Api::CreatePlayerShot01(Object* target,int x,int y, 125 | double speed,double angle,double damage, 126 | int pene,int id){ 127 | target->shoot(x,y,speed,angle,damage,pene,id); 128 | } 129 | void Api::CreateShot01(Object* target,int x,int y, 130 | double speed,double angle,Bullet::Color color,int delay){ 131 | target->shoot(x,y,speed,angle,999999,10000,color,delay); 132 | } 133 | 134 | /* SpellCard */ 135 | void Api::CutIn(Object* target,std::string label,std::string img,int x1,int y1,int x2,int y2){ 136 | target->CutIn(label,img,x1,y1,x2,y2); 137 | } 138 | /* Action */ 139 | void Api::SetMovePosition02(Object* target,int x,int y,int frame){ 140 | target->start_move(x,y,frame); 141 | } 142 | 143 | /* Keyboard */ 144 | Api::KeyState Api::GetKeyState(SDL_Keycode key){ 145 | if(keyboard->is_keyon(key)) return KEY_PUSH; 146 | if(keyboard->is_keytoggle(key)) return KEY_HOLD; 147 | if(keyboard->is_keyoff(key)) return KEY_RELEASE; 148 | } 149 | 150 | /* Other */ 151 | std::string Api::GetCurrentScriptDirectory(){ 152 | char buf[256]; 153 | getcwd(buf,256); 154 | std::string path = buf; 155 | return path; 156 | } 157 | 158 | /* Unofficial API (hidden) */ 159 | void Api::RenderClear(){ 160 | SDL_RenderClear(Window::renderer); 161 | } 162 | void Api::RenderPresent(){ 163 | SDL_RenderPresent(Window::renderer); 164 | } 165 | 166 | 167 | /* ### ABI list ### */ 168 | /* Graphics */ 169 | void Api::_LoadGraphic(Object* target,double filename){ 170 | //std::cout<<(unsigned long)filename<((unsigned long)(filename)); 172 | std::string filename_s = std::string(fnamep); 173 | std::cout<<"LoadGraphic: "<((unsigned long)(filename)); 179 | std::string filename_s = std::string(fnamep); 180 | SetTexture(target, filename_s); 181 | } 182 | 183 | void Api::_SetGraphicRect(Object* target,double sx,double sy,double dx,double dy){ 184 | Uint32 sxi = (int)(sx); 185 | Uint32 syi = (int)(sy); 186 | Uint32 dxi = (int)(dx); 187 | Uint32 dyi = (int)(dy); 188 | SetGraphicRect(target, sxi, syi, dxi, dyi); 189 | } 190 | 191 | void Api::_SetGraphicAngle(Object* target,double angle){ 192 | Uint32 anglei = (Uint32)(angle); 193 | SetGraphicAngle(target, anglei); 194 | } 195 | 196 | void Api::_DrawGraphic(Object* target,double x,double y){ 197 | Uint32 xi = (int)(x); 198 | Uint32 yi = (int)(y); 199 | DrawGraphic(target,xi,yi); 200 | } 201 | 202 | /* Status*/ 203 | void Api::_SetSpeed(Object* target,double speed){ 204 | int speedi = (int)(speed); 205 | SetSpeed(target, speedi); 206 | } 207 | void Api::_SetLife(Object* target,double life){ 208 | int lifei = (int)(life); 209 | SetLife(target, lifei); 210 | } 211 | void Api::_SetX(Object* target,double x){ 212 | double xi = (int)(x); 213 | SetX(target, xi); 214 | } 215 | void Api::_SetY(Object* target,double y){ 216 | double yi = (int)(y); 217 | SetY(target, yi); 218 | } 219 | int Api::_GetPlayerX(Object* target){ 220 | GetPlayerX(target); 221 | } 222 | int Api::_GetPlayerY(Object* target){ 223 | GetPlayerY(target); 224 | } 225 | int Api::_GetSpeedX(Object* target){ 226 | GetSpeedX(target); 227 | } 228 | int Api::_GetSpeedY(Object* target){ 229 | GetSpeedY(target); 230 | } 231 | int Api::_GetX(Object* target){ 232 | return GetX(target); 233 | } 234 | int Api::_GetY(Object* target){ 235 | return GetY(target); 236 | } 237 | int Api::_GetMX(Object* target){ 238 | return GetMX(target); 239 | } 240 | int Api::_GetMY(Object* target){ 241 | return GetMY(target); 242 | } 243 | int Api::_GetW(Object* target){ 244 | return GetW(target); 245 | } 246 | int Api::_GetH(Object* target){ 247 | return GetH(target); 248 | } 249 | int Api::_GetCenterX(){ 250 | return GetCenterX(); 251 | } 252 | int Api::_GetCenterY(){ 253 | return GetCenterY(); 254 | } 255 | 256 | /* Danmaku */ 257 | void Api::_CreatePlayerShot01(Object* target,double x,double y, 258 | double speed,double angle,double damage, 259 | double pene,double id){ 260 | int xi = (int)x; 261 | int yi = (int)y; 262 | int penei = (int)pene; 263 | int idi = (int)id; 264 | CreatePlayerShot01(target,xi,yi,speed,angle,damage,penei,idi); 265 | } 266 | void Api::_CreateShot01(Object* target,double x,double y, 267 | double speed,double angle,double color,double delay){ 268 | int xi = (int)x; 269 | int yi = (int)y; 270 | Bullet::Color colorc= (Bullet::Color)((int)color); 271 | int delayi = (int)delay; 272 | CreateShot01(target,xi,yi,speed,angle,colorc, delayi); 273 | } 274 | 275 | /* SpellCard */ 276 | void Api::_CutIn(Object* target,double label,double img,double x1,double y1,double x2,double y2){ 277 | const char *labelp = reinterpret_cast((unsigned long)(label)); 278 | std::string label_s = std::string(labelp); 279 | const char *imgp = reinterpret_cast((unsigned long)(img)); 280 | std::string img_s = std::string(imgp); 281 | 282 | int x1i = (int)x1; 283 | int y1i = (int)y1; 284 | int x2i = (int)x2; 285 | int y2i = (int)y2; 286 | 287 | CutIn(target,label_s,img_s,x1i,y1i,x2i,y2i); 288 | } 289 | /* Action */ 290 | void Api::_SetMovePosition02(Object* target,double x,double y,double frame){ 291 | int xi = (int)x; 292 | int yi = (int)y; 293 | int framei = (int)frame; 294 | SetMovePosition02(target,xi,yi,framei); 295 | } 296 | 297 | /* Keyboard */ 298 | Api::KeyState Api::_GetKeyState(double key){ 299 | SDL_Keycode keys = (SDL_Keycode)key; 300 | GetKeyState(keys); 301 | } 302 | 303 | /* Other */ 304 | std::string Api::_GetCurrentScriptDirectory(){ 305 | return GetCurrentScriptDirectory(); 306 | } 307 | -------------------------------------------------------------------------------- /Dnlang/DnLexer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "Token.hpp" 5 | #include "Lexer.hpp" 6 | #include "DnLexer.hpp" 7 | 8 | 9 | /* TODO: These macros are bit ugly. Refactor it to better one. */ 10 | #define STR(str) #str 11 | #define ASSIGNCON(__o,__o2,__token) \ 12 | consume(); \ 13 | switch(c) { \ 14 | case '=': consume(); return Token(__token##ASSIGN, STR(__o##=)); \ 15 | case __o2: consume(); return Token(__token##__token, STR(__o##__o)); \ 16 | default: return Token(__token, #__o); \ 17 | } 18 | #define ASSIGN(__o,__token) \ 19 | consume(); \ 20 | switch(c) { \ 21 | case '=': consume(); return Token(__token##ASSIGN, STR(__o##=)); \ 22 | default: return Token(__token, #__o); \ 23 | } 24 | 25 | #define EQUALCON(__o,__o2,__token) \ 26 | consume(); \ 27 | switch(c) { \ 28 | case '=': consume(); return Token(__token##EQUAL, STR(__o##=)); \ 29 | case __o2: consume(); return Token(__token##__token, STR(__o##__o)); \ 30 | default: return Token(__token, #__o); \ 31 | } 32 | #define EQUALL(__o,__token) \ 33 | consume(); \ 34 | switch(c) { \ 35 | case '=': consume(); return Token(__token##EQUAL, STR(__o##=)); \ 36 | default: return Token(__token, #__o); \ 37 | } 38 | 39 | namespace Dnlang { 40 | 41 | const std::string DnLexer::token_names[] = { 42 | "n/a", "", 43 | "BREAK", "CONTINUE", "ELSE", "FOR", "FUNCTION", "IF", "LET", "RETURN", "SWITCH", 44 | "WHILE", 45 | "ID", "INTCONST", "CHARCONST", "FLOATCONST", "STRING", "SEMICORON", "COMMA", 46 | "LBRACKA", "RBRACKA", "LBRACK", "RBRACK", "LBRACKB", "RBRACKB", 47 | "MULASSIGN", "DIVASSIGN", "MODASSIGN", "PLUSASSIGN", "MINUSASSIGN", 48 | "ANDASSIGN", "ORASSIGN", "XORASSIGN","EQUAL", 49 | "OROR", "OR", "ANDAND", "AND", "XOR", "NOT", "PLUS", "MINUS", "MUL", "DIV", "MOD", 50 | "PLUSPLUS", "MINUSMINUS", 51 | "LESSLESS", "ABOVEABOVE", "EQUALEQUAL", "NOTEQUAL", 52 | "LESS", "LESSEQUAL", "ABOVE", "ABOVEEQUAL", 53 | /* virtual token for AST */ 54 | "FUNC_DEF", "DECL", "AREF", "CALL", "PARAM", "ASSIGN", 55 | "INITIALIZER", "EXP", "BLOCK", "UNARYEXP", "PRIMARYEXP", 56 | }; 57 | 58 | const std::string DnLexer::reserved[] = { 59 | "break", "continue", "else", "for", "function", "if", "let", "return", "switch", "while", 60 | }; 61 | 62 | Token DnLexer::nextToken() { 63 | while(c != LEX_EOF) { 64 | switch(c) { 65 | case ' ': case '\t': case '\n': case '\r': skipSpaces(); continue; 66 | case ';': consume(); return Token(SEMICORON, ";"); 67 | case ',': consume(); return Token(COMMA, ","); 68 | case '(': consume(); return Token(LBRACKA, "("); 69 | case ')': consume(); return Token(RBRACKA, ")"); 70 | case '[': consume(); return Token(LBRACK, "["); 71 | case ']': consume(); return Token(RBRACK, "]"); 72 | case '{': consume(); return Token(LBRACKB, "{"); 73 | case '}': consume(); return Token(RBRACKB, "}"); 74 | case '=': 75 | EQUALL(=, EQUAL) 76 | case '+': 77 | ASSIGNCON(+, '+', PLUS) 78 | case '-': 79 | ASSIGNCON(-, '-', MINUS) 80 | case '/': 81 | ASSIGN(/, DIV) 82 | case '*': 83 | ASSIGN(*, MUL) 84 | case '%': 85 | ASSIGN(%, MOD) 86 | case '&': 87 | ASSIGNCON(&, '&', AND) 88 | case '|': 89 | ASSIGNCON(|, '|', OR) 90 | case '^': 91 | ASSIGN(^, XOR) 92 | case '!': 93 | EQUALL(!, NOT) 94 | case '<': 95 | EQUALCON(<, '<', LESS) 96 | case '>': 97 | EQUALCON(>, '>', ABOVE) 98 | case '\"': 99 | /* "hoge" (string) */ 100 | if(isString()) return String(); 101 | case '\'': 102 | /* 'X' (char) */ 103 | if(isChar()) return CharConst(); 104 | default: 105 | if(isDecimal()) { 106 | /* {D} */ 107 | if(isFloat()) return FloatConst(); 108 | else return IntConst(); 109 | }else if(isId()) { 110 | /* {L} It could be id or reserved word */ 111 | return Id(); 112 | } 113 | break; 114 | } 115 | } 116 | return Token(EOF_TYPE, ""); 117 | } 118 | 119 | /* TODO: Is it reserved word? It's judged by using binary search. */ 120 | int DnLexer::isReserved(std::string str) { 121 | int rsize = sizeof(reserved) / sizeof(std::string *); 122 | for(int i = 0; i < rsize; i++){ 123 | if(reserved[i] == str) return i; 124 | } 125 | return -1; 126 | /*std::string *pos = std::lower_bound(reserved, reserved + rsize, str); 127 | return (pos != rsize && *pos == str); */ 128 | } 129 | 130 | Token DnLexer::IntConst() { 131 | std::string buf; 132 | do { buf.append(1, c); consume(); } while(isDecimal()); 133 | return Token(INTCONST, buf); 134 | } 135 | 136 | Token DnLexer::CharConst() { 137 | std::string buf; 138 | consume(); 139 | buf.append(1,c); 140 | consume(); 141 | return Token(CHARCONST, buf); 142 | } 143 | 144 | Token DnLexer::FloatConst() { 145 | std::string buf; 146 | do { buf.append(1, c); consume(); } while(isDecimal() || c == '.'); 147 | return Token(FLOATCONST, buf); 148 | } 149 | 150 | Token DnLexer::String() { 151 | std::string buf; 152 | do { buf.append(1, c); consume(); } while(isDecimal() || isLetter() || isSym() || c == '\"' || c == '\"'); 153 | return Token(STRING, buf); 154 | } 155 | 156 | Token DnLexer::Id() { 157 | std::string buf; 158 | int resv = -1; 159 | do { buf.append(1, c); consume(); } while(isDecimal() || isLetter() || isSym()); 160 | if((resv = isReserved(buf)) != -1){ 161 | /* Is this id reserved word? */ 162 | return Token(2 + resv, buf); 163 | } 164 | return Token(ID, buf); 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /Dnlang/DnParser.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "Token.hpp" 7 | #include "Lexer.hpp" 8 | #include "DnLexer.hpp" 9 | #include "Symbol.hpp" 10 | #include "Scope.hpp" 11 | #include "Register.hpp" 12 | #include "AST.hpp" 13 | #include "Parser.hpp" 14 | #include "DnParser.hpp" 15 | 16 | 17 | #define SPECULATE(x) \ 18 | [this]() { \ 19 | bool success = true; \ 20 | mark(); \ 21 | try { x } \ 22 | catch (std::string &str) { success = false; } \ 23 | release(); \ 24 | return success; \ 25 | } 26 | #define DEFINE_MEMO(x, fp) \ 27 | bool failed = false; \ 28 | int startTokenIndex = index(); \ 29 | if(isSpeculating() && alreadyParsedRule(#x)) return; \ 30 | try { _##fp } \ 31 | catch(std::string &s) { \ 32 | failed = true; \ 33 | if(isSpeculating()) memorize(#x, startTokenIndex, failed); \ 34 | throw s; \ 35 | } \ 36 | if(isSpeculating()) memorize(#x, startTokenIndex, failed); \ 37 | 38 | #define ADD_TOKEN(type, str) \ 39 | if(!isSpeculating()) { \ 40 | AST *child= new AST(Token(type, str)); \ 41 | ast_root->addChild(ast_root, child); \ 42 | } \ 43 | 44 | #define ADD_ROOT_CHROOT(root) \ 45 | if(!isSpeculating()) { \ 46 | AST *child = new AST(root); \ 47 | ast_root = ast_root->addChild(ast_root, child); \ 48 | } \ 49 | 50 | #define ADD_TOKEN_CHROOT(type, str) \ 51 | if(!isSpeculating()) { \ 52 | AST *child = new AST(Token(type, str)); \ 53 | ast_root = ast_root->addChild(ast_root, child); \ 54 | } \ 55 | 56 | #define BREAK_UP \ 57 | if(!isSpeculating()) { \ 58 | ast_root = ast_root->parent; \ 59 | } \ 60 | 61 | namespace Dnlang { 62 | /* type inference 63 | XXX bit ugly. Is there any better solution? */ 64 | void DnParser::_TranslationUnit() { 65 | if(SPECULATE( ExternalDecl(); TranslationUnit(); match(DnLexer::EOF_TYPE); )()) { 66 | ExternalDecl(); TranslationUnit(); match(DnLexer::EOF_TYPE); 67 | } 68 | else if(SPECULATE( ExternalDecl(); match(DnLexer::EOF_TYPE); )()) { 69 | ExternalDecl(); match(DnLexer::EOF_TYPE); 70 | } 71 | else { 72 | std::stringstream error; 73 | error << "Error: " << LT(1) << LT(2); 74 | throw error.str(); 75 | } 76 | } 77 | void DnParser::_ExternalDecl() { 78 | if(SPECULATE( FunctionDef(); )()) { 79 | FunctionDef(); 80 | } 81 | else if(SPECULATE( Decl(); )()) { 82 | Decl(); 83 | } 84 | else { 85 | std::stringstream error; 86 | error << "Error: " << LT(1) << LT(2); 87 | throw error.str(); 88 | } 89 | } 90 | void DnParser::_FunctionDef() { 91 | if(SPECULATE( DeclSpecs(); Declarator(); CompoundStat(); )()) { 92 | ADD_ROOT_CHROOT(DnLexer::FUNC_DEF) 93 | DeclSpecs(); Declarator(); CompoundStat(); 94 | BREAK_UP 95 | } 96 | else { 97 | std::stringstream error; 98 | error << "Error: " << LT(1) << LT(2); 99 | throw error.str(); 100 | } 101 | } 102 | void DnParser::_Decl() { 103 | if(SPECULATE( DeclSpecs(); InitDecl(); match(DnLexer::SEMICORON); )()) { 104 | ADD_ROOT_CHROOT(DnLexer::DECL) 105 | DeclSpecs(); 106 | InitDecl(); 107 | match(DnLexer::SEMICORON); 108 | BREAK_UP 109 | } 110 | else { 111 | std::stringstream error; 112 | error << "Error: " << LT(1) << LT(2); 113 | throw error.str(); 114 | } 115 | } 116 | void DnParser::_DeclList() { 117 | if(SPECULATE( Decl(); DeclList(); )()) { 118 | Decl(); DeclList(); 119 | } 120 | else if(SPECULATE( Decl(); )()) { 121 | Decl(); 122 | } 123 | else { 124 | std::stringstream error; 125 | error << "Error: " << LT(1) << LT(2); 126 | throw error.str(); 127 | } 128 | } 129 | void DnParser::_DeclSpecs() { 130 | if(SPECULATE( FuncSpec(); )()) { 131 | FuncSpec(); 132 | } 133 | else if(SPECULATE( TypeSpec(); )()) { 134 | TypeSpec(); 135 | } 136 | else { 137 | std::stringstream error; 138 | error << "Error: " << LT(1) << LT(2); 139 | throw error.str(); 140 | } 141 | } 142 | void DnParser::_FuncSpec() { 143 | if(SPECULATE( match(DnLexer::FUNCTION); )()) { 144 | match(DnLexer::FUNCTION); 145 | } 146 | else { 147 | std::stringstream error; 148 | error << "Error: " << LT(1) << LT(2); 149 | throw error.str(); 150 | } 151 | } 152 | void DnParser::_TypeSpec() { 153 | if(SPECULATE( match(DnLexer::LET); )()) { 154 | match(DnLexer::LET); 155 | } 156 | else { 157 | std::stringstream error; 158 | error << "Error: " << LT(1) << LT(2); 159 | throw error.str(); 160 | } 161 | } 162 | void DnParser::_InitDeclList() { 163 | if(SPECULATE( InitDecl(); match(DnLexer::COMMA); InitDeclList(); )()) { 164 | InitDecl(); match(DnLexer::COMMA); InitDeclList(); 165 | } 166 | else if(SPECULATE( InitDecl(); )()) { 167 | InitDecl(); 168 | } 169 | else { 170 | std::stringstream error; 171 | error << "Error: " << LT(1) << LT(2); 172 | throw error.str(); 173 | } 174 | } 175 | void DnParser::_InitDecl() { 176 | if(SPECULATE( Declarator(); match(DnLexer::EQUAL); Initializer(); )()) { 177 | Declarator(); match(DnLexer::EQUAL); Initializer(); 178 | } 179 | else if(SPECULATE( Declarator(); )()) { 180 | Declarator(); 181 | } 182 | else { 183 | std::stringstream error; 184 | error << "Error: " << LT(1) << LT(2); 185 | throw error.str(); 186 | } 187 | } 188 | void DnParser::_Declarator() { 189 | if(SPECULATE( match(DnLexer::ID); match(DnLexer::LBRACKA); IdList(); match(DnLexer::RBRACKA); )()) { 190 | ADD_TOKEN(DnLexer::ID, LT(1).text) 191 | match(DnLexer::ID); 192 | ADD_ROOT_CHROOT(DnLexer::PARAM) 193 | match(DnLexer::LBRACKA); IdList(); match(DnLexer::RBRACKA); 194 | BREAK_UP 195 | } 196 | else if(SPECULATE( match(DnLexer::ID); match(DnLexer::LBRACKA); match(DnLexer::RBRACKA); )()) { 197 | ADD_TOKEN(DnLexer::ID, LT(1).text) 198 | match(DnLexer::ID); 199 | ADD_ROOT_CHROOT(DnLexer::PARAM) 200 | match(DnLexer::LBRACKA); match(DnLexer::RBRACKA); 201 | BREAK_UP 202 | } 203 | else if(SPECULATE( match(DnLexer::ID); match(DnLexer::LBRACK); match(DnLexer::INTCONST); match(DnLexer::RBRACK); )()) { 204 | ADD_TOKEN(DnLexer::ID, LT(1).text) 205 | match(DnLexer::ID); 206 | /* TODO: Implement declaration of array */ 207 | } 208 | else if(SPECULATE( match(DnLexer::ID); )()) { 209 | ADD_TOKEN(DnLexer::ID, LT(1).text) 210 | match(DnLexer::ID); 211 | } 212 | else { 213 | std::stringstream error; 214 | error << "Error: " << LT(1) << LT(2); 215 | throw error.str(); 216 | } 217 | } 218 | void DnParser::_IdList() { 219 | if(SPECULATE( match(DnLexer::ID); match(DnLexer::COMMA); IdList(); )()) { 220 | ADD_TOKEN(DnLexer::ID, LT(1).text) 221 | match(DnLexer::ID); 222 | match(DnLexer::COMMA); IdList(); 223 | } 224 | else if(SPECULATE( match(DnLexer::ID); )()) { 225 | ADD_TOKEN(DnLexer::ID, LT(1).text) 226 | match(DnLexer::ID); 227 | } 228 | else { 229 | std::stringstream error; 230 | error << "Error: " << LT(1) << LT(2); 231 | throw error.str(); 232 | } 233 | } 234 | void DnParser::_Initializer() { 235 | if(SPECULATE( AssignExp(); )()) { 236 | AssignExp(); 237 | } 238 | else { 239 | std::stringstream error; 240 | error << "Error: " << LT(1) << LT(2); 241 | throw error.str(); 242 | } 243 | } 244 | void DnParser::_Stat() { 245 | if(SPECULATE( ExpStat(); )()) { 246 | ExpStat(); 247 | } 248 | else if(SPECULATE( CompoundStat(); )()) { 249 | CompoundStat(); 250 | } 251 | else if(SPECULATE( SelectionStat(); )()) { 252 | SelectionStat(); 253 | } 254 | else if(SPECULATE( IterationStat(); )()) { 255 | IterationStat(); 256 | } 257 | else if(SPECULATE( JumpStat(); )()) { 258 | JumpStat(); 259 | } 260 | else { 261 | std::stringstream error; 262 | error << "Error: " << LT(1) << LT(2); 263 | throw error.str(); 264 | } 265 | } 266 | void DnParser::_ExpStat() { 267 | if(SPECULATE( Exp(); match(DnLexer::SEMICORON); )()) { 268 | Exp(); match(DnLexer::SEMICORON); 269 | } 270 | else if(SPECULATE( match(DnLexer::SEMICORON); )()) { 271 | match(DnLexer::SEMICORON); 272 | } 273 | else { 274 | std::stringstream error; 275 | error << "Error: " << LT(1) << LT(2); 276 | throw error.str(); 277 | } 278 | } 279 | void DnParser::_CompoundStat() { 280 | if(SPECULATE( match(DnLexer::LBRACKB); match(DnLexer::RBRACKB); )()) { 281 | ADD_ROOT_CHROOT(DnLexer::BLOCK) 282 | match(DnLexer::LBRACKB); match(DnLexer::RBRACKB); 283 | BREAK_UP 284 | } 285 | else if(SPECULATE( match(DnLexer::LBRACKB); DeclList(); StatList(); match(DnLexer::RBRACKB); )()) { 286 | ADD_ROOT_CHROOT(DnLexer::BLOCK) 287 | match(DnLexer::LBRACKB); DeclList(); StatList(); match(DnLexer::RBRACKB); 288 | BREAK_UP 289 | } 290 | else if(SPECULATE( match(DnLexer::LBRACKB); DeclList(); match(DnLexer::RBRACKB); )()) { 291 | ADD_ROOT_CHROOT(DnLexer::BLOCK) 292 | match(DnLexer::LBRACKB); DeclList(); match(DnLexer::RBRACKB); 293 | BREAK_UP 294 | } 295 | else if(SPECULATE( match(DnLexer::LBRACKB); StatList(); match(DnLexer::RBRACKB); )()) { 296 | ADD_ROOT_CHROOT(DnLexer::BLOCK) 297 | match(DnLexer::LBRACKB); StatList(); match(DnLexer::RBRACKB); 298 | BREAK_UP 299 | } 300 | else { 301 | std::stringstream error; 302 | error << "Error: " << LT(1) << LT(2); 303 | throw error.str(); 304 | } 305 | } 306 | void DnParser::_StatList() { 307 | if(SPECULATE( Stat(); StatList(); )()) { 308 | Stat(); StatList(); 309 | } 310 | else if(SPECULATE( Stat(); )()) { 311 | Stat(); 312 | } 313 | else { 314 | std::stringstream error; 315 | error << "Error: " << LT(1) << LT(2); 316 | throw error.str(); 317 | } 318 | } 319 | void DnParser::_SelectionStat() { 320 | if(SPECULATE( match(DnLexer::IF); match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); Stat(); match(DnLexer::ELSE); Stat(); )()) { 321 | ADD_TOKEN_CHROOT(DnLexer::IF, "IF") 322 | match(DnLexer::IF); 323 | match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); Stat(); 324 | match(DnLexer::ELSE); Stat(); 325 | BREAK_UP 326 | } 327 | else if(SPECULATE( match(DnLexer::IF); match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); Stat(); )()) { 328 | ADD_TOKEN_CHROOT(DnLexer::IF, "IF") 329 | match(DnLexer::IF); 330 | match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); Stat(); 331 | BREAK_UP 332 | } 333 | else { 334 | std::stringstream error; 335 | error << "Error: " << LT(1) << LT(2); 336 | throw error.str(); 337 | } 338 | } 339 | void DnParser::_IterationStat() { 340 | if(SPECULATE( match(DnLexer::WHILE); match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); Stat(); )()) { 341 | ADD_TOKEN_CHROOT(DnLexer::WHILE, "WHILE") 342 | match(DnLexer::WHILE); 343 | match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); Stat(); 344 | BREAK_UP 345 | } 346 | else if(SPECULATE( match(DnLexer::FOR); match(DnLexer::LBRACKA); Exp(); match(DnLexer::SEMICORON); Exp(); match(DnLexer::SEMICORON); Exp(); match(DnLexer::RBRACKA); Stat(); )()) { 347 | ADD_TOKEN_CHROOT(DnLexer::FOR, "FOR") 348 | match(DnLexer::FOR); 349 | match(DnLexer::LBRACKA); 350 | Exp(); match(DnLexer::SEMICORON); 351 | Exp(); match(DnLexer::SEMICORON); 352 | Exp(); 353 | match(DnLexer::RBRACKA); Stat(); 354 | BREAK_UP 355 | } 356 | else { 357 | std::stringstream error; 358 | error << "Error: " << LT(1) << LT(2); 359 | throw error.str(); 360 | } 361 | 362 | } 363 | void DnParser::_JumpStat() { 364 | if(SPECULATE( match(DnLexer::CONTINUE); match(DnLexer::SEMICORON); )()) { 365 | ADD_TOKEN(DnLexer::CONTINUE, "CONTINUE") 366 | match(DnLexer::CONTINUE); 367 | match(DnLexer::SEMICORON); 368 | } 369 | else if(SPECULATE( match(DnLexer::BREAK); match(DnLexer::SEMICORON); )()) { 370 | ADD_TOKEN(DnLexer::BREAK, "BREAK") 371 | match(DnLexer::BREAK); 372 | match(DnLexer::SEMICORON); 373 | } 374 | else if(SPECULATE( match(DnLexer::RETURN); Exp(); match(DnLexer::SEMICORON); )()) { 375 | ADD_TOKEN_CHROOT(DnLexer::RETURN, "RETURN") 376 | match(DnLexer::RETURN); 377 | Exp(); match(DnLexer::SEMICORON); 378 | BREAK_UP 379 | } 380 | else if(SPECULATE( match(DnLexer::RETURN); match(DnLexer::SEMICORON); )()) { 381 | ADD_TOKEN(DnLexer::RETURN, "RETURN") 382 | match(DnLexer::RETURN); 383 | match(DnLexer::SEMICORON); 384 | } 385 | else { 386 | std::stringstream error; 387 | error << "Error: " << LT(1) << LT(2); 388 | throw error.str(); 389 | } 390 | } 391 | void DnParser::_Exp() { 392 | if(SPECULATE( AssignExp(); match(DnLexer::COMMA); Exp(); )()) { 393 | AssignExp(); match(DnLexer::COMMA); Exp(); 394 | } 395 | else if(SPECULATE( AssignExp(); )()) { 396 | AssignExp(); 397 | } 398 | else { 399 | std::stringstream error; 400 | error << "Error: " << LT(1) << LT(2); 401 | throw error.str(); 402 | } 403 | } 404 | void DnParser::_AssignExp() { 405 | if(SPECULATE( UnaryExp(); AssignOperator(); AssignExp(); )()) { 406 | ADD_TOKEN_CHROOT(DnLexer::ASSIGN, "ASSIGN"); 407 | UnaryExp(); AssignOperator(); AssignExp(); 408 | BREAK_UP 409 | } 410 | else if(SPECULATE( ConditionalExp(); )()) { 411 | ConditionalExp(); 412 | } 413 | else { 414 | std::stringstream error; 415 | error << "Error: " << LT(1) << LT(2); 416 | throw error.str(); 417 | } 418 | } 419 | void DnParser::_AssignOperator() { 420 | if(SPECULATE( match(DnLexer::EQUAL); )()) { 421 | ADD_TOKEN(DnLexer::EQUAL, "=") 422 | match(DnLexer::EQUAL); 423 | } 424 | else if(SPECULATE( match(DnLexer::MULASSIGN); )()) { 425 | ADD_TOKEN(DnLexer::MULASSIGN, "*=") 426 | match(DnLexer::MULASSIGN); 427 | } 428 | else if(SPECULATE( match(DnLexer::DIVASSIGN); )()) { 429 | ADD_TOKEN(DnLexer::DIVASSIGN, "/=") 430 | match(DnLexer::DIVASSIGN); 431 | } 432 | else if(SPECULATE( match(DnLexer::MODASSIGN); )()) { 433 | ADD_TOKEN(DnLexer::MODASSIGN, "%=") 434 | match(DnLexer::MODASSIGN); 435 | } 436 | else if(SPECULATE( match(DnLexer::PLUSASSIGN); )()) { 437 | ADD_TOKEN(DnLexer::PLUSASSIGN, "+=") 438 | match(DnLexer::PLUSASSIGN); 439 | } 440 | else if(SPECULATE( match(DnLexer::MINUSASSIGN); )()) { 441 | ADD_TOKEN(DnLexer::MINUSASSIGN, "-=") 442 | match(DnLexer::MINUSASSIGN); 443 | } 444 | else if(SPECULATE( match(DnLexer::ANDASSIGN); )()) { 445 | ADD_TOKEN(DnLexer::ANDASSIGN, "&=") 446 | match(DnLexer::ANDASSIGN); 447 | } 448 | else if(SPECULATE( match(DnLexer::ORASSIGN); )()) { 449 | match(DnLexer::ORASSIGN); 450 | ADD_TOKEN(DnLexer::ORASSIGN, "|=") 451 | } 452 | else if(SPECULATE( match(DnLexer::XORASSIGN); )()) { 453 | match(DnLexer::XORASSIGN); 454 | ADD_TOKEN(DnLexer::XORASSIGN, "^=") 455 | } 456 | else { 457 | std::stringstream error; 458 | error << "Error: " << LT(1) << LT(2); 459 | throw error.str(); 460 | } 461 | } 462 | void DnParser::_ConditionalExp() { 463 | if(SPECULATE( LogicalOrExp(); )()) { 464 | LogicalOrExp(); 465 | } 466 | else { 467 | std::stringstream error; 468 | error << "Error: " << LT(1) << LT(2); 469 | throw error.str(); 470 | } 471 | } 472 | void DnParser::_LogicalOrExp() { 473 | if(SPECULATE( LogicalAndExp(); )()) { 474 | LogicalAndExp(); 475 | } 476 | else if(SPECULATE( LogicalAndExp(); match(DnLexer::OROR); LogicalOrExp(); )()) { 477 | ADD_TOKEN_CHROOT(DnLexer::OROR, "||") 478 | LogicalAndExp(); match(DnLexer::OROR); LogicalOrExp(); 479 | BREAK_UP 480 | } 481 | else { 482 | std::stringstream error; 483 | error << "Error: " << LT(1) << LT(2); 484 | throw error.str(); 485 | } 486 | } 487 | void DnParser::_LogicalAndExp() { 488 | if(SPECULATE( InclusiveOrExp(); match(DnLexer::ANDAND); LogicalAndExp(); )()) { 489 | ADD_TOKEN_CHROOT(DnLexer::ANDAND, "&&") 490 | InclusiveOrExp(); match(DnLexer::ANDAND); LogicalAndExp(); 491 | BREAK_UP 492 | } 493 | else if(SPECULATE( InclusiveOrExp(); )()) { 494 | InclusiveOrExp(); 495 | } 496 | else { 497 | std::stringstream error; 498 | error << "Error: " << LT(1) << LT(2); 499 | throw error.str(); 500 | } 501 | } 502 | void DnParser::_InclusiveOrExp() { 503 | if(SPECULATE( ExclusiveOrExp(); match(DnLexer::OR); InclusiveOrExp(); )()) { 504 | ADD_TOKEN_CHROOT(DnLexer::OR, "|") 505 | ExclusiveOrExp(); match(DnLexer::OR); InclusiveOrExp(); 506 | BREAK_UP 507 | } 508 | else if(SPECULATE( ExclusiveOrExp(); )()) { 509 | ExclusiveOrExp(); 510 | } 511 | else { 512 | std::stringstream error; 513 | error << "Error: " << LT(1) << LT(2); 514 | throw error.str(); 515 | } 516 | } 517 | void DnParser::_ExclusiveOrExp() { 518 | if(SPECULATE( AndExp(); match(DnLexer::XOR); ExclusiveOrExp(); )()) { 519 | ADD_TOKEN_CHROOT(DnLexer::XOR, "^") 520 | AndExp(); match(DnLexer::XOR); ExclusiveOrExp(); 521 | BREAK_UP 522 | } 523 | else if(SPECULATE( AndExp(); )()) { 524 | AndExp(); 525 | } 526 | else { 527 | std::stringstream error; 528 | error << "Error: " << LT(1) << LT(2); 529 | throw error.str(); 530 | } 531 | 532 | } 533 | void DnParser::_AndExp() { 534 | if(SPECULATE( EqualityExp(); match(DnLexer::AND); AndExp(); )()) { 535 | ADD_TOKEN_CHROOT(DnLexer::AND, "&") 536 | EqualityExp(); match(DnLexer::AND); AndExp(); 537 | BREAK_UP 538 | } 539 | else if(SPECULATE( EqualityExp(); )()) { 540 | EqualityExp(); 541 | } 542 | else { 543 | std::stringstream error; 544 | error << "Error: " << LT(1) << LT(2); 545 | throw error.str(); 546 | } 547 | } 548 | void DnParser::_EqualityExp() { 549 | if(SPECULATE( RelationalExp(); match(DnLexer::EQUALEQUAL); EqualityExp(); )()) { 550 | ADD_TOKEN_CHROOT(DnLexer::EQUALEQUAL, "==") 551 | RelationalExp(); match(DnLexer::EQUALEQUAL); EqualityExp(); 552 | BREAK_UP 553 | } 554 | else if(SPECULATE( RelationalExp(); match(DnLexer::NOTEQUAL); EqualityExp(); )()) { 555 | ADD_TOKEN_CHROOT(DnLexer::NOTEQUAL, "!=") 556 | RelationalExp(); match(DnLexer::NOTEQUAL); EqualityExp(); 557 | BREAK_UP 558 | } 559 | else if(SPECULATE( RelationalExp(); )()) { 560 | RelationalExp(); 561 | } 562 | else { 563 | std::stringstream error; 564 | error << "Error: " << LT(1) << LT(2); 565 | throw error.str(); 566 | } 567 | } 568 | void DnParser::_RelationalExp() { 569 | if(SPECULATE( ShiftExp(); match(DnLexer::LESS); RelationalExp(); )()) { 570 | ADD_TOKEN_CHROOT(DnLexer::LESS, "<") 571 | ShiftExp(); match(DnLexer::LESS); RelationalExp(); 572 | BREAK_UP 573 | } 574 | else if(SPECULATE( ShiftExp(); match(DnLexer::ABOVE); RelationalExp(); )()) { 575 | ADD_TOKEN_CHROOT(DnLexer::ABOVE, ">") 576 | ShiftExp(); match(DnLexer::ABOVE); RelationalExp(); 577 | BREAK_UP 578 | } 579 | else if(SPECULATE( ShiftExp(); match(DnLexer::LESSEQUAL); RelationalExp(); )()) { 580 | ADD_TOKEN_CHROOT(DnLexer::LESSEQUAL, "<=") 581 | ShiftExp(); match(DnLexer::LESSEQUAL); RelationalExp(); 582 | BREAK_UP 583 | } 584 | else if(SPECULATE( ShiftExp(); match(DnLexer::ABOVEEQUAL); RelationalExp(); )()) { 585 | ADD_TOKEN_CHROOT(DnLexer::ABOVEEQUAL, ">=") 586 | ShiftExp(); match(DnLexer::ABOVEEQUAL); RelationalExp(); 587 | BREAK_UP 588 | } 589 | else if(SPECULATE( ShiftExp(); )()) { 590 | ShiftExp(); 591 | } 592 | else { 593 | std::stringstream error; 594 | error << "Error: " << LT(1) << LT(2); 595 | throw error.str(); 596 | } 597 | } 598 | void DnParser::_ShiftExp() { 599 | if(SPECULATE( AdditiveExp(); match(DnLexer::LESSLESS); ShiftExp(); )()) { 600 | ADD_TOKEN_CHROOT(DnLexer::LESSLESS, "<<") 601 | AdditiveExp(); match(DnLexer::LESSLESS); ShiftExp(); 602 | BREAK_UP 603 | } 604 | else if(SPECULATE( AdditiveExp(); match(DnLexer::ABOVEABOVE); ShiftExp(); )()) { 605 | ADD_TOKEN_CHROOT(DnLexer::ABOVEABOVE, ">>") 606 | AdditiveExp(); match(DnLexer::ABOVEABOVE); ShiftExp(); 607 | BREAK_UP 608 | } 609 | else if(SPECULATE( AdditiveExp(); )()) { 610 | AdditiveExp(); 611 | } 612 | else { 613 | std::stringstream error; 614 | error << "Error: " << LT(1) << LT(2); 615 | throw error.str(); 616 | } 617 | } 618 | void DnParser::_AdditiveExp() { 619 | if(SPECULATE( MultExp(); match(DnLexer::PLUS); AdditiveExp(); )()) { 620 | ADD_TOKEN_CHROOT(DnLexer::PLUS, "+") 621 | MultExp(); match(DnLexer::PLUS); AdditiveExp(); 622 | BREAK_UP 623 | } 624 | else if(SPECULATE( MultExp(); match(DnLexer::MINUS); AdditiveExp(); )()) { 625 | ADD_TOKEN_CHROOT(DnLexer::MINUS, "-") 626 | MultExp(); match(DnLexer::MINUS); AdditiveExp(); 627 | BREAK_UP 628 | } 629 | else if(SPECULATE( MultExp(); )()) { 630 | MultExp(); 631 | } 632 | else { 633 | std::stringstream error; 634 | error << "Error: " << LT(1) << LT(2); 635 | throw error.str(); 636 | } 637 | } 638 | void DnParser::_MultExp() { 639 | if(SPECULATE( UnaryExp(); match(DnLexer::MUL); MultExp(); )()) { 640 | ADD_TOKEN_CHROOT(DnLexer::MUL, "*") 641 | UnaryExp(); match(DnLexer::MUL); MultExp(); 642 | BREAK_UP 643 | } 644 | else if(SPECULATE( UnaryExp(); match(DnLexer::DIV); MultExp(); )()) { 645 | ADD_TOKEN_CHROOT(DnLexer::DIV, "/") 646 | UnaryExp(); match(DnLexer::DIV); MultExp(); 647 | BREAK_UP 648 | } 649 | else if(SPECULATE( UnaryExp(); match(DnLexer::MOD); MultExp(); )()) { 650 | ADD_TOKEN_CHROOT(DnLexer::MOD, "%") 651 | UnaryExp(); match(DnLexer::MOD); MultExp(); 652 | BREAK_UP 653 | } 654 | else if(SPECULATE( UnaryExp(); )()) { 655 | UnaryExp(); 656 | } 657 | else { 658 | std::stringstream error; 659 | error << "Error: " << LT(1) << LT(2); 660 | throw error.str(); 661 | } 662 | } 663 | void DnParser::_UnaryExp() { 664 | if(SPECULATE( PostfixExp(); )()) { 665 | PostfixExp(); 666 | } 667 | else if(SPECULATE( match(DnLexer::PLUSPLUS); UnaryExp(); )()) { 668 | ADD_TOKEN_CHROOT(DnLexer::PLUSPLUS, "++") 669 | match(DnLexer::PLUSPLUS); UnaryExp(); 670 | BREAK_UP 671 | } 672 | else if(SPECULATE( match(DnLexer::MINUSMINUS); UnaryExp(); )()) { 673 | ADD_TOKEN_CHROOT(DnLexer::MINUSMINUS, "--") 674 | match(DnLexer::MINUSMINUS); UnaryExp(); 675 | BREAK_UP 676 | } 677 | else if(SPECULATE( UnaryOperator(); UnaryExp(); )()) { 678 | UnaryOperator(); UnaryExp(); 679 | BREAK_UP 680 | } 681 | else { 682 | std::stringstream error; 683 | error << "Error: " << LT(1) << LT(2); 684 | throw error.str(); 685 | } 686 | } 687 | void DnParser::_UnaryOperator() { 688 | if(SPECULATE( match(DnLexer::PLUS); )()) { 689 | ADD_TOKEN_CHROOT(DnLexer::PLUS, "+") 690 | match(DnLexer::PLUS); 691 | } 692 | else if(SPECULATE( match(DnLexer::MINUS); )()) { 693 | ADD_TOKEN_CHROOT(DnLexer::MINUS, "-") 694 | match(DnLexer::MINUS); 695 | } 696 | else if(SPECULATE( match(DnLexer::NOT); )()) { 697 | ADD_TOKEN_CHROOT(DnLexer::NOT, "!") 698 | match(DnLexer::NOT); 699 | } 700 | else { 701 | std::stringstream error; 702 | error << "Error: " << LT(1) << LT(2); 703 | throw error.str(); 704 | } 705 | } 706 | void DnParser::_PostfixExp() { 707 | if(SPECULATE( PrimaryExp(); match(DnLexer::LBRACK); Exp(); match(DnLexer::RBRACK); )()) { 708 | ADD_ROOT_CHROOT(DnLexer::AREF) 709 | PrimaryExp(); match(DnLexer::LBRACK); Exp(); match(DnLexer::RBRACK); 710 | BREAK_UP 711 | } 712 | else if(SPECULATE( PrimaryExp(); match(DnLexer::LBRACKA); ArgumentExpList(); match(DnLexer::RBRACKA); )()) { 713 | ADD_ROOT_CHROOT(DnLexer::CALL) 714 | PrimaryExp(); match(DnLexer::LBRACKA); ArgumentExpList(); match(DnLexer::RBRACKA); 715 | BREAK_UP 716 | } 717 | else if(SPECULATE( PrimaryExp(); match(DnLexer::LBRACKA); match(DnLexer::RBRACKA); )()) { 718 | ADD_ROOT_CHROOT(DnLexer::CALL) 719 | PrimaryExp(); match(DnLexer::LBRACKA); match(DnLexer::RBRACKA); 720 | BREAK_UP 721 | } 722 | else if(SPECULATE( PrimaryExp(); )()) { 723 | PrimaryExp(); 724 | } 725 | else { 726 | std::stringstream error; 727 | error << "Error: " << LT(1) << LT(2); 728 | throw error.str(); 729 | } 730 | 731 | } 732 | void DnParser::_PrimaryExp() { 733 | if(SPECULATE( match(DnLexer::ID); )()) { 734 | ADD_TOKEN(DnLexer::ID, LT(1).text); 735 | match(DnLexer::ID); 736 | } 737 | else if(SPECULATE( Const(); )()) { 738 | Const(); 739 | } 740 | else if(SPECULATE( match(DnLexer::STRING); )()) { 741 | ADD_TOKEN(DnLexer::STRING, LT(1).text); 742 | match(DnLexer::STRING); 743 | } 744 | else if(SPECULATE( match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); )()) { 745 | match(DnLexer::LBRACKA); Exp(); match(DnLexer::RBRACKA); 746 | } 747 | else { 748 | std::stringstream error; 749 | error << "Error: " << LT(1) << LT(2); 750 | throw error.str(); 751 | } 752 | } 753 | void DnParser::_ArgumentExpList() { 754 | if(SPECULATE( AssignExp(); match(DnLexer::COMMA); ArgumentExpList(); )()) { 755 | AssignExp(); match(DnLexer::COMMA); ArgumentExpList(); 756 | } 757 | else if(SPECULATE( AssignExp(); )()) { 758 | AssignExp(); 759 | } 760 | else { 761 | std::stringstream error; 762 | error << "Error: " << LT(1) << LT(2); 763 | throw error.str(); 764 | } 765 | } 766 | void DnParser::_Const() { 767 | if(SPECULATE( match(DnLexer::INTCONST); )()) { 768 | ADD_TOKEN(DnLexer::INTCONST, LT(1).text); 769 | match(DnLexer::INTCONST); 770 | } 771 | else if(SPECULATE( match(DnLexer::CHARCONST); )()) { 772 | ADD_TOKEN(DnLexer::CHARCONST, LT(1).text); 773 | match(DnLexer::CHARCONST); 774 | } 775 | else if(SPECULATE( match(DnLexer::FLOATCONST); )()) { 776 | ADD_TOKEN(DnLexer::FLOATCONST, LT(1).text); 777 | match(DnLexer::FLOATCONST); 778 | } 779 | else { 780 | std::stringstream error; 781 | error << "Error: " << LT(1) << LT(2); 782 | throw error.str(); 783 | } 784 | } 785 | void DnParser::TranslationUnit() { DEFINE_MEMO(TranslationUnit,TranslationUnit();) } 786 | void DnParser::ExternalDecl() { DEFINE_MEMO(ExternalDecl,ExternalDecl();) } 787 | void DnParser::FunctionDef() { DEFINE_MEMO(FunctionDef,FunctionDef();) } 788 | void DnParser::Decl() { DEFINE_MEMO(Decl,Decl();) } 789 | void DnParser::DeclList() { DEFINE_MEMO(DeclList,DeclList();) } 790 | void DnParser::DeclSpecs() { DEFINE_MEMO(DeclSpecs,DeclSpecs();) } 791 | void DnParser::FuncSpec() { DEFINE_MEMO(FuncSpec,FuncSpec();) } 792 | void DnParser::TypeSpec() { DEFINE_MEMO(TypeSpec,TypeSpec();) } 793 | void DnParser::InitDeclList() { DEFINE_MEMO(InitDeclList,InitDeclList();) } 794 | void DnParser::InitDecl() { DEFINE_MEMO(InitDecl,InitDecl();) } 795 | void DnParser::Declarator() { DEFINE_MEMO(Declarator,Declarator();) } 796 | void DnParser::IdList() { DEFINE_MEMO(IdList,IdList();) } 797 | void DnParser::Initializer() { DEFINE_MEMO(Initializer,Initializer();) } 798 | void DnParser::Stat() { DEFINE_MEMO(Stat,Stat();) } 799 | void DnParser::ExpStat() { DEFINE_MEMO(ExpStat,ExpStat();) } 800 | void DnParser::CompoundStat() { DEFINE_MEMO(CompoundStat,CompoundStat();) } 801 | void DnParser::StatList() { DEFINE_MEMO(StatList,StatList();) } 802 | void DnParser::SelectionStat() { DEFINE_MEMO(SelectionStat,SelectionStat();) } 803 | void DnParser::IterationStat() { DEFINE_MEMO(IterationStat,IterationStat();) } 804 | void DnParser::JumpStat() { DEFINE_MEMO(JumpStat,JumpStat();) } 805 | void DnParser::Exp() { DEFINE_MEMO(Exp,Exp();) } 806 | void DnParser::AssignExp() { DEFINE_MEMO(AssignExp,AssignExp();) } 807 | void DnParser::AssignOperator() { DEFINE_MEMO(AssignOperator,AssignOperator();) } 808 | void DnParser::ConditionalExp() { DEFINE_MEMO(ConditionalExp,ConditionalExp();) } 809 | void DnParser::LogicalOrExp() { DEFINE_MEMO(LogicalOrExp,LogicalOrExp();) } 810 | void DnParser::LogicalAndExp() { DEFINE_MEMO(LogicalAndExp,LogicalAndExp();) } 811 | void DnParser::InclusiveOrExp() { DEFINE_MEMO(InclusiveOrExp,InclusiveOrExp();) } 812 | void DnParser::ExclusiveOrExp() { DEFINE_MEMO(ExclusiveOrExp,ExclusiveOrExp();) } 813 | void DnParser::AndExp() { DEFINE_MEMO(AndExp,AndExp();) } 814 | void DnParser::EqualityExp() { DEFINE_MEMO(EqualityExp,EqualityExp();) } 815 | void DnParser::RelationalExp() { DEFINE_MEMO(RelationalExp,RelationalExp();) } 816 | void DnParser::ShiftExp() { DEFINE_MEMO(ShiftExp,ShiftExp();) } 817 | void DnParser::AdditiveExp() { DEFINE_MEMO(AdditiveExp,AdditiveExp();) } 818 | void DnParser::MultExp() { DEFINE_MEMO(MultExp,MultExp();) } 819 | void DnParser::UnaryExp() { DEFINE_MEMO(UnaryExp,UnaryExp();) } 820 | void DnParser::UnaryOperator() { DEFINE_MEMO(UnaryOperator,UnaryOperator();) } 821 | void DnParser::PostfixExp() { DEFINE_MEMO(PostfixExp,PostfixExp();) } 822 | void DnParser::PrimaryExp() { DEFINE_MEMO(PrimaryExp,PrimaryExp();) } 823 | void DnParser::ArgumentExpList() { DEFINE_MEMO(ArgumentExpList,ArgumentExpList();) } 824 | void DnParser::Const() { DEFINE_MEMO(Const,Const();) } 825 | } 826 | -------------------------------------------------------------------------------- /Dnlang/Dnlang.bnf: -------------------------------------------------------------------------------- 1 | ::= 2 | | 3 | ::= 4 | | 5 | ::= 6 | ::= ";" 7 | ::= 8 | | 9 | ::= 10 | | 11 | ::= "function" 12 | ::= "let" 13 | ::= "=" 14 | | 15 | ::= "(" ")" 16 | | "(" ")" 17 | | "[""]" 18 | | 19 | ::= "," 20 | | 21 | ::= 22 | ::= 23 | | 24 | | 25 | | 26 | | 27 | ::= ";" 28 | | ";" 29 | ::= "{" "}" 30 | | "{" "}" 31 | | "{" "}" 32 | | "{" "}" 33 | ::= 34 | | 35 | ::= "if" "(" ")" "else" 36 | | "if" "(" ")" 37 | ::= "while" "(" ")" 38 | | "for" "(" ";" ";" ")" 39 | ::= "continue" ";" 40 | | "break" ";" 41 | | "return" ";" 42 | | "return" ";" 43 | ::= "," 44 | | 45 | ::= 46 | | 47 | ::= "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&=" | "|=" | "^=" 48 | ::= 49 | ::= 50 | | "||" 51 | ::= "&&" 52 | | 53 | ::= "|" 54 | | 55 | ::= "^" 56 | | 57 | ::= "&" 58 | | 59 | ::= "==" 60 | | "!=" 61 | | 62 | ::= "<" 63 | | ">" 64 | | "<=" 65 | | ">=" 66 | | 67 | ::= "<<" 68 | | ">>" 69 | | 70 | ::= "+" 71 | | "-" 72 | | 73 | ::= "*" 74 | | "/" 75 | | "%" 76 | | 77 | ::= 78 | | "++" 79 | | "--" 80 | | 81 | ::= "+" | "-" | "!" 82 | ::= "[" "]" 83 | | "(" ")" 84 | | "(" ")" 85 | | 86 | ::= 87 | | 88 | | 89 | | "(" ")" 90 | ::= "," 91 | | 92 | ::= 93 | | 94 | | 95 | 96 | D ::= [0-9] //Decimal 97 | L ::= [a-zA-Z_] //Literal 98 | H ::= [a-fA-F0-9] //Hexadecimal 99 | ::= {D}+ 100 | ::= \'({L}|{D})\' 101 | ::= {D}+"."{D} 102 | ::= \"{L}({L}|{D})*\" 103 | ::= {L}({L}|{D})* 104 | -------------------------------------------------------------------------------- /Dnlang/IR/3_addr.syntax: -------------------------------------------------------------------------------- 1 | ## 3_address code 2 | 3 | ## LL(1) pre-read 1 words from head to determine a statement. 4 | stat head 5 | 6 | 'goto' 7 | 'if' 8 | 'param' 9 | 'call' 10 | 'ret' 11 | 12 | <3_addr> ::= | | | 13 | 14 | # assign = l op r 15 | ::= '=' 16 | ::= 17 | ::= 18 | 19 | # x = y op z, x = op y, x = y 20 | ::= 21 | | 22 | | 23 | ::= '+' | '-' | '*' | '/' | '%' 24 | 25 | # goto L 26 | ::= 'goto'