鉴于this grammar:
(* integers *)
DEC = /([1-9][0-9]*|0+)/;
int = /(0b[01]+|0o[0-7]+|0x[0-9a-fA-F]+)/ | DEC;
(* floats *)
pointfloat = /([0-9]*\.[0-9]+|[0-9]+\.)/;
expfloat = /([0-9]+\.?|[0-9]*\.)[eE][+-]?[0-9]+/;
float = pointfloat | expfloat;
list = '[' @+:atom {',' @+:atom}* ']';
(* atoms *)
identifier = /[_a-zA-Z][_a-zA-Z0-9]*/;
symbol = int |
float |
identifier |
list;
(* functions *)
arglist = @+:atom {',' @+:atom}*;
function = identifier '(' [arglist] ')';
atom = function | symbol;
prec8 = '(' atom ')' | atom;
prec7 = [('+' | '-' | '~')] prec8;
prec6 = prec7 ['!'];
prec5 = [prec6 '**'] prec6;
prec4 = [prec5 ('*' | '/' | '%' | 'd')] prec5;
prec3 = [prec4 ('+' | '-')] prec4;
(* <| and >| are rotate-left and rotate-right, respectively. They assume the nearest C size. *)
prec2 = [prec3 ('<<' | '>>' | '<|' | '>|')] prec3;
prec1 = [prec2 ('&' | '|' | '^')] prec2;
expr = prec1 $;
class ChessaSemantics:
def int(self, ast):
return int(ast)
def float(self, ast):
return float(ast)
def list(self, ast):
return ast
def identifier(self, ast):
if isinstance(ast, str) and ast in variables:
return variables[ast]
else:
return ast
def function(self, ast):
func = funcs[ast[0]][0]
args = ast[2:-1]
if len(args) < funcs[ast[0]][1]:
raise ValueError('insufficient arguments')
return func(*args)
def prec8(self, ast):
return ast
def prec7(self, ast):
if isinstance(ast, list) and len(ast) > 1 and not isinstance(ast[0], (int, float, list)):
return unop[ast[0]](ast[1])
else:
return ast
def prec6(self, ast):
if isinstance(ast, list) and len(ast) > 1 and not isinstance(ast[1], (int, float, list)):
return unop[ast[1]](ast[0])
else:
return ast
def prec5(self, ast):
if isinstance(ast, list) and len(ast) > 2 and not isinstance(ast[1], (int, float, list)):
return binop[ast[1]](ast[0], ast[2])
else:
return ast
def prec4(self, ast):
if isinstance(ast, list) and len(ast) > 2 and not isinstance(ast[1], (int, float, list)):
return binop[ast[1]](ast[0], ast[2])
else:
return ast
def prec3(self, ast):
if isinstance(ast, list) and len(ast) > 2 and not isinstance(ast[1], (int, float, list)):
return binop[ast[1]](ast[0], ast[2])
else:
return ast
def prec2(self, ast):
if isinstance(ast, list) and len(ast) > 2 and not isinstance(ast[1], (int, float, list)):
return binop[ast[1]](ast[0], ast[2])
else:
return ast
def prec1(self, ast):
if isinstance(ast, list) and len(ast) > 2 and not isinstance(ast[1], (int, float, list)):
return binop[ast[1]](ast[0], ast[2])
else:
return ast
...遇到带有非整数元素的列表时,我的解析器会因no available options
错误而停止(浮点数或列表;但变量很好)。
示例:
drop(4d6, 1)
[1.5, 2, 3]
有趣的是,drop([1, 2, 4, 2], 1)
行为正确并输出[2, 4, 2]
。