-
Notifications
You must be signed in to change notification settings - Fork 4
/
Parser.cpp
80 lines (70 loc) · 2.18 KB
/
Parser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
//
// Parser.cpp
// Scheme_Interpreter
//
// Created by Josh Sun on 2017-05-08.
// Copyright © 2017 Josh Sun. All rights reserved.
//
#include "Parser.hpp"
SList Parser::parse(const std::string rawInput) {
std::deque<std::string> temp = tokenize(rawInput);
return process_syntax(temp);
}
std::deque<std::string> Parser::tokenize(const std::string rawInput) {
std::deque<std::string> tokens;
for (int i = 0; i < rawInput.length(); ++i) {
while (rawInput[i] == ' ') ++i;
if (rawInput[i] == '(') tokens.push_back("(");
else if (rawInput[i] == ')') tokens.push_back(")");
else {
int j = i;
while (rawInput[j] && rawInput[j] != ')' && rawInput[j] != '(' && rawInput[j] != ' ')
++j;
tokens.push_back(rawInput.substr(i,j-i));
i = j-1;
}
}
return tokens;
}
SList Parser::process_syntax (std::deque<std::string>& tokens) {
if (tokens.size()==0) throw "Syntax Error: Unexpected End of Line";
std::string token = tokens[0];
tokens.pop_front();
if (token == "'") {
for (auto vi = tokens.begin(); vi != tokens.end(); vi++) {
if (*vi==")") {
tokens.insert(vi,")");
break;
}
}
tokens.push_front("quote");
tokens.push_front("(");
return process_syntax (tokens);
} else if (token == "(") { //expression
SLists list;
while (tokens[0]!=")") {
list.push_back(process_syntax(tokens));
}
tokens.pop_front();
return SList(list);
} else if (token == ")") {
throw "Syntax Error: Unexpected Syntax ')'";
} else { //atom
return atomic(token);
}
}
SList Parser::atomic (std::string s) {
if (isNumber(s)) {
return SList(atof(s.c_str())); //double/float
}
return SList(s); //symbol
}
bool Parser::isNumber (std::string s) {
return s.find_first_not_of( "0123456789." ) == std::string::npos;
}
bool Parser::isInteger (std::string s) {
if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ;
char * p ;
strtol(s.c_str(), &p, 10) ;
return (*p == 0) ;
}