-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Include no-meaning operators in JSON op extraction (#85)
Include no-meaning operators in JSON op extraction, separated by affix: Infix, Postifx, or Prefix. Also, update "meaningful" field comment at the top of the YAML file. Add a unit test for operator-table consistency.
- Loading branch information
Showing
3 changed files
with
145 additions
and
11 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import os.path as osp | ||
from pathlib import Path | ||
|
||
import yaml | ||
|
||
data_dir = Path(osp.normpath(osp.dirname(__file__)), "..", "mathics_scanner", "data") | ||
with open(data_dir / "operators.yml", "r", encoding="utf8") as operator_f, open( | ||
data_dir / "named-characters.yml", "r", encoding="utf8" | ||
) as character_f: | ||
# Load the YAML data. | ||
operator_data = yaml.load(operator_f, Loader=yaml.FullLoader) | ||
character_data = yaml.load(character_f, Loader=yaml.FullLoader) | ||
|
||
|
||
def test_operators(): | ||
# We need to use "operator-name" instead of YAML "name" key | ||
# because of situations like "FunctionAmpersand" | ||
# which is the same as "Function", but "Function" is already | ||
# needed/used as a YAML key. Apply3Ats (MapApply) is another | ||
# example. | ||
character_operator_names = set( | ||
[ | ||
value["operator-name"] | ||
for value in operator_data.values() | ||
if "operator-name" in value | ||
] | ||
) | ||
operator_names = set(tuple(operator_data.keys())) | ||
|
||
left_character_operators = { | ||
operator_name | ||
for operator_name in character_operator_names | ||
if operator_name.startswith("Left") | ||
} | ||
right_character_operators = { | ||
operator_name | ||
for operator_name in character_operator_names | ||
if operator_name.startswith("Right") | ||
} | ||
|
||
# For "Left" operators listed in name characters, check that there is a corresponding "Right" | ||
# and check that the name without "Left" or "Right" appears in the operator table. | ||
left_operator_remove = set() | ||
for left_operator in left_character_operators: | ||
if left_operator in operator_names: | ||
continue | ||
operator_name = left_operator[len("Left") :] | ||
right_operator = "Right" + operator_name | ||
assert right_operator in right_character_operators | ||
assert operator_name in operator_names | ||
# print(f"WOOT short found: {operator_name}") | ||
left_operator_remove.add(left_operator) | ||
|
||
right_operator_remove = set() | ||
for right_operator in right_character_operators: | ||
if right_operator in operator_names: | ||
continue | ||
operator_name = right_operator[len("Right") :] | ||
left_operator = "Left" + operator_name | ||
assert left_operator in left_character_operators | ||
character_operator_names.remove(right_operator) | ||
assert operator_name in operator_names | ||
operator_names.remove(operator_name) | ||
right_operator_remove.add(right_operator) | ||
|
||
character_operator_names -= left_operator_remove | ||
character_operator_names -= right_operator_remove | ||
|
||
# For some reason we decided to exclude "Prefix" as a character operator. Add it back in here | ||
character_operator_names.add("Prefix") | ||
|
||
extra_character_operators = character_operator_names - operator_names | ||
|
||
# FIXME: go over tables to make the below work | ||
# extra_operator_names = operator_names - character_operator_names | ||
# assert not extra_operator_names, f"Should not have extra operators in YAML operator table {extra_operator_names}" | ||
|
||
assert ( | ||
not extra_character_operators | ||
), f"Should not have extra operators in JSON character table {extra_character_operators}" | ||
|
||
|
||
def test_meaningful_affix(): | ||
""" | ||
Check that all operators where the "meaningful" field is "false" have an valid affix value. | ||
""" | ||
for operator_name, operator_info in operator_data.items(): | ||
if operator_info.get("meaningful", True) is False and ( | ||
character_info := character_data.get(operator_name) | ||
): | ||
if (character_info.get("unicode-equivalent")) is None: | ||
assert ( | ||
character_info.get("wl-unicode") is not None | ||
), f"no unicode or WMA equivalent for {operator_name}" | ||
continue | ||
|
||
affix = operator_info["affix"] | ||
assert affix in ( | ||
"Infix", | ||
"Postfix", | ||
"Prefix", | ||
), f"affix {affix} of {operator_name} not handled" |