whenever-py / whenever / parse.py

from pypy.rlib.streamio import open_file_as_stream

from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function
from pypy.rlib.parsing.deterministic import LexerError
from pypy.rlib.parsing.parsing import ParseError


def parse(filename):
    result = {}

    fp = open_file_as_stream(filename)
    while True:
        line = fp.readline()
        if len(line) == 0:
            break
        number, commands = parseline(line)
        assert number not in result
        result[number] = commands
    return result



def parseline(line):
    number_str, commands = line.split(' ', 1)
    try:
        return int(number_str), parse_command(commands[:-1])
    except LexerError, e:
        print e.args[0], e.nice_error_message()
        print commands
        print ' '*e.args[2].i + '^'
        raise
    except ParseError, e:
        print e.args[0], e.nice_error_message()
        print commands
        print ' '*e.args[0].i + '^'
        raise

regexs, rules, ToAST = parse_ebnf(
"""
IGNORE: " ";
DECIMAL: "0|[1-9][0-9]*";
STRING: "\\"[^\\\\"]*\\"";

RPAR: "\)";
LPAR: "\(";
PLUS: "\+";
STAR: "\*";
FUNC: "N";

EQ: "==";
LT: "<";
GT: ">";
LTE: "<=";
GTE: ">=";

SHARP: "#";
COMMA: ",";
SEMICOLON: ";";

OR: "\|\|";
AND: "&&";

command:  >op<  [SEMICOLON] ;
op: action+ statements | action+ | statements;



integer: <DECIMAL> | "-" DECIMAL;
number: <integer>| <function> | <STRING>;

statement: integer [SHARP] expr | integer;
statements: (statement [COMMA])* statement;



function: ["N"] [LPAR] expr [RPAR];

addition: (number [PLUS])* number;
expr: <addition>;

comparisation: EQ | LT | GT | LTE | GTE;
compare: expr >comparisation< expr;


bool: compare | expr;
chain: AND |OR;
boolean: (bool >chain<)* bool;


ACTION: "defer|again|forget";
PRINT: "print";
action: ACTION [LPAR] boolean [RPAR] | [PRINT] [LPAR] expr [RPAR];

""")


parse_function = make_parse_function(regexs, rules)

def parse_command(command):
    parse_tree = parse_function(command)
    to_ast = ToAST()
    tree = to_ast.transform(parse_tree)
    #tree.view()
    return tree
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.