2024-01-05 12:04
BullseyeCoverage 9.6.4
expr/ Parser.cpp


1 // Expression evaluator parser implementation 2 #include <cassert> 3 #include "Parser.h" 4 5 void Parser::unitTest() 6 { 7 assert(Parser("1+2*3").expression() == 7); 8 assert(Parser("9/4").expression() == 2); 9 assert(Parser("5%4").expression() == 1); 10 assert(Parser("-(1 || 0)").expression() == -1); 11 assert(Parser("7-6").expression() == 1); 12 assert(Parser("8<<2").expression() == 32); 13 assert(Parser("32>>2").expression() == 8); 14 assert(Parser("8<9").expression() == 1); 15 assert(Parser("1<1").expression() == 0); 16 assert(Parser("1<=1").expression() == 1); 17 assert(Parser("1<=0").expression() == 0); 18 assert(Parser("1>=1").expression() == 1); 19 assert(Parser("0>=1").expression() == 0); 20 assert(Parser("1>1").expression() == 0); 21 assert(Parser("1>0").expression() == 1); 22 try { 23 Parser("1/0").expression(); 24 assert(false); 25 } 26 catch (const char*) { 27 } 28 } 29 30 Parser::Parser(const char* string) 31 : m_lexer(string) 32 { 33 } 34 35 int64_t Parser::primary_expression() 36 { 37 int64_t n; 38 switch (m_token.kind) { 39 case Token::Kind::minus: 40 m_lexer.read(m_token); 41 n = -primary_expression(); 42 break; 43 case Token::Kind::number: 44 n = m_token.value; 45 m_lexer.read(m_token); 46 break; 47 case Token::Kind::parenLeft: 48 m_lexer.read(m_token); 49 n = logical_or_expression(); 50 m_lexer.read(m_token); 51 if (m_token.kind != Token::Kind::parenRight) { 52 throw "expected ')'"; 53 } 54 m_lexer.read(m_token); 55 break; 56 default: 57 throw "syntax error"; 58 } 59 return n; 60 } 61 62 int64_t Parser::multiplicative_expression() 63 { 64 int64_t n = primary_expression(); 65 for (;;) { 66 if (m_token.kind == Token::Kind::multiply) { 67 m_lexer.read(m_token); 68 n = n * primary_expression(); 69 } else if (m_token.kind == Token::Kind::divide) { 70 m_lexer.read(m_token); 71 const int64_t n2 = primary_expression();; 72 if (n2 == 0) { 73 throw "divide by zero"; 74 } 75 n = n / n2; 76 } else if (m_token.kind == Token::Kind::modulus) { 77 m_lexer.read(m_token); 78 const int64_t n2 = primary_expression();; 79 if (n2 == 0) { 80 throw "divide by zero"; 81 } 82 n = n % n2; 83 } else { 84 break; 85 } 86 } 87 return n; 88 } 89 90 int64_t Parser::additive_expression() 91 { 92 int64_t n = multiplicative_expression(); 93 for (;;) { 94 if (m_token.kind == Token::Kind::plus) { 95 m_lexer.read(m_token); 96 n = n + multiplicative_expression(); 97 } else if (m_token.kind == Token::Kind::minus) { 98 m_lexer.read(m_token); 99 n = n - multiplicative_expression(); 100 } else { 101 break; 102 } 103 } 104 return n; 105 } 106 107 int64_t Parser::shift_expression() 108 { 109 int64_t n = additive_expression(); 110 for (;;) { 111 if (m_token.kind == Token::Kind::shiftLeft) { 112 m_lexer.read(m_token); 113 n = n << additive_expression(); 114 } else if (m_token.kind == Token::Kind::shiftRight) { 115 m_lexer.read(m_token); 116 n = n >> additive_expression(); 117 } else { 118 break; 119 } 120 } 121 return n; 122 } 123 124 int64_t Parser::relational_expression() 125 { 126 int64_t n = shift_expression(); 127 for (;;) { 128 if (m_token.kind == Token::Kind::lessThan) { 129 m_lexer.read(m_token); 130 n = n < shift_expression(); 131 } else if (m_token.kind == Token::Kind::lessThanEq) { 132 m_lexer.read(m_token); 133 n = n <= shift_expression(); 134 } else if (m_token.kind == Token::Kind::greaterThan) { 135 m_lexer.read(m_token); 136 n = n > shift_expression(); 137 } else if (m_token.kind == Token::Kind::greaterThanEq) { 138 m_lexer.read(m_token); 139 n = n >= shift_expression(); 140 } else { 141 break; 142 } 143 } 144 return n; 145 } 146 147 int64_t Parser::equality_expression() 148 { 149 int64_t n = relational_expression(); 150 for (;;) { 151 if (m_token.kind == Token::Kind::equal) { 152 m_lexer.read(m_token); 153 n = n == relational_expression(); 154 } else if (m_token.kind == Token::Kind::notEqual) { 155 m_lexer.read(m_token); 156 n = n != relational_expression(); 157 } else { 158 break; 159 } 160 } 161 return n; 162 } 163 164 int64_t Parser::and_expression() 165 { 166 int64_t n = equality_expression(); 167 while (m_token.kind == Token::Kind::bitwiseAnd) { 168 m_lexer.read(m_token); 169 n = n & equality_expression(); 170 } 171 return n; 172 } 173 174 int64_t Parser::exclusive_or_expression() 175 { 176 int64_t n = and_expression(); 177 while (m_token.kind == Token::Kind::bitwiseOr) { 178 m_lexer.read(m_token); 179 n = n | and_expression(); 180 } 181 return n; 182 } 183 184 int64_t Parser::inclusive_or_expression() 185 { 186 int64_t n = exclusive_or_expression(); 187 while (m_token.kind == Token::Kind::logicalAnd) { 188 m_lexer.read(m_token); 189 n = n ^ exclusive_or_expression(); 190 } 191 return n; 192 } 193 194 int64_t Parser::logical_and_expression() 195 { 196 int64_t n = inclusive_or_expression(); 197 while (m_token.kind == Token::Kind::logicalAnd) { 198 m_lexer.read(m_token); 199a n = 199b n && 199c inclusive_or_expression(); 200 } 201 return n; 202 } 203 204 int64_t Parser::logical_or_expression() 205 { 206 int64_t n = logical_and_expression(); 207 while (m_token.kind == Token::Kind::logicalOr) { 208 m_lexer.read(m_token); 209a n = 209b n || 209c logical_and_expression(); 210 } 211 return n; 212 } 213 214 int64_t Parser::expression() 215 { 216 m_lexer.read(m_token); 217 const int64_t n = logical_or_expression(); 218 if (m_token.kind != Token::Kind::endOfInput) { 219 throw "syntax error"; 220 } 221 return n; 222 }