I am currently trying to translate Python's formal grammar (https://docs.python.org/3/reference/grammar.html) into Rail Diagrams. The website we are using http://www.bottlecaps.de/rr/ui is very helpful for most of it and we have changed many things by hand to fir the proper notation for it to create the rail diagram but there is still 50+ lines that are incorrect and very hard for us to fix as we are brand new to this. Is there an easier way to do this than changing it all by hand?
Note the website uses EBNF
Thanks for your time,
答案 0 :(得分:0)
编写解析语法的解析器,然后从解析树转换为必需的表示法。
转型本身很简单:
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为其创建解析器,例如在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])*#", "$1//")
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
结果就是你要找的东西。
当然,您也可以使用自己喜欢的文本编辑器仔细地进行全局替换。这样做会非常有趣。