Трансляционная форма Бэкуса – Наура - Translational Backus–Naur form
Трансляционная форма Бэкуса – Наура ( TBNF или Translational BNF ) относится к форме Бэкуса – Наура , которая представляет собой формальную грамматическую нотацию, используемую для определения синтаксиса компьютерных языков, таких как Algol , Ada , C ++ , COBOL , Fortran , Java , Perl , Python. , и многие другие. TBNF выходит за рамки BNF и расширенной грамматической нотации BNF (EBNF), потому что он не только определяет синтаксис языка, но также определяет структуру абстрактного синтаксического дерева (AST), которое должно быть создано в памяти, и выходной промежуточный код, который должен быть сгенерирован. Таким образом, TBNF определяет полный процесс трансляции от исходного исходного кода до промежуточного кода. Указание выходного промежуточного кода не является обязательным, и в этом случае вы все равно получите автоматическое создание AST и сможете определять его структуру в грамматике.
Обзор
Концепция TBNF была впервые опубликована в апреле 2006 года в документе SIGPLAN Notices, специальной группы ACM .
Вот пример грамматики, указанной в TBNF:
/* TBNF Grammar for a simple language.
Five node arguments are used in this grammar to avoid having to create node actions.
*/
/* Input Tokens. */
<error> => error() ;
<identifier> => lookup(); // Lookup & store in symbol table.
<integer> => lookup(); // Lookup & store in symbol table.
<eof> ;
/* Operator precedence. */
{ '==' '!=' } << // Lowest priority.
{ '+' '-' } <<
{ '*' '/' } << // Highest priority.
/* Productions. */
Goal -> Program... <eof> *> goal_ (0,,"\t\tSTART\n" ,,"\t\tEOF\n\n")
Program -> 'program' <identifier> '{' Stmt... '}' *> program_ (2,,"\t\tPROGRAM %s\n",,"\t\tEND PROGRAM %s\n")
Stmt -> Assignment
-> IfThen
-> IfElse
-> IfThenElse
Assignment ~> Target '=' Exp ';' *> assign_ (0,, ,,"\t\tSTORE\n")
IfThen -> 'if' RelExp Then 'endif' *> if_ (0,,"if&0:\n",,"endif&0:\n" )
IfElse -> 'if' RelExp Else 'endif' *> if_ (0,,"if&0:\n",,"endif&0:\n" )
IfThenElse -> 'if' RelExp Then2 Else2 'endif' *> if_ (0,,"if&0:\n",,"endif&0:\n" )
Target -> <identifier> *> ident_ (1,,,,"\t\tLADR %s\n")
RelExp -> Exp '==' Exp *> eq_ (0,,,,"\t\tEQ\n" )
-> Exp '!=' Exp *> ne_ (0,,,,"\t\tNE\n" )
Exp -> Primary
-> Exp '+' Exp *> add_ (0,,,,"\t\tADD\n")
-> Exp '-' Exp *> sub_ (0,,,,"\t\tSUB\n")
-> Exp '*' Exp *> mul_ (0,,,,"\t\tMUL\n")
-> Exp '/' Exp *> div_ (0,,,,"\t\tDIV\n")
Primary -> <integer> *> intr_ (1,,,,"\t\tLOAD %s\n")
-> <identifier> *> ident_ (1,,,,"\t\tLOAD %s\n")
-> '(' Exp ')'
Then -> 'then' Stmt... *> then_ (0,,"\t\tBR NZ endif&1\nthen&1:\n",,)
Else -> 'else' Stmt... *> else_ (0,,"\t\tBR Z endif&1\nelse&1:\n" ,,)
Then2 -> 'then' Stmt... *> then2_ (0,,"\t\tBR NZ else&1\nthen&1:\n" ,,)
Else2 -> 'else' Stmt... *> else2_ (0,,"\t\tBR endif&1\nelse&1:\n" ,,)
/* End of Grammar. */
Учитывая этот ввод:
program test
{
if a == 0
then
if x == 0
then b = 10;
else b = 20;
endif
else
if x == 1
then b = 30;
else b = 40;
endif
endif
}
Запуск переводчика, созданного на основе приведенной выше грамматики, даст следующий результат:
START
PROGRAM test
if1:
LOAD a
LOAD 0
EQ
BR NZ else1
then1:
if2:
LOAD x
LOAD 0
EQ
BR NZ else2
then2:
LOAD 10
LADR b
STORE
BR endif2
else2:
LOAD 20
LADR b
STORE
endif2:
BR endif1
else1:
if3:
LOAD x
LOAD 1
EQ
BR NZ else3
then3:
LOAD 30
LADR b
STORE
BR endif3
else3:
LOAD 40
LADR b
STORE
endif3:
endif1:
END PROGRAM test
EOF