[add] tool:convert
This commit is contained in:
parent
079d559400
commit
8fe2a17e41
167
tools/convert
Executable file
167
tools/convert
Executable file
|
|
@ -0,0 +1,167 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys as _sys
|
||||
import re as _re
|
||||
import json as _json
|
||||
|
||||
|
||||
def coin(template, arguments):
|
||||
result = template
|
||||
for (key, value, ) in arguments.items():
|
||||
result = result.replace("{{%s}}" % key, value)
|
||||
return result
|
||||
|
||||
|
||||
def convert_symbol(symbol):
|
||||
if (symbol.startswith("<")):
|
||||
return {"type": "variable", "parameters": {"id": symbol[1:-1]}}
|
||||
elif (symbol.startswith("[")):
|
||||
return {"type": "terminal", "parameters": {"id": symbol[1:-1]}}
|
||||
elif (symbol.startswith("{")):
|
||||
return {"type": "label", "parameters": {"id": symbol[1:-1]}}
|
||||
else:
|
||||
raise ValueError("unknown symbol: %s" % symbol)
|
||||
|
||||
|
||||
def extract_name(symbol, type_):
|
||||
conversion = convert_symbol(symbol)
|
||||
if (not (conversion["type"] == type_)):
|
||||
raise ValueError("type mismatch")
|
||||
else:
|
||||
name = conversion["parameters"]["id"]
|
||||
return (None if (name == "") else name)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
pattern_name = "[0-9a-zA-Z_-]*"
|
||||
pattern_terminal = coin("\[{{pattern_name}}\]", {"pattern_name": pattern_name})
|
||||
pattern_variable = coin("<{{pattern_name}}>", {"pattern_name": pattern_name})
|
||||
pattern_label = coin("\{{{pattern_name}}\}", {"pattern_name": pattern_name})
|
||||
|
||||
rules = [
|
||||
# version
|
||||
{
|
||||
"pattern": coin(
|
||||
"@{{space}}(.+)",
|
||||
{
|
||||
"space": "\s*",
|
||||
}
|
||||
),
|
||||
"action": lambda state, matching: {
|
||||
"version": matching.group(1),
|
||||
"specification": state["specification"],
|
||||
},
|
||||
},
|
||||
# lexer_rule
|
||||
{
|
||||
"pattern": coin(
|
||||
"{{space}}({{pattern_terminal}}){{space}}:{{space}}\"(.*)\"(?:{{space}}:{{space}}(\S+){{space}})?",
|
||||
{
|
||||
"space": "\s*",
|
||||
"pattern_terminal": pattern_terminal,
|
||||
}
|
||||
),
|
||||
"action": lambda state, matching: {
|
||||
"version": state["version"],
|
||||
"specification": {
|
||||
"version": state["specification"]["version"],
|
||||
"lexer_rules": (
|
||||
state["specification"]["lexer_rules"]
|
||||
+
|
||||
[{
|
||||
"pattern": matching.group(2),
|
||||
"name": extract_name(matching.group(1), "terminal"),
|
||||
"pass": (len(matching.groups()) >= 3),
|
||||
}]
|
||||
),
|
||||
"parser_rules": state["specification"]["parser_rules"],
|
||||
"parser_start": state["specification"]["parser_start"],
|
||||
}
|
||||
}
|
||||
},
|
||||
# parser_rule
|
||||
{
|
||||
"pattern": coin(
|
||||
"({{pattern_label}}){{space}}:{{space}}({{pattern_variable}}){{space}}:(.*)",
|
||||
{
|
||||
"space": "\s*",
|
||||
"pattern_variable": pattern_variable,
|
||||
"pattern_label": pattern_label,
|
||||
}
|
||||
),
|
||||
"action": lambda state, matching: {
|
||||
"version": state["version"],
|
||||
"specification": {
|
||||
"version": state["specification"]["version"],
|
||||
"lexer_rules": state["specification"]["lexer_rules"],
|
||||
"parser_rules": (
|
||||
state["specification"]["parser_rules"]
|
||||
+
|
||||
[{
|
||||
"label": extract_name(matching.group(1), "label"),
|
||||
"premise": extract_name(matching.group(2), "variable"),
|
||||
"conclusion": list(map(
|
||||
convert_symbol,
|
||||
_re.findall(
|
||||
coin(
|
||||
"{{pattern_terminal}}|{{pattern_variable}}",
|
||||
{
|
||||
"pattern_terminal": pattern_terminal,
|
||||
"pattern_variable": pattern_variable,
|
||||
}
|
||||
),
|
||||
matching.group(3)
|
||||
)
|
||||
)),
|
||||
}]
|
||||
),
|
||||
"parser_start": state["specification"]["parser_start"],
|
||||
}
|
||||
}
|
||||
},
|
||||
# parser_start
|
||||
{
|
||||
"pattern": coin(
|
||||
"({{pattern_variable}})",
|
||||
{
|
||||
"space": "\s*",
|
||||
"pattern_variable": pattern_variable,
|
||||
}
|
||||
),
|
||||
"action": lambda state, matching: {
|
||||
"version": state["version"],
|
||||
"specification": {
|
||||
"version": state["specification"]["version"],
|
||||
"lexer_rules": state["specification"]["lexer_rules"],
|
||||
"parser_rules": state["specification"]["parser_rules"],
|
||||
"parser_start": extract_name(matching.group(1), "variable"),
|
||||
}
|
||||
}
|
||||
},
|
||||
# empty
|
||||
{
|
||||
"pattern": ".*",
|
||||
"action": lambda state, matching: state,
|
||||
},
|
||||
]
|
||||
|
||||
state = {
|
||||
"version": "1",
|
||||
"specification": {
|
||||
"version": "2",
|
||||
"lexer_rules": [],
|
||||
"parser_rules": [],
|
||||
"parser_start": None,
|
||||
},
|
||||
}
|
||||
content = _sys.stdin.read()
|
||||
for line in content.split("\n"):
|
||||
for rule in rules:
|
||||
matching = _re.match("^%s$" % rule["pattern"], line)
|
||||
if (not (matching is None)):
|
||||
state = rule["action"](state, matching)
|
||||
break
|
||||
_sys.stdout.write(_json.dumps(state["specification"], indent = "\t"))
|
||||
|
||||
main()
|
||||
Loading…
Reference in a new issue