Created
June 4, 2018 07:12
-
-
Save WorryingWonton/67a9eafd754799dbf181e46c5fc70798 to your computer and use it in GitHub Desktop.
Tuple work-around for parse error caused by multiple inputs to a function in Java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #See the terminal symbol 'arg_list' in cbat_grammar | |
| #I noticed that functions on CodingBat were always in the form 'function_name' '(' 'arg' (',' 'whitespace_token'? arg)* ')' | |
| #My grammar originally didn't have a way to deal with this. | |
| #It could deal with multiple arguments in an array or map, but multiple- | |
| #comma separated arguments not in a container literal would cause Lark to fail. | |
| #To get around this, I figured I could treate the parentheses around the function arguments as a tuple, so... that's what I've done. | |
| #Thus far it seems to work, though it feels inelegant. | |
| from lark import Transformer, Lark | |
| cbat_grammar = """ | |
| ?literal : string | |
| | char | |
| | array | |
| | map | |
| | int | |
| | float | |
| | boolean | |
| | arg_list | |
| array : "[" [literal ("," literal)*] "]" | |
| map : "{" [kv_pair ("," kv_pair)*] "}" | |
| kv_pair : literal ":" literal | |
| string : ESCAPED_STRING | |
| char : /'.'/ | |
| float : /-?[0-9]+.[0-9]*/ | |
| int : /-?[0-9]+/ | |
| boolean : /true|false/ | |
| arg_list : "(" [literal ("," literal)*] ")" | |
| %import common.ESCAPED_STRING | |
| %import common.WS | |
| %ignore WS | |
| """ | |
| class ASTElement(): | |
| pass | |
| class AtomicLiteral(ASTElement): | |
| def __init__(self, scalar): | |
| self.scalar = scalar | |
| def to_rust_code(self): | |
| return f'{self.scalar}' | |
| class ArrayLiteral(ASTElement): | |
| def __init__(self, arrayx): | |
| self.arrayx = arrayx | |
| self.item_type = None | |
| def to_rust_code(self): | |
| if len(self.arrayx) > 0: | |
| string = 'vec![' | |
| count = 0 | |
| for elem in self.arrayx: | |
| if count < len(self.arrayx) - 1: | |
| string += elem.to_rust_code() + ', ' | |
| count += 1 | |
| else: | |
| string += elem.to_rust_code() | |
| return string + ']' | |
| else: | |
| return f'Vec::<{self.item_type}>::new()' | |
| class ArgList(ASTElement): | |
| def __init__(self, args): | |
| self.args = args | |
| def to_rust_code(self): | |
| string = '' | |
| count = 0 | |
| for elem in self.args: | |
| if count < len(self.args) - 1: | |
| string += elem.to_rust_code() + ', ' | |
| count += 1 | |
| else: | |
| string += elem.to_rust_code() | |
| return string | |
| class MapLiteral(ASTElement): | |
| def __init__(self, mapx): | |
| self.mapx = mapx | |
| def to_rust_code(self): | |
| string = '{let mut m = BTreeMap::new();\n' | |
| for kv_pair in self.mapx: | |
| string += f'm.insert({kv_pair[0].to_rust_code()}, {kv_pair[1].to_rust_code()});\n' | |
| string += '}' | |
| return string | |
| class JTransformer(Transformer): | |
| def int(self, int): | |
| return AtomicLiteral(int[0].value) | |
| def float(self, float): | |
| return AtomicLiteral(float[0].value) | |
| def boolean(self, boolean): | |
| return AtomicLiteral(boolean[0].value) | |
| def char(self, char): | |
| return AtomicLiteral(char[0].value) | |
| def string(self, string): | |
| return AtomicLiteral(string[0].value) | |
| def array(self, items): | |
| return ArrayLiteral(items) | |
| def map(self, items): | |
| return MapLiteral([item.children for item in items]) | |
| def arg_list(self, items): | |
| return ArgList(items) | |
| # parser = Lark(cbat_grammar, start='literal') | |
| # stuff = JTransformer().transform(parser.parse("[1, [2, [3], {3: [2, 2, 2], 5: 1}], true, false, \"Hello\", 'a', 1.2, 2.2222312312321]")) | |
| # print(stuff.to_rust_code()) | |
| # | |
| # stuff2 = JTransformer().transform(parser.parse("([1, 2], [1, 2])")) | |
| # print(stuff2) | |
| # print(stuff2.to_rust_code()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment