На языке без переменных (например, на простом калькуляторе) можно различать выражения guish разных типов во время анализа при условии, что невозможно автоматически привести (привести) введите другое.
Но реально будет неудобно многократно печатать матрицы каждый раз. Вам и вашим другим пользователям очень быстро потребуется какой-либо способ сохранить матричную константу в качестве именованного объекта. Если именованные объекты также могут быть скалярами, то вам нужно будет либо настаивать на том, чтобы имя объекта каким-либо образом представляло тип (например, матрица могла быть написана заглавной буквой или чем-то подобным), или, скорее всего, вы ' В итоге мы не узнаем, является ли имя скалярным выражением или матричным выражением. И в этот момент любая сложная грамматика, которую вы могли бы построить, чтобы попытаться различить guish двух типов выражений во время разбора, внезапно станет бессмысленной.
Так что мой совет - избавить себя от обострения , Первоначальный анализ должен просто создать AST некоторой формы, и затем вы можете пройтись по дереву, чтобы выполнить любой требуемый семантический c анализ, включая разрешение операторов polymorphi c и вставку автоматических c приведений, если таковые имеются.
Игнорируемое приложение
Хотя в вашей грамматике нет ничего плохого в q_matrix
, она кажется мне немного неловкой, поскольку на самом деле она не представляет структуру матрицы syntacti c. константы. Я написал бы немного по-другому (также используя значения semanti c для хранения промежуточных результатов вместо глобальной переменной):
q_matrix: '[' q_row_list ']' { $$ = $2; }
q_rows : q_row { $$ = qm_create();
qm_append_row($$, $1); }
| q_rows ';' q_row { /* $$ = $1; */
/* ensure $1.cols() == $3.cols */
qm_append_row($$, $3); }
q_row : q_term { $$ = qr_create();
qr_append_val($$, $1); }
| q_row ',' q_term { /* $$ = $1; */
qr_append_val($$, $3); }
Выше я закомментировал оба экземпляра $$ = $1;
, поскольку в случае парсеров, генерируемых бизонами C, эта копия уже была сделана непосредственно перед выполнением какого-либо действия. Если вы переходите на другой язык, например C ++, вам может потребоваться включить явную копию.
Код предполагает, что у вас есть как матричные, так и строковые (или векторные) объекты. (Конечно, векторный объект может быть матричным объектом с одной строкой, если вы не хотите go реализовать два разных типа.) В приведенном выше коде строка завершается перед добавлением в матрица; на этом этапе легко проверить, что добавляемая строка имеет то же количество столбцов, что и накопленная матрица. Я обозначил этот тест комментарием, а не пытался предложить, какое действие следует предпринять в случае неудачи теста.