2012-04-15 2 views
2

Мне интересно, сохраняются ли на всех языках программирования ключи ключей? Говорит If, While зарезервированы ключевые слова. Мы не должны использовать его в качестве обычной переменной или имени функции, если у меня есть If = 3 является незаконным. Таким образом, компилятор будет генерировать ошибку во время фазы sanner. Что, если язык позволяет программисту использовать зарезервированные ключевые слова, скажите If как имя переменной или имя функции. Как компилятор может справиться с этим? Выполняется ли это в сканере или синтаксическом анализаторе? Что должен делать семантический анализ?Зарезервированные ключевые слова на языке программирования

обновление: Я понимаю, что это не очень хорошая практика, но реальная причина в большинстве случаев/язык программирования не поддерживает это потому, что сканер или анализатор не может сделать acurately сканирование языка или разбора языка или то, что это на самом деле за сценой? Благодарю.

+0

Такие, erm, способности, будут не только «путать», но и люди, которые будут читать код на этом языке. Тогда зачем это разрешать? – kirilloid

ответ

4

Вы определенно могли бы сделать такую ​​вещь, но, очевидно, это разрушило бы интуитивность исходного кода. Представьте себе следующее:

if if == 1 

Что касается фактического его осуществления, лексера не нужно было менять вообще. Если лексер соответствует «if» в источнике, он возвращает токен с типом IF. Предположим, мы имеем следующее оператор присваивания, где if является имя переменной, и это получение присваивается значение 1.

if <- 1; 

маркер потока лексером к подаваться в парсера:

IF, LARROW, INTLITERAL, SEMICOLON 

Я мог бы имеют следующие постановки, чтобы описать оператор присваивания (\ ш целочисленных rvals):

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :} 
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :} 
id::= ID:i {: RESULT = i.strVal; :} 

LARROW, ID, IF, INTLITERAL и SEMICOLON являются терминалами, которые являются токенами, возвращаемыми лексером, и assignStmt, id и intExpr являются не-терминалами. ID представляет собой идентификатор (например, имя класса/переменной/метода).

После отказа от производства для оператора if мы в конечном итоге введем первое производство для оператора присваивания. Мы расширяем нон-терминал id, единственным производством которого является ID, но токен, который я хочу сопоставить, - IF, поэтому производство assignStmt полностью не удается.

Для моего языка, чтобы переменный будет называться «если» все, что нужно сделать, это:

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :} 
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :} 
id::= ID:i {: RESULT = i.strVal; :} 
    |IF {: RESULT = "if"; :} 

Обратите внимание, что | определяет альтернативное производство для нетерминала. Теперь у нас есть второе производство для non-terminal id, которое соответствует текущему токену и в конечном итоге приводит к сопоставлению оператора присваивания.

AssignmentStatement является узел AST определяется следующим образом:

class AssignmentStatement { 
    String varName; 
    int intVal; 
    AssignmentStatement(String s, int i){varName = s; intVal = i; } 
} 

После того, как анализатор решает источник синтаксический правильно, ничего не должно быть затронуто. Имена ваших переменных не должны влиять на последние этапы компиляции, то есть, если вы не создаете условий, которые позволили бы это произойти.

+0

Благодарим вас за подробное объяснение, это именно то, что я ищу. –

0

Ну, я не могу придумать какие-либо скомпилированные языки без зарезервированных ключевых слов; это намного более убедительно, и редко есть причины использовать эти зарезервированные ключевые слова («if» не является хорошим именем переменной).

В PHP переменные используются начиная со знака доллара, поэтому я предполагаю, что язык может реализовать его таким образом (используя небуквенный код для префикса переменной, чтобы вы могли иметь $ if). Я полагаю, что это может быть сделано для работы, хотя опять же мало пользы для этого.

1

Почему бы вам не сделать это, даже если бы вы могли?

Все, что он может сделать, это сделать для недостижимого кода.

if (a==b) - это выражение if или вызов функции if, переводящий логический аргумент?

Я бы сказал, что если бы какой-либо язык позволил вам это сделать, это, вероятно, было бы странным академическим делом с 3 пользователями.

[надевая асбестовую Underware в рамках подготовки к беспощадному пламенному от 3-х пользователей ;-)]

-1

Я не думаю, что такой язык существует. Все информационные языки основаны на грамматике, то есть наборе правил, указывающих, как должен строиться код. Таким образом, вы можете доказать, что код структурно важен. Если вы позволили бы переименовывать имена по своему усмотрению, вам необходимо будет изменить грамматику «на лету», чтобы убедиться, что проверка кода остается верной.

На более практическом уровне, зачем беспокоиться о таком? Что не так с зарезервированными ключевыми словами? Они действительно полезны, по крайней мере, каждый говорит на одном языке одинаково. Вы бы даже не подумали о такой вещи с реальным мировым языком ... Представьте, если вы начали переключать слова, говорящие вокруг! Никто больше ничего не понял бы!

+0

Посмотрите на PL/1 ... –

1

Языки программирования обычно имеют зарезервированные слова, потому что людям нравится ставить лексические сканеры перед парсером. Лексический сканер превратит исходный код в ряд токенов, поэтому вы можете вставить токен «>>» и сказать, что все такие токены - это операторы сдвига, а затем вы не можете использовать символы ни для чего другого, кроме как часть других токенов (например, строка с кавычками), которая является или используется для популярной проблемы с C++. Другие слова типа «если» одинаковы, что превращается в какой-то токен «если», и всякий раз, когда парсер видит маркер «если», он будет рассматривать его как первую часть некоторой условной конструкции. Другим примером может служить JavaScript, где вы можете написать

JSON.stringify ({бар: 2})

, но вы не можете писать

JSON.stringify ({Var: 2})

Поскольку "вар" является "вар" маркер, но "бар" является просто идентификатор, как любой другой.

+0

, как описано в ответе blackcompe, если разрешить 'id-> IF', тогда мы можем рассматривать его как просто идентификатор. –

+0

Это откладывает ту же проблему из lexer в синтаксический анализатор, для чего нужен другой слой. Также имейте в виду, что вам не просто нужно принимать действительный код. Вы также должны иметь возможность выводить правильные ошибки в правильном месте, если программа неверна. Неоднозначный синтаксис делает это намного сложнее. –

0

Одним из способов разрешения произвольных ключевых слов является использование неалфавитных символов для всех неидентифицирующих синтаксических переменных. APL использует этот подход, и, возможно, Smalltalk (в Smalltalk-80) содержит шесть зарезервированных слов, но все они имеют переменную-подобную семантику, и обычно это ключевые слова, такие как условия, являются синтаксически регулярными сообщениями).

Смежные вопросы