- •Транслирующая грамматика
- •C) Функии переходов преобразователя и пример его работы
- •Пример работы преобразователя
- •Лексический анализатор
- •A) Грамматика лексических единиц и структура лексем
- •B) Матрица переходов лексического анализатора
- •D) Структура программы лексического анализатора и пример его работы
- •C) Описание символов действия
- •D) Атрибутная грамматика в окончательном виде
- •E) Вывод в атрибутной грамматике
- •B) Построение инструкций а-преобразвателя
- •C) Фрагмент работы а-преобразователя
- •Заключение
Задание, примеры поясняющие задачу.
Требуется описать заданное множество конструкций языка программирования с помощью формальной грамматики, построить преобразователь, описать перевод заданных конструкций в постфиксную польскую запись, построить преобразователь .
Составить LL(1) грамматику, задающую следующее подмножество языка С:
-описания переменных типа float и int
-арифметические операции (+,*)
-циклы типа for( )
Примеры принадлежащих этому языку цепочек:
-
main()
{
int a:
a= 2+3*4;
}
2) main()
{
int x;
float y;
}
3) main()
{
int a,b,c;
f loat x,y;
a=5;
x = 3.12;
for(b=3;b<17;b+2)
{
for(c=35;c<100;c+10)
{
y=x*5+a;
}
}
}
Преобразуется к следующему виду:
-
int a
a 2 3 4 * + =
-
int x float y
-
int a int b int c
float x float y
a 5 =
x 3.12 =
b 3 = BEG: b 17 < END JMP_F b 2 + c 35 = BEG: c 100 < END JMP_F c 10 + y x 5 a + * = BEG GOTO END: BEG GOTO END:
Построение символьного преобразователя
a) Входная грамматика
//Оновной блок: программа состоит из
// -блока описаний переменных
// -блока операторов, использующих эти переменные
--описание начала пpогpаммы
<PROGRAM>::="main()"<MAINBLOCK>
--пpавила для объевления пеpеменных типа 'int'
<LIST_IDENT_I>::=<IDENTIFICATOR><C_L_I_I>
<C_L_I_I>::=$|','<LIST_IDENT_I>
--пpавила для объевления пеpеменных типа 'float'
<LIST_IDENT_F>::=<IDENTIFICATOR><C_L_I_F>
<C_L_I_F>::=$|','<LIST_IDENT_F>
--пpавила для описания константов,используемые в выpажении
<CHAR>::=a|b|c
<DIGIT>::=0|1|2
<IDENTIFICATOR>::=<CHAR><CONT>
<CONT>::=<DIGIT><CONT>|<CHAR><CONT>
<CONT>::=$
--описание числа
<CONSTANT>::=<NUMBER><CONT_CONSTANT>
<CONT_CONSTANT>::=$|.<NUMBER>
<NUMBER>::=<DIGIT><CONT_NUMBER>
<CONT_NUMBER>::=$|<NUMBER>
--описание содеpжания пpогpаммы
<MAINBLOCK>::='{'<BODY>'}'
<BODY>::=<DEFINE_CONSTANT><CONT_BODY>
<CONT_BODY1>::=<EQUATION>|<FOR>
<CONT_BODY>::=<CONT_BODY1><CONT_CONT_BODY>
<CONT_CONT_BODY>::=$|<BODY>
--пpавила для объевления пеpеменных типа 'int' или 'float'
<DEFINE_CONSTANT>::=$
<DEFINE_CONSTANT>::="float"<LIST_IDENT_f>;
<DEFINE_CONSTANT>::="int"<LIST_IDENT_i>;
--пpавила для описания опеpатоpов цикла и пpисвоения с аpиф. выpажениями (+,*)
--и логическими выpажениями.
<FOR>::=<HEAD>'{'<CONT_BODY>'}';
<HEAD>::='for('<CONDITION1><CONT_HEAD>
<CONT_HEAD>::=;<CONDITION2><CCONT_HEAD>
<CCONT_HEAD>::=;<CONDITION3>')'
<CONDITION1>::=<IDENTIFICATOR>'='<CONSTANT>
<CONDITION2>::=<IDENTIFICATOR><CONT_COND2>
<CONT_COND2>::='>'<CONSTANT>;
<CONT_COND2>::='<'<CONSTANT>;
<CONDITION3>::=<IDENTIFICATOR><CONT_COND3>
<CONT_COND3>::='+'<R_EQUATION>
<CONT_COND3>::='*'<R_EQUATION>
--описание выpажения
<EQUATION>::=<identificator>'='<R_EQUATION>;
--описание правой части выpажения
<R_EQUATION>::=<IDENTIFICATOR><CONT_R_EQUATION>
<R_EQUATION>::=<CONSTANT><CONT_R_EQUATION>
<CONT_R_EQUATION>::=$
<CONT_R_EQUATION>::='+'<R_EQUATION>
<CONT_R_EQUATION>::='*'<R_EQUATION>
b) СУ схема и транслирующая грамматика
СУ схема
СУ схема определяется:
а) терминальными входным и выходным словарями
б) нетерминальным словарем
в) начальным символом
г) множеством правил, вида А ,
где (Vтвх VA )* , а (Vтвых VA )*
--описание начала пpогpаммы
<PROGRAM>::="main()"<MAINBLOCK>,<MAINBLOCK>
--пpавила для объевления пеpеменных типа 'int'
<LIST_IDENT_I>::=<IDENTIFICATOR><C_L_I_I>,<IDENTIFICATOR><C_L_I_I>
<C_L_I_i>::=$,$|','<LIST_IDENT_I>,{" int"}<LIST_IDENT_I>
--пpавила для объевления пеpеменных типа 'float'
<LIST_IDENT_F>::=<IDENTIFICATOR><C_L_I_F>,<IDENTIFICATOR><C_L_I_F>
<C_L_I_F>::=$,$|','<LIST_IDENT_F>,{" float"}<LIST_IDENT_F>
--пpавила для описания константов,используемые в выpажении
<CHAR>::=a,{a}|b,{b}|c,{c}
<DIGIT>::=0,{0}|1,{1}|2,{2}
<IDENTIFICATOR>::=<CHAR><CONT>,<CHAR><CONT>
<CONT>::=<DIGIT><CONT>,<DIGIT><CONT>|<CHAR><CONT>,<CHAR><CONT>
<CONT>::=$,$
--описание числа
<CONSTANT>::=<NUMBER><CONT_CONSTANT>,<NUMBER><CONT_CONSTANT>
<CONT_CONSTANT>::=$,$|.<NUMBER>,.<NUMBER>
<NUMBER>::=<DIGIT><CONT_NUMBER>,<DIGIT><CONT_NUMBER>
<CONT_NUMBER>::=$,$|<NUMBER>,<NUMBER>
--описание содеpжания пpогpаммы
<MAINBLOCK>::='{'<BODY>'}',<BODY>
<BODY>::=<DEFINE_CONSTANT><CONT_BODY>,<DEFINE_CONSTANT><CONT_BODY>
<CONT_BODY1>::=<EQUATION>,<EQUATION>|<FOR>,<FOR>
<CONT_BODY>::=<CONT_BODY1><CONT_CONT_BODY>,<CONT_BODY1><CONT_CONT_BODY>
<CONT_CONT_BODY>::=$,$|<BODY>,<BODY>
--пpавила для объевления пеpеменных типа 'int' или 'float'
<DEFINE_CONSTANT>::=$,$
<DEFINE_CONSTANT>::="float"<LIST_IDENT_f>;,{"float"}<LIST_IDENT_f>
<DEFINE_CONSTANT>::="int"<LIST_IDENT_i>;,{"int"}<LIST_IDENT_i>
--пpавила для описания опеpатоpов цикла и пpисваивания с аpиф. выpажениями (+,*)
--и логическими выpажениями.
<FOR>::=<HEAD>'{'<CONT_BODY>'}';,<HEAD><CONT_BODY>{"begin goto end:"};
<HEAD>::='for('<CONDITION1><CONT_HEAD>,<CONDITION1><CONT_HEAD>
<CONT_HEAD>::=;<CONDITION2><CCONT_HEAD>,{"begin:"}<CONDITION2>{"end jmp_false"}<CCONT_HEAD>
<CCONT_HEAD>::=;<CONDITION3>')',<CONDITION3>
<CONDITION1>::=<IDENTIFICATOR>'='<CONSTANT>,<IDENTIFICATOR>'='<CONSTANT>{'='}
<CONDITION2>::=<IDENTIFCATOR><CONT_COND2>,<IDENTIFICATOR><CONT_COND2>
<CONT_COND2>::='>'<CONSTANT>;,<CONSTANT>{'>'}
<CONT_COND2>::='<'<CONSTANT>;,<CONSTANT>{'<'}
<CONDITION3>::=<IDENTIFCATOR><CONT_COND3>,<IDENTIFICATOR><CONT_COND3>
<CONT_COND3>::='+'<R_EQUATION>,<R_EQUATION>{'+'}
<CONT_COND3>::='*'<R_EQUATION>,<R_EQUATION>{'*'}
--описание выpажения
<EQUATION>::=<identificator>'='<R_EQUATION>;,<identificator><R_EQUATION>{'='}
--описание правой части выpажения
<R_EQUATION>::=<IDENTIFICATOR><CONT_R_EQUATION>,<IDENTIFICATOR><CONT_R_EQUATION>
<R_EQUATION>::=<CONSTANT><CONT_R_EQUATON>,<CONSTANT><CONT_R_EQUATION>
<CONT_R_EQUATION>::=$,$
<CONT_R_EQUATION>::='+'<R_EQUATION>,<R_EQUATION>{'+'}
<CONT_R_EQUATION>::='*'<R_EQUATION>,<R_EQUATION>{'*'}
Транслирующая грамматика
ТГ - контекстно-свободная грамматика, множество терминальных символов которой разделено на подмножество входных и выходных символов.
--описание начала пpогpаммы
<PROGRAM>::="main()"<MAINBLOCK>
--пpавила для объевления пеpеменных типа 'int'
<LIST_IDENT_I>::=<IDENTIFICATOR><C_L_I_I>
<C_L_I_i>::=$|','{" int"}<LIST_IDENT_I>
--пpавила для объевления пеpеменных типа 'float'
<LIST_IDENT_F>::=<IDENTIFICATOR><C_L_I_F>
<C_L_I_F>::=$|','{" float"}<LIST_IDENT_F>
--пpавила для описания константов,используемые в выpажении
<CHAR>::=a{a}|b{b}|c{c}
<DIGIT>::=0{0}|1{1}|2{2}
<IDENTIFICATOR>::=<CHAR><CONT>
<CONT>::=<DIGIT><CONT>|<CHAR><CONT>
<CONT>::=$
--описание числа
<CONSTANT>::=<NUMBER><CONT_CONSTANT>
<CONT_CONSTANT>::=$|.<NUMBER>
<NUMBER>::=<DIGIT><CONT_NUMBER>
<CONT_NUMBER>::=$|<NUMBER>
--описание содеpжания пpогpаммы
<MAINBLOCK>::='{'<BODY>'}'
<BODY>::=<DEFINE_CONSTANT><CONT_BODY>
<CONT_BODY1>::=<EQUATION>|<FOR>
<CONT_BODY>::=<CONT_BODY1><CONT_CONT_BODY>
<CONT_CONT_BODY>::=$|<BODY>
--пpавила для объевления пеpеменных типа 'int' или 'float'
<DEFINE_CONSTANT>::=$
<DEFINE_CONSTANT>::="float"{"float"}<LIST_IDENT_f>;
<DEFINE_CONSTANT>::="int"{"int"}<LIST_IDENT_i>;
--пpавила для описания опеpатоpов цикла и пpисваивания с аpиф. выpажениями (+,*)
--и логическими выpажениями.
<FOR>::=<HEAD>'{'<CONT_BODY>'}'{"begin goto end:"};
<HEAD>::='for('<CONDITION1><CONT_HEAD>
<CONT_HEAD>::=;{"begin:"}<CONDITION2>{"end jmp_false"}<CCONT_HEAD>
<CCONT_HEAD>::=;<CONDITION3>')'
<CONDITION1>::=<IDENTIFICATOR>'='<CONSTANT>{'='}
<CONDITION2>::=<IDENTIFICATOR><CONT_COND2>
<CONT_COND2>::='>'<CONSTANT>;{'>'}
<CONT_COND2>::='<'<CONSTANT>;{'<'}
<CONDITION3>::=<IDENTIFICATOR><CONT_COND3>
<CONT_COND3>::='+'<R_EQUATION>{'+'}
<CONT_COND3>::='*'<R_EQUATION>{'*'}
--описание выpажения
<EQUATION>::=<identificator>'='<R_EQUATION>{'='};
--описание правой части выpажения
<R_EQUATION>::=<IDENTIFICATOR><CONT_R_EQUATION>
<R_EQUATION>::=<CONSTANT><CONT_R_EQUATION>
<CONT_R_EQUATION>::=$
<CONT_R_EQUATION>::='+'<R_EQUATION>{'+'}
<CONT_R_EQUATION>::='*'<R_EQUATION>{'*'}
C) Функии переходов преобразователя и пример его работы
-- оптимизация для правил, правая часть которых начинается с терминала
-- сдвиг, вытолкнуть, за менить
( S, "main()" , <program> )= ( S, <mainblock>,$ )
( S, "," , <c_l_i_i> ) = ( S, <list_ident_i>,#" int"# )
( S, "," , <c_l_i_f> ) = ( S, <list_ident_f>,#" float"# )
(S, a, <char> ) = ( S, $,#a# )
( S, b, <char> ) = ( S, $,#b# )
( S, c, <char> ) = ( S, $ ,#c#)
( S, 0, <digit> ) = ( S, $,#0# )
( S, 1, <digit> ) = ( S, $,#1# )
( S, 2, <digit> ) = ( S, $ ,#2#)
( S, ., <cont_constant> ) = ( S, <number>,#.# )
( S, {, <mainblock> ) = ( S, }<body>,$ )
(s,"<",<cont_cnd2>)=(s,#"<"#<constant>,$)
(s,">",<cont_cnd2>)=(s,#">"#<constant>,$)
(s,"*",<cont_cond3>)=(s,#"*"#<r_equation>,$)
(s,"+",<cont_cond3>)=(s,#"+"#<r_equation>,$)
( S, "for(" , <head> ) = ( S,<cont_head><condition1>,#" "# )
(s ,";",<cont_head>)=(s,<rcont_head>#"end jmp_f"#<cnd2>#"beg:"#,$)
(s,";",<rcont_head>)=(s,")"<condition3>,$)
(s , "+",<cont_r_equation>)=(s,#"+"#<r_equation>,$)
(s , "*",<cont_r_equation>)=(s,#"*"#<r_equation>,$)
(s,"float",<define_constant>)=(s,;<list_ident_f>#"float"#,$)
(s,"int",<define_constant>)=(s,;<list_ident_i>#"int"#,$)
-- правила общего вида
-- нет сдвига, заменить
*( S, a, <list_ident_i> ) = ( S, <c_l_i_i> <identificator>,$ )
*( S, b, <list_ident_i> ) = ( S, <c_l_i_i> <identificator>,$ )
*( S, c, <list_ident_i> ) = ( S, <c_l_i_i> <identificator>,$ )
*( S, a, <list_ident_f> ) = ( S, <c_l_i_f> <identificator>,$ )
*( S, b, <list_ident_f> ) = ( S, <c_l_i_f> <identificator>,$ )
*( S, c, <list_ident_f> ) = ( S, <c_l_i_f> <identificator>,$ )
*( S, a, <identificator> ) = ( S, <cont> <char>,$ )
*( S, b, <identificator> ) = ( S, <cont> <char>,$ )
*( S, c, <identificator> ) = ( S, <cont> <char>,$ )
*( S, 0, <cont> ) = ( S, <cont> <digit>,$ )
*( S, 1, <cont> ) = ( S, <cont> <digit>,$ )
*( S, 2, <cont> ) = ( S, <cont> <digit> ,$)
*( S, a, <cont> ) = ( S, <cont> <char>,$ )
*( S, b, <cont> ) = ( S, <cont> <char>,$ )
*( S, c, <cont> ) = ( S, <cont> <char>,$ )
*( S, 0, <constant> ) = ( S, <cont_constant> <number>,$ )
*( S, 1, <constant> ) = ( S, <cont_constant> <number> ,$)
*( S, 2, <constant> ) = ( S, <cont_constant> <number>,$ )
*( S, 0, <number> ) = ( S, <cont_number> <digit>,$ )
*( S, 1, <number> ) = ( S, <cont_number> <digit>,$ )
*( S, 2, <number> ) = ( S, <cont_number> <digit>,$ )
*( S, 0, <cont_number> ) = ( S, <number> ,$)
*( S, 1, <cont_number> ) = ( S, <number>,$ )
*( S, 2, <cont_number> ) = ( S, <number> ,$)
*( S, "int" , <body> ) = ( S, <cont_body> <define_constant>,$ )
*( S, "float" , <body> ) = ( S, <cont_body> <define_constant>,$ )
*( S, a, <body> ) = ( S, <cont_body> <define_constant>,$ )
*( S, b, <body> ) = ( S, <cont_body> <define_constant>,$ )
*( S, c, <body> ) = ( S, <cont_body> <define_constant>,$ )
*( S, "for(" , <body> ) = ( S, <cont_body> <define_constant>,$ )
*( S, a, <cont_body1> ) = ( S, <equation>,$ )
*( S, b, <cont_body1> ) = ( S, <equation>,$ )
*( S, c, <cont_body1> ) = ( S, <equation> ,$)
*( S, "for(" , <cont_body1> ) = ( S, <for>,$ )
*( S, a, <cont_body> ) = ( S, <cont_cont_body> <cont_body1>,$ )
*( S, b, <cont_body> ) = ( S, <cont_cont_body> <cont_body1>,$ )
*( S, c, <cont_body> ) = ( S, <cont_cont_body> <cont_body1>,$ )
*( S, "for(" , <cont_body> ) = ( S, <cont_cont_body> <cont_body1>,$ )
*( S, "int" , <cont_cont_body> ) = ( S, <body>,$ )
*( S, "float" , <cont_cont_body> ) = ( S, <body>,$ )
*( S, a, <cont_cont_body> ) = ( S, <body>,$ )
*( S, b, <cont_cont_body> ) = ( S, <body>,$ )
*( S, c, <cont_cont_body> ) = ( S, <body>,$ )
*( S, "for(" , <cont_cont_body> ) = ( S, <body>,$ )
*( S, "for(",<for>) = ( S,#"beg goto end:"# ;}<cont_body> {<head>,$ )
*( S, a, <condition1> ) = ( S,#"="# <constant>"="<identificator>,$ )
*( S, b, <condition1> ) = ( S,#"="# <constant>"="<identificator>,$ )
*( S, c, <condition1> ) = ( S,#"="# <constant>"="<identificator>,$ )
*( S, a, <cnd2> ) = ( S, <cont_cnd2> <identificator>,$ )
*( S, b, <cnd2> ) = ( S, <cont_cnd2><identificator>, $)
*( S, c, <cnd2> ) = ( S, <cont_cnd2><identificator>,$ )
*( S, a, <condition3> ) = ( S, <cont_cond3> <identificator>,$ )
*( S, b, <condition3> ) = ( S, <cont_cond3><identificator>,$ )
*( S, c, <condition3> ) = ( S, <cont_cond3><identificator>,$ )
*( S, a, <equation>) = ( S, ;#"="#<r_equation> "="<identificator>,$ )
*( S, b, <equation>) = ( S, ;#"="#<r_equation> "="<identificator>,$ )
*( S, c, <equation>) = ( S, ;#"="#<r_equation> "="<identificator>,$ )
*( S, a, <r_equation> ) = ( S, <cont_r_equation> <identificator>,$ )
*( S, b, <r_equation> ) = ( S, <cont_r_equation> <identificator> ,$)
*( S, c, <r_equation> ) = ( S, <cont_r_equation> <identificator> ,$)
*( S, 0, <r_equation> ) = ( S, <cont_r_equation> <constant> ,$)
*( S, 1, <r_equation> ) = ( S, <cont_r_equation> <constant>,$ )
*( S, 2, <r_equation> ) = ( S, <cont_r_equation> <constant>,$ )
-- Е-правила
-- нет сдвига, вытолкнуть
*( S, ;, <c_l_i_i> ) = ( S, $,$ )
*( S, ;, <c_l_i_f> ) = ( S, $,$ )
*( S, "," , <cont> ) = ( S, $,$ )
*( S, *, <cont> ) = ( S, $,#" "# )
*( S, +, <cont> ) = ( S, $,#" "# )
*( S, "<" , <cont> ) = ( S, $,#" "# )
*( S, ">" , <cont> ) = ( S, $,#" "# )
*( S, ;, <cont> ) = ( S, $,$ )
*( S, =, <cont> ) = ( S, $,#" "# )
*( S, ")" , <cont> ) = ( S, $,#" "# )
*( S, ;, <cont_constant> ) = ( S,$, $ )
*( S, +, <cont_constant> ) = ( S,$, $ )
*( S, *, <cont_constant> ) = ( S,$, $ )
*( S, ")" , <cont_constant> ) = ( S,$, $ )
*( S, ., <cont_number> ) = ( S,$, $ )
*( S, *, <cont_number> ) = ( S, $,#" "# )
*( S, +, <cont_number> ) = ( S, $,#" "# )
*( S, ;, <cont_number> ) = ( S, $,$ )
*( S, ")" , <cont_number> ) = ( S, $,#" "# )
*( S, }, <cont_cont_body> ) = ( S, $,$ )
*( S, a, <define_constant> ) = ( S, $,$ )
*( S, b, <define_constant> ) = ( S, $,$ )
*( S, c, <define_constant> ) = ( S, $,$ )
*( S, "for(" , <define_constant> ) = ( S, $,$ )
*( S, ;, <cont_r_equation> ) = ( S, $,$ )
*( S, ")" , <cont_r_equation> ) = ( S, $,$ )
-- выталкивание терминалов
-- сдвиг, вытолкнуть
( S, {, {) = ( S, $,$ )
( S, ;, ;) = ( S, $,$ )
( S, }, }) = ( S, $,$ )
( S, "," , "," ) = ( S, $,$ )
( S, "<" , "<" ) = ( S, $,$ )
( S, ">" , ">" ) = ( S, $,$ )
( S, ")" , ")" ) = ( S, $,$ )
( S, "for(" , "for(" ) = ( S, $,$)
( S, "int" , "int" ) = ( S, $,$ )
( S, "float" , "float" ) = ( S, $,$ )
( S, "main()" , "main()" ) = ( S, $,$ )
( S, *, *) = ( S, $,$ )
( S, +, +) = ( S, $,$ )
( S, =, =) = ( S, $,$ )
( S, a, a) = ( S, $,$ )
( S, b, b) = ( S, $,$ )
( S, c, c) = ( S, $,$ )
( S, 0, 0) = ( S, $,$ )
( S, 1, 1) = ( S, $,$ )
( S, 2, 2) = ( S, $,$ )
( S, ., .) = ( S, $,$ )
-- выталкивание выходных терминалов
-- сдвиг, вытолкнуть
*( S, $ , #","# ) = ( S, $,#" "# )
*( S, $ , #"<"# ) = ( S, $,#"<"# )
*( S, $ , #">"# ) = ( S, $,#">"# )
*( S, $ , #"int"# ) = ( S, $,#"int"# )
*( S, $ , #"float"# ) = ( S, $,#"float"# )
*( S, $, #"*"#) = ( S, $,#*# )
*( S, $, #"+"#) = ( S, $,#+# )
*( S, $, #"="#) = ( S, $,#"="# )
*(s,$,#"end jmp_f"#)=(s,$,#" end jmp_f"#)
*(s,$,#"beg goto end:"#)=(s,$,#"beg goto end:"#)
*(s,$,#"beg:"#)=(s,$,#"beg:"#)
-- переход в заключительное состояние
( S, -|, [] ) = ( S1, $,$ )