@staticmethod<EOL><INDENT>def parse_AMR_line(line):<DEDENT>
<EOL>state = <NUM_LIT:0><EOL>stack = []<EOL>cur_charseq = []<EOL>node_dict = {}<EOL>node_name_list = []<EOL>node_relation_dict1 = defaultdict(list)<EOL>node_relation_dict2 = defaultdict(list)<EOL>cur_relation_name = "<STR_LIT>"<EOL>in_quote = False<EOL>for i, c in enumerate(line.strip()):<EOL><INDENT>if c == "<STR_LIT:U+0020>":<EOL><INDENT>if state == <NUM_LIT:2>:<EOL><INDENT>cur_charseq.append(c)<EOL><DEDENT>continue<EOL><DEDENT>if c == "<STR_LIT>":<EOL><INDENT>if in_quote:<EOL><INDENT>cur_charseq.append('<STR_LIT:_>')<EOL><DEDENT>in_quote = not in_quote<EOL><DEDENT>elif c == "<STR_LIT:(>":<EOL><INDENT>if in_quote:<EOL><INDENT>cur_charseq.append(c)<EOL>continue<EOL><DEDENT>if state == <NUM_LIT:2>:<EOL><INDENT>if cur_relation_name != "<STR_LIT>":<EOL><INDENT>print("<STR_LIT>", line[<NUM_LIT:0>:i + <NUM_LIT:1>], file=ERROR_LOG)<EOL>return None<EOL><DEDENT>cur_relation_name = "<STR_LIT>".join(cur_charseq).strip()<EOL>cur_charseq[:] = []<EOL><DEDENT>state = <NUM_LIT:1><EOL><DEDENT>elif c == "<STR_LIT::>":<EOL><INDENT>if in_quote:<EOL><INDENT>cur_charseq.append(c)<EOL>continue<EOL><DEDENT>if state == <NUM_LIT:3>:<EOL><INDENT>node_value = "<STR_LIT>".join(cur_charseq)<EOL>cur_charseq[:] = []<EOL>cur_node_name = stack[-<NUM_LIT:1>]<EOL>node_dict[cur_node_name] = node_value<EOL><DEDENT>elif state == <NUM_LIT:2>:<EOL><INDENT>temp_attr_value = "<STR_LIT>".join(cur_charseq)<EOL>cur_charseq[:] = []<EOL>parts = temp_attr_value.split()<EOL>if len(parts) < <NUM_LIT:2>:<EOL><INDENT>print("<STR_LIT>", line[<NUM_LIT:0>:i + <NUM_LIT:1>], file=ERROR_LOG)<EOL>return None<EOL><DEDENT>relation_name = parts[<NUM_LIT:0>].strip()<EOL>relation_value = parts[<NUM_LIT:1>].strip()<EOL>if len(stack) == <NUM_LIT:0>:<EOL><INDENT>print("<STR_LIT>", line[:i], relation_name, relation_value, file=ERROR_LOG)<EOL>return None<EOL><DEDENT>if relation_value not in node_dict:<EOL><INDENT>node_relation_dict2[stack[-<NUM_LIT:1>]].append((relation_name, relation_value))<EOL><DEDENT>else:<EOL><INDENT>node_relation_dict1[stack[-<NUM_LIT:1>]].append((relation_name, relation_value))<EOL><DEDENT><DEDENT>state = <NUM_LIT:2><EOL><DEDENT>elif c == "<STR_LIT:/>":<EOL><INDENT>if in_quote:<EOL><INDENT>cur_charseq.append(c)<EOL>continue<EOL><DEDENT>if state == <NUM_LIT:1>:<EOL><INDENT>node_name = "<STR_LIT>".join(cur_charseq)<EOL>cur_charseq[:] = []<EOL>if node_name in node_dict:<EOL><INDENT>print("<STR_LIT>", node_name, "<STR_LIT>", file=ERROR_LOG)<EOL>return None<EOL><DEDENT>stack.append(node_name)<EOL>node_name_list.append(node_name)<EOL>if cur_relation_name != "<STR_LIT>":<EOL><INDENT>if not cur_relation_name.endswith("<STR_LIT>"):<EOL><INDENT>node_relation_dict1[stack[-<NUM_LIT:2>]].append((cur_relation_name, node_name))<EOL><DEDENT>else:<EOL><INDENT>node_relation_dict1[node_name].append((cur_relation_name[:-<NUM_LIT:3>], stack[-<NUM_LIT:2>]))<EOL><DEDENT>cur_relation_name = "<STR_LIT>"<EOL><DEDENT><DEDENT>else:<EOL><INDENT>print("<STR_LIT>", line[<NUM_LIT:0>:i + <NUM_LIT:1>], file=ERROR_LOG)<EOL>return None<EOL><DEDENT>state = <NUM_LIT:3><EOL><DEDENT>elif c == "<STR_LIT:)>":<EOL><INDENT>if in_quote:<EOL><INDENT>cur_charseq.append(c)<EOL>continue<EOL><DEDENT>if len(stack) == <NUM_LIT:0>:<EOL><INDENT>print("<STR_LIT>", i, "<STR_LIT>", line[<NUM_LIT:0>:i + <NUM_LIT:1>], file=ERROR_LOG)<EOL>return None<EOL><DEDENT>if state == <NUM_LIT:2>:<EOL><INDENT>temp_attr_value = "<STR_LIT>".join(cur_charseq)<EOL>cur_charseq[:] = []<EOL>parts = temp_attr_value.split()<EOL>if len(parts) < <NUM_LIT:2>:<EOL><INDENT>print("<STR_LIT>", line[:i + <NUM_LIT:1>], temp_attr_value, file=ERROR_LOG)<EOL>return None<EOL><DEDENT>relation_name = parts[<NUM_LIT:0>].strip()<EOL>relation_value = parts[<NUM_LIT:1>].strip()<EOL>if relation_name.endswith("<STR_LIT>"):<EOL><INDENT>node_relation_dict1[relation_value].append((relation_name[:-<NUM_LIT:3>], stack[-<NUM_LIT:1>]))<EOL><DEDENT>elif relation_value not in node_dict:<EOL><INDENT>node_relation_dict2[stack[-<NUM_LIT:1>]].append((relation_name, relation_value))<EOL><DEDENT>else:<EOL><INDENT>node_relation_dict1[stack[-<NUM_LIT:1>]].append((relation_name, relation_value))<EOL><DEDENT><DEDENT>elif state == <NUM_LIT:3>:<EOL><INDENT>node_value = "<STR_LIT>".join(cur_charseq)<EOL>cur_charseq[:] = []<EOL>cur_node_name = stack[-<NUM_LIT:1>]<EOL>node_dict[cur_node_name] = node_value<EOL><DEDENT>stack.pop()<EOL>cur_relation_name = "<STR_LIT>"<EOL>state = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>cur_charseq.append(c)<EOL><DEDENT><DEDENT>node_value_list = []<EOL>relation_list = []<EOL>attribute_list = []<EOL>for v in node_name_list:<EOL><INDENT>if v not in node_dict:<EOL><INDENT>print("<STR_LIT>", v, file=ERROR_LOG)<EOL>return None<EOL><DEDENT>else:<EOL><INDENT>node_value_list.append(node_dict[v])<EOL><DEDENT>node_rel_list = []<EOL>node_attr_list = []<EOL>if v in node_relation_dict1:<EOL><INDENT>for v1 in node_relation_dict1[v]:<EOL><INDENT>node_rel_list.append([v1[<NUM_LIT:0>], v1[<NUM_LIT:1>]])<EOL><DEDENT><DEDENT>if v in node_relation_dict2:<EOL><INDENT>for v2 in node_relation_dict2[v]:<EOL><INDENT>if v2[<NUM_LIT:1>][<NUM_LIT:0>] == "<STR_LIT>" and v2[<NUM_LIT:1>][-<NUM_LIT:1>] == "<STR_LIT>":<EOL><INDENT>node_attr_list.append([[v2[<NUM_LIT:0>]], v2[<NUM_LIT:1>][<NUM_LIT:1>:-<NUM_LIT:1>]])<EOL><DEDENT>elif v2[<NUM_LIT:1>] in node_dict:<EOL><INDENT>node_rel_list.append([v2[<NUM_LIT:0>], v2[<NUM_LIT:1>]])<EOL><DEDENT>else:<EOL><INDENT>node_attr_list.append([v2[<NUM_LIT:0>], v2[<NUM_LIT:1>]])<EOL><DEDENT><DEDENT><DEDENT>relation_list.append(node_rel_list)<EOL>attribute_list.append(node_attr_list)<EOL><DEDENT>attribute_list[<NUM_LIT:0>].append(["<STR_LIT>", node_value_list[<NUM_LIT:0>]])<EOL>result_amr = AMR(node_name_list, node_value_list, relation_list, attribute_list)<EOL>return result_amr<EOL>
Parse a AMR from line representation to an AMR object.
This parsing algorithm scans the line once and process each character, in a shift-reduce style.