0

この文法を考えると:

(* 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]

4

0 に答える 0