⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.118
Server IP:
2.57.91.2
Server:
Linux sg-nme-web1518.main-hosting.eu 5.14.0-611.16.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Dec 22 03:40:39 EST 2025 x86_64
Server Software:
LiteSpeed
PHP Version:
8.3.28
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
opt
/
gsutil
/
third_party
/
pyparsing
/
examples
/
View File Name :
lox_parser.py
""" The Lox language grammar From Robert Nystrom's "Crafting Interpreters" http://craftinginterpreters.com/ The BNF for the Lox language is at http://craftinginterpreters.com/appendix-i.html """ import pyparsing as pp pp.ParserElement.enable_packrat() # punctuation COMMA, LPAR, RPAR, LBRACE, RBRACE, EQ, SEMI = map(pp.Suppress, ",(){}=;") # keywords (CLASS, FUN, VAR, FOR, IF, ELSE, PRINT, RETURN, WHILE, TRUE, FALSE, NIL, THIS, SUPER, AND, OR) = pp.Keyword.using_each( "class fun var for if else print return while" " true false nil this super and or".split() ) identifier = pp.Word(pp.alphas + "_", pp.alphanums + "_'") string = pp.QuotedString('"') number = pp.Regex(r"\d+(?:\.\d+)?") declaration = pp.Forward() statement = pp.Forward() class_decl = pp.Forward() expression = pp.Forward() block = pp.Forward() arguments = pp.DelimitedList(expression) parameters = pp.DelimitedList(identifier) function = identifier + LPAR + pp.Opt(parameters) + RPAR + block property_ = identifier + block fun_decl = FUN + function var_decl = VAR + identifier + pp.Opt(EQ + expression) + SEMI class_decl <<= ( CLASS - identifier + pp.Opt("<" + identifier) + LBRACE + (function | property_ | class_decl)[...] + RBRACE ) primary = (TRUE | FALSE | NIL | THIS | number | string | identifier | SUPER + "." + identifier # | LPAR + expression + RPAR <-- not needed, infix_notation takes care of this ).set_name("primary") call = primary + ( LPAR + pp.Opt(arguments) + RPAR | "." + identifier )[1, ...] arith_expression = pp.infix_notation( (call | primary).set_name("arith_operand"), [ (pp.one_of("! -"), 1, pp.opAssoc.RIGHT), (pp.one_of("/ *"), 2, pp.opAssoc.LEFT), (pp.one_of("- +"), 2, pp.opAssoc.LEFT), (pp.one_of("> >= < <="), 2, pp.opAssoc.LEFT), (pp.one_of("!= =="), 2, pp.opAssoc.LEFT), (AND, 2, pp.opAssoc.LEFT), (OR, 2, pp.opAssoc.LEFT), ] ) assignment = pp.Forward() assignment <<= (call | identifier) + EQ + (assignment | arith_expression) expression <<= assignment ^ arith_expression ^ function block <<= pp.Group(LBRACE + declaration[...] + RBRACE) while_statement = WHILE + LPAR + expression + RPAR + statement return_statement = RETURN + pp.Opt(expression) + SEMI print_statement = PRINT + expression + SEMI if_statement = IF + LPAR + expression + RPAR + statement + pp.Opt(ELSE + statement) expr_statement = expression + ";" for_statement = FOR + LPAR + pp.Group( (var_decl | expr_statement | ";") + pp.Opt(expression) + ";" + pp.Opt(expression) ) + RPAR + statement statement <<= pp.Group( expr_statement | for_statement | if_statement | print_statement | return_statement | while_statement | block ) declaration <<= ( class_decl | fun_decl | var_decl | statement ) program = declaration[...] program.ignore(pp.dbl_slash_comment) # define names so that we get a better diagram pp.autoname_elements() def main(): import textwrap success, _ = program.run_tests( textwrap.dedent(t) for t in [ """\ var a = 1; { var a = a + 2; print a; } """, """\ { var i = 0; while (i < 10) { print i; i = i + 1; } } """, """\ var a = 0; var temp; for (var b = 1; a < 10000; b = temp + b) { print a; temp = a; a = b; } """, """\ fun add(a, b, c) { print a + b + c; } add(1, 2, 3); """, """\ fun count(n) { while (n < 100) { if (n == 3) return n; // <-- print n; n = n + 1; } } count(1); """, """\ fun fib(n) { if (n <= 1) return n; return fib(n - 2) + fib(n - 1); } for (var i = 0; i < 20; i = i + 1) { print fib(i); } """, """\ fun makeCounter() { var i = 0; fun count() { i = i + 1; print i; } return count; } var counter = makeCounter(); counter(); // "1". counter(); // "2". """, """\ fun thrice(fn) { for (var i = 1; i <= 3; i = i + 1) { fn(i); } } thrice(fun (a) { print a; }); // "1". // "2". // "3". """, """\ class Math { square(n) { return n * n; } } print Math.square(3); // Prints "9". """, """\ class Circle { init(radius) { this.radius = radius; } area { return 3.141592653 * this.radius * this.radius; } } var circle = Circle(4); print circle.area; // Prints roughly "50.2655". """, """\ // Your first Lox program! print "Hello, world!"; """ ] ) assert success if __name__ == '__main__': import contextlib with contextlib.suppress(Exception): program.create_diagram("lox_parser_diagram.html", vertical=2, show_groups=True) main()