0

Given 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 $;

and this semantics object:

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

...my parser halts with no available options errors when encountering a list with non-integral elements (floats or lists; variables are fine, though).

Examples:

  • drop(4d6, 1)
  • [1.5, 2, 3]

Interestingly enough, drop([1, 2, 4, 2], 1) behaves correctly and outputs [2, 4, 2].

Aerdan
  • 143
  • 7
  • Please paste your code into the question so that people will still be able to read it next month. See http://stackoverflow.com/help/how-to-ask – PM 2Ring Sep 25 '14 at 23:21
  • Are you sure this is a good idea? There's an awful lot of Python in the second paste, and SO got grouchy at me when I tried to inline it. – Aerdan Sep 26 '14 at 01:32
  • I wasn't aware that there was a size limit (I'm still very new here) but I do agree that your linked material is rather large. It would be _much_ better if you could post an abridged version of the program that exhibits the error. Try to isolate the problem into a chunk of code that others can both read and run. If that's too hard to do, you could simplify your grammar so that it only handles a single operator. Or something. The smaller your program is the more likely it is that people will read it. If you post no code on StackOverflow, you're unlikely to get much help. – PM 2Ring Sep 26 '14 at 11:59
  • Following the StackOveflow suggestions and norms is the best way to get quick and good answers. Also keep in mind that there's a tacit norm that you should try to do your homework at your best before asking for help. – Apalala Sep 27 '14 at 02:37
  • Oh, definitely. My concern was mostly that I didn't want to provide too little information to be useful. – Aerdan Sep 27 '14 at 12:52
  • How are we supposed to debug that? We can't run it, and it refers to various mysterious data structures and functions. – PM 2Ring Oct 01 '14 at 14:58
  • @PM2Ring: it is not mysterious if you are familiar with Grako. The only thing that is missing is `parse()` call so we can assume the default. [Here's complete example](http://stackoverflow.com/a/26195510/4279). – jfs Oct 05 '14 at 17:39
  • Rightio, @J.F.Sebastian; I'm not familiar with Grako. But I'm glad that this question hasn't been lost in oblivion. – PM 2Ring Oct 06 '14 at 13:04
  • possible duplicate of [Rule precedence issue with grako](http://stackoverflow.com/questions/26016475/rule-precedence-issue-with-grako) – Paul Sweatte Oct 13 '14 at 22:18
  • Is there a reason you can't make a minimal example? – Veedrac Oct 14 '14 at 15:49
  • Wasn't this question answered in another forum? If so, please post your own answer here. At any rate, it seems that the regular expressions for floats are wrong. – Apalala Nov 01 '14 at 12:21

0 Answers0