-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.vscode | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from representation import Pair | ||
from split import bulid_exp_list | ||
|
||
class Stack: | ||
def __init__(self, line=None): | ||
self.line = line or [] | ||
self.index = len(self.line) | ||
|
||
def pop(self): | ||
self.index -= 1 | ||
return self.line.pop() | ||
|
||
def top(self): | ||
return self.line[self.index-1] | ||
|
||
def stash(self, val): | ||
self.index += 1 | ||
self.line.append(val) | ||
|
||
def not_empty(self): | ||
return self.index > 0 | ||
|
||
def parse(exp_stack): | ||
buffer = Stack() | ||
while exp_stack.not_empty(): | ||
val = exp_stack.pop() | ||
if val == ')': | ||
buffer.stash(val) | ||
elif val == '(': | ||
car = buffer.pop() | ||
buffer.pop() | ||
if buffer.not_empty(): | ||
if buffer.top() != ')': | ||
cdr = buffer.pop() | ||
val = Pair(car, cdr) | ||
buffer.stash(val) | ||
else: | ||
buffer.stash(car) | ||
else: | ||
return car | ||
else: | ||
if buffer.top() == ')': | ||
buffer.stash(Pair(val, None)) | ||
else: | ||
cdr = buffer.pop() | ||
buffer.stash(Pair(val, cdr)) | ||
|
||
if __name__ == "__main__": | ||
#b1 = Stack(["(", "*", 1, 2, ")"]) | ||
#b2 = Stack(["(", "*", "(", "+", 1, 2, ")", 3, ")"]) | ||
#val1 = parse(b1) | ||
#val2 = parse(b2) | ||
#print(val1) | ||
#print(val2) | ||
exp = "(lambda (x) (+ 1 x))" | ||
print(exp) | ||
exp = bulid_exp_list(exp) | ||
print(exp) | ||
b3 = Stack(exp) | ||
print(parse(b3)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
class Pair: | ||
"""Pair: has car and cdr""" | ||
|
||
def __init__(self, car, cdr): | ||
self.car = car | ||
self.cdr = cdr | ||
|
||
def __repr__(self): | ||
return "<Pair: {car} {cdr}>".format(car=repr(self.car), | ||
cdr=repr(self.cdr)) | ||
|
||
def __str__(self): | ||
s = "(" + str(self.car) | ||
cdr = self.cdr | ||
while isinstance(cdr, Pair): | ||
s += " " + str(cdr.car) | ||
cdr = cdr.cdr | ||
if cdr is not None: | ||
s += " . " + str(cdr) | ||
return s + ")" | ||
|
||
def __len__(self): | ||
n, cdr = 1, self.cdr | ||
while isinstance(cdr, Pair): | ||
n += 1 | ||
cdr = cdr.cdr | ||
if cdr is not None: | ||
raise TypeError("length attempted on improper list") | ||
return n |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import string | ||
|
||
_NUMERAL_STARTS = set(string.digits) | set('+-.') | ||
_SYMBOL_CHARS = (set('!$%&*/:<=>?@^_~') | set(string.ascii_lowercase) | | ||
set(string.ascii_uppercase) | _NUMERAL_STARTS) | ||
_STRING_DELIMS = set('"') | ||
_WHITESPACE = set(' \t\n\r') | ||
_SINGLE_CHAR_TOKENS = set("()'`") | ||
_TOKEN_END = _WHITESPACE | _SINGLE_CHAR_TOKENS | _STRING_DELIMS | {',', ',@'} | ||
DELIMITERS = _SINGLE_CHAR_TOKENS | {'.', ',', ',@'} | ||
|
||
def split_exp_str(line, index=0): | ||
"""返回分割得到的字符串""" | ||
var = [] | ||
while index < len(line): | ||
var.clear() | ||
char = line[index] | ||
if char in _WHITESPACE: | ||
index += 1 | ||
elif char in _STRING_DELIMS: | ||
index += 1 # 跳过" | ||
char = line[index] | ||
while char not in _STRING_DELIMS: | ||
var.append(char) | ||
index += 1 | ||
char = line[index] | ||
index += 1 # 跳过" | ||
yield "".join(var) | ||
elif char in _SINGLE_CHAR_TOKENS: | ||
index += 1 | ||
yield char | ||
elif char in _SYMBOL_CHARS: | ||
while char not in _WHITESPACE | _SINGLE_CHAR_TOKENS: | ||
var.append(char) | ||
index += 1 | ||
char = line[index] | ||
yield "".join(var) | ||
|
||
def bulid_exp_list(line): | ||
exp = [] | ||
for var in split_exp_str(line): | ||
exp.append(var) | ||
return exp | ||
|
||
if __name__ == "__main__": | ||
print(bulid_exp_list('(define "asd" (+ 1 2) (* 3 4) "adf")')) |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.