Я пишу грамматику BNF для очень простого языка программирования и использую Flex и Bison для компиляции.
У меня есть только 3 типа переменных и констант: real, integer, string.
Мой файл .l содержит определение токена для "ID" следующим образом:
DIGIT [0-9]
LETTER [a-zA-Z]
ID {LETTER}({LETTER}|{DIGIT})*
В моем файле .y есть такое определение идентификатора:
identifier:
ID;
Теперь я хочу использовать определение identifier для создания имен переменных и констант. Но я также хочу ограничить назначение данными одного и того же типа (например, я не хочу, чтобы строка присваивалась целочисленной переменной). Поэтому я создал несколько правил для разделения каждого типа переменных и констант:
id_variable_string:
identifier;
id_variable_integer:
identifier;
id_variable_real:
identifier;
Я сделал то же самое для констант. Теперь в моем языке есть раздел для объявления/определения констант, а затем раздел для объявления переменных. То есть константы объявляются одновременно с их присвоением (что-то вроде «myConstant = 123»), но сначала необходимо объявить переменные, а затем присвоить значение в разделе, специально предназначенном для операторов.
Например, если мне нужно целое число и строковая переменная, я должен сначала объявить их:
STRING myStrVariable;
ЦЕЛОЕ ЧИСЛО myIntVariable;
И затем, в зоне, отведенной для операторов, я могу выбрать выполнение задания (оператор может быть заданием, решением, выбором, выходом и т. д.):
assignment:
id_variable_string ASSIGN_OPERATOR literal_string
| id_variable_string ASSIGN_OPERATOR id_const_string
| id_variable_string ASSIGN_OPERATOR id_variable_string
| id_variable_string ASSIGN_OPERATOR concatenacion
| id_variable_integer ASSIGN_OPERATOR id_const_integer
| id_variable_integer ASSIGN_OPERATOR id_variable_integer
| id_variable_integer ASSIGN_OPERATOR expression
| id_variable_integer ASSIGN_OPERATOR literal_integer
| id_variable_real ASSIGN_OPERATOR id_variable_real
| id_variable_real ASSIGN_OPERATOR id_const_real
| id_variable_real ASSIGN_OPERATOR expression
| id_variable_real ASSIGN_OPERATOR literal_real
;
Я намереваюсь здесь явно сказать, что строковой переменной может быть присвоен только строковый литерал, конкатенация строк (используя +), строковая константа или другая строковая переменная. То же самое для целочисленных переменных, а затем и для реальных переменных, только то, что им не может быть присвоена конкатенация, а вместо этого выражение (математические операции).
Конкатенация определяется следующим образом:
concatenation:
id_variable_string ADD_OPERATOR id_variable_string
| id_variable_string ADD_OPERADOR literal_string
| literal_string ADD_OPERADOR id_variable_string
| literal_string ADD_OPERADOR literal_string
| id_const_string ADD_OPERADOR id_const_string
| id_const_string ADD_OPERADOR id_variable_string
| id_const_string ADD_OPERADOR literal_string
| literal_string ADD_OPERADOR id_const_string
| id_variable_string ADD_OPERADOR id_const_string
;
И выражение определяется как:
expression:
expression ADD_OPERATOR term
| expression SUBST_OPERADOR term
| term
;
term:
term MULTIP_OPERATOR factor
| term DIVISION_OPERATOR factor
| factor
;
factor:
id_variable_integer
| id_variable_real
| id_const_integer
| id_const_real
| literal_integer
| literal_real
| PARENTHESIS_OPEN expression PARENTHESIS_CLOSE
;
Вот что говорит Бизон:
55 назначение: id_variable_integer ASSIGN_OPERATOR id_const_integer
56 | id_variable_integer ASSIGN_OPERATOR id_variable_integer
58 | id_variable_integer ASSIGN_OPERATOR literal_integer
59 | id_variable_real ASSIGN_OPERATOR id_variable_real
60 | id_variable_real ASSIGN_OPERATOR id_const_real
62 | id_variable_real ASSIGN_OPERATOR literal_real
Состояние 50 конфликтов: 1 сдвиг/уменьшение
Состояние 76 конфликтов: 14 сдвиг/уменьшение
Состояние 130 конфликтов: 2 сдвиг/уменьшение
Состояние 131 конфликт: 1 сдвиг/уменьшение
Состояние 133 конфликта : 1 сдвиг/уменьшение
состояние 134 конфликта: 1 сдвиг/уменьшение
состояние 135 конфликтов: 1 сдвиг/уменьшение
состояние 137 конфликтов: 1 сдвиг/уменьшение
состояние 138 конфликтов: 1 сдвиг/уменьшение
Я предполагаю, что что-то в моей грамматике не так, но я не уверен, что именно.