将 Python 的形式语言翻译成铁路图
Translating Python's formal language into Rail Diagrams
我目前正在尝试将 Python 的形式语法 (https://docs.python.org/3/reference/grammar.html) 翻译成铁路图。
我们正在使用的网站 http://www.bottlecaps.de/rr/ui 对其中的大部分内容都非常有帮助,我们手动更改了很多东西以使用正确的符号来创建轨道图,但仍然有 50 多条线是不正确的并且非常困难供我们修复,因为我们对此是全新的。有没有比手动更改更简单的方法?
请注意该网站使用 EBNF
感谢您的宝贵时间,
编写一个解析语法的解析器,然后从解析树转换为所需的符号。
转换本身相当简单:
- 用'//'替换'#'评论介绍者
- 将“:”标记替换为“::=”
- 将“[”标记替换为“(”
- 将“]”标记替换为“)?”
W3C notation中一个合适的元语法是
Grammar ::= Rule+ EOF
Rule ::= Nonterminal ':' Alternatives
Alternatives
::= Alternative ( '|' Alternative )*
Alternative
::= ( Symbol ( '*' | '+' )? )*
Symbol ::= Nonterminal
| Terminal
| '(' Alternatives ')'
| '[' Alternatives ']'
<?TOKENS?>
Nonterminal
::= [a-z] [a-z_]*
Terminal ::= [A-Z] [A-Z_]*
| "'" [^']+ "'"
EOF ::= $
IgnorableWhitespace
::= [ #x9#xA#xD]+
| '#' [^#xA]* [#xA]
/* ws: definition */
把它放在grammar.ebnf
,然后使用REx to create a parser for it, coded e.g. in XQuery,使用这个命令行:
-xquery -tree
这为您提供了 XQuery 模块 grammar.xquery
。接下来,将 python 语法放在 python.grammar
中,并将此 XQuery 程序放在 transform.xquery
中:
import module namespace p="grammar" at "grammar.xquery";
declare option saxon:output "method=text";
declare variable $input as xs:string external;
for $token in p:parse-Grammar(unparsed-text($input))//text()
return
if (starts-with(normalize-space($token), "#")) then
replace($token, "((^|
)[\s])*#", "//")
else
switch ($token)
case ":" return "::="
case "[" return "("
case "]" return ")?"
default return $token
然后用Saxon到运行吧:
java net.sf.saxon.Query transform.xquery input=python.grammar > python.ebnf
结果就是您要找的。
当然你也可以使用你喜欢的文本编辑器仔细地做全局替换来达到同样的效果。做对了会更有趣。
我目前正在尝试将 Python 的形式语法 (https://docs.python.org/3/reference/grammar.html) 翻译成铁路图。 我们正在使用的网站 http://www.bottlecaps.de/rr/ui 对其中的大部分内容都非常有帮助,我们手动更改了很多东西以使用正确的符号来创建轨道图,但仍然有 50 多条线是不正确的并且非常困难供我们修复,因为我们对此是全新的。有没有比手动更改更简单的方法?
请注意该网站使用 EBNF
感谢您的宝贵时间,
编写一个解析语法的解析器,然后从解析树转换为所需的符号。
转换本身相当简单:
- 用'//'替换'#'评论介绍者
- 将“:”标记替换为“::=”
- 将“[”标记替换为“(”
- 将“]”标记替换为“)?”
W3C notation中一个合适的元语法是
Grammar ::= Rule+ EOF
Rule ::= Nonterminal ':' Alternatives
Alternatives
::= Alternative ( '|' Alternative )*
Alternative
::= ( Symbol ( '*' | '+' )? )*
Symbol ::= Nonterminal
| Terminal
| '(' Alternatives ')'
| '[' Alternatives ']'
<?TOKENS?>
Nonterminal
::= [a-z] [a-z_]*
Terminal ::= [A-Z] [A-Z_]*
| "'" [^']+ "'"
EOF ::= $
IgnorableWhitespace
::= [ #x9#xA#xD]+
| '#' [^#xA]* [#xA]
/* ws: definition */
把它放在grammar.ebnf
,然后使用REx to create a parser for it, coded e.g. in XQuery,使用这个命令行:
-xquery -tree
这为您提供了 XQuery 模块 grammar.xquery
。接下来,将 python 语法放在 python.grammar
中,并将此 XQuery 程序放在 transform.xquery
中:
import module namespace p="grammar" at "grammar.xquery";
declare option saxon:output "method=text";
declare variable $input as xs:string external;
for $token in p:parse-Grammar(unparsed-text($input))//text()
return
if (starts-with(normalize-space($token), "#")) then
replace($token, "((^|
)[\s])*#", "//")
else
switch ($token)
case ":" return "::="
case "[" return "("
case "]" return ")?"
default return $token
然后用Saxon到运行吧:
java net.sf.saxon.Query transform.xquery input=python.grammar > python.ebnf
结果就是您要找的。
当然你也可以使用你喜欢的文本编辑器仔细地做全局替换来达到同样的效果。做对了会更有趣。