2016-02-03 4 views
0

В настоящее время я пытаюсь перевести формальную грамматику Python (https://docs.python.org/3/reference/grammar.html) в диаграммы рельсов. Веб-сайт, который мы используем http://www.bottlecaps.de/rr/ui, очень полезен для большинства из них, и мы многое изменили вручную, чтобы создать правильную нотацию для создания диаграммы рельсов, но есть еще 50 строк, которые являются неправильными и очень трудными для нас. исправить, поскольку мы новичок в этом. Есть ли более простой способ сделать это, чем изменить все это вручную?Перевод официального языка Python в диаграммы рельсов

Обратите внимание на веб-сайт использует EBNF

Спасибо за ваше время,

ответ

0

Написать парсер, который анализирует грамматику, затем трансформируют из синтаксического анализа дерева до требуемой записи.

Само преобразование достаточно прост:

  • заменить '#' комментарий поручителей по '//'
  • заменить ':' лексемы ':: ='
  • заменить '[' токенов by '('
  • заменить ']' токены на ')?'

Подходящая мета-грамматика, в 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.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, "((^|&#xA;)[\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 

В результате то, что вы искали.

Конечно, вы также можете использовать свой любимый текстовый редактор, чтобы сделать глобальное замещение тем же. Это просто гораздо интереснее, чтобы сделать это правильно.

Смежные вопросы