Как парсеры обрабатывают параметры универсального типа? - PullRequest
3 голосов
/ 08 июня 2019

Я пишу рекурсивный приличный парсер для воображаемого языка программирования.Это язык в стиле C с общими операторами, такими как ==, <,>, <= и> =, и он также имеет универсальные функции (как в C #).

В таких языках, как C #, вызыватьуниверсальная функция, вы пишете:

someFunction<T>(x);

Мой вопрос заключается в том, как синтаксический анализатор отличает универсальные параметры от операторов сравнения (<и>).

С моей точки зрения, код вышеможет иметь любое из этих двух значений:

  • вызвать 'someFunction' с универсальным параметром 'T' и с регулярным параметром 'x'
  • оценить выражение '(someFunction x ', трактуя' someFunction ',' T 'и' x 'как регулярные переменные

Как парсер узнает, какая интерпретация предназначена?

1 Ответ

5 голосов
/ 10 июня 2019

Вы на 100% правы, что общий синтаксис вызова функции неоднозначен во многих языках, которые включают эту функцию.

Не все языки используют неоднозначный синтаксис.В Java нет никакой двусмысленности, потому что аргументы типа помещаются перед именем метода, и перед ним должно стоять .: SomeClass.<ArgType>genericMethod().Другие возможности включают использование другого символа для скобок типа, например [], ::<> или !.(Scala, Rust и D. соответственно. Scala использует круглые скобки для индексов массива.)

Но многие языки используют синтаксис C ++ / C #, который неоднозначен.Каждый язык имеет свое собственное правило устранения неоднозначности, и, насколько я знаю, нет единого мнения о том, как это сделать.В частности:

  • C ++ требует, чтобы компилятор выяснил, является ли имя функции / метода / класса (или может быть) шаблонным.(ADL делает это немного сложным, и в C ++ 18 правила были изменены, чтобы включить случай, когда имя не шаблонной функции / метода могло бы все еще интерпретироваться, как если бы оно было шаблонным.)

  • C # требует, чтобы компилятор нашел конец аргументов шаблона в угловых скобках, если это возможно, и затем изучил следующий входной токен;если следующий токен является открытой скобкой или одним из набора токенов, которые не могут синтаксически следовать за > (например, точкой с запятой), то аргументы шаблона обрабатываются как таковые;если нет совпадения > или за совпадением > следует что-то вроде 42, то это обрабатывается для сравнения.

Насколько я вижу,парсер рекурсивного спуска, использующий определение C #, должен иметь возможность вернуться назад.С другой стороны, определение C ++ требует, чтобы разрешение имен было вплетено в синтаксический анализ, что является другим уродством.

Насколько я понимаю, вы свободны придумать свое собственное другое решение,Я призываю вас полностью и четко документировать это, если вы ожидаете, что другие люди будут использовать ваш язык.(Я не мог найти такую ​​документацию для машинописного текста, например, которую я не использую.) Если бы я разрабатывал язык с использованием дженериков, я думаю, я бы выбрал однозначный синтаксис.Но это только я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...