Что может создать лексическую ошибку в C? - PullRequest
7 голосов
/ 04 апреля 2011

Помимо закрытия комментария /*..., что является лексической ошибкой в ​​C?

Ответы [ 6 ]

8 голосов
/ 04 апреля 2011

Вот некоторые из них:

 "abc<EOF>

, где EOF - конец файла.Фактически, EOF в середине многих лексем должен выдавать ошибки:

 0x<EOF>

Я предполагаю, что использование неправильных escape-выражений в строках недопустимо:

  "ab\qcd"

Вероятно, проблема с показателями с плавающей запятой

 1e+%

Возможно, у вас не должно быть содержимого в конце директивы препроцессора:

#if x   %
2 голосов
/ 04 апреля 2011

Не являются ли [@ $ `] и другие подобные символы (возможно, из unicode) лексическими ошибками в C, если они помещены где-либо за пределами строки или комментария? Они не составляют никакой действительной лексической последовательности этого языка. Они не могут передать лексер, потому что лексер не может распознать их как какой-либо действительный токен. Обычно лексеры основаны на FSM или регулярных выражениях, поэтому эти символы являются просто нераспознанным вводом.

Например, в следующем коде есть несколько лексических ошибок:

int main(void){
` int a = 3;
@ —
return 0;
}

Мы можем поддержать это, передав это gcc, что дает

../a.c: In function ‘main’:
../a.c:2: error: stray ‘`’ in program
../a.c:3: error: stray ‘@’ in program
../a.c:3: error: stray ‘\342’ in program  
../a.c:3: error: stray ‘\200’ in program
../a.c:3: error: stray ‘\224’ in program

GCC является умным и выполняет восстановление после ошибок, поэтому он проанализировал определение функции (он знает, что мы находимся в 'main'), но эти ошибки определенно выглядят как лексические ошибки, они не являются синтаксическими ошибками и это правильно. У лексера GCC нет никаких типов токенов, которые можно собрать из этих символов. Обратите внимание, что он даже обрабатывает трехбайтовый символ UTF-8 как три нераспознанных символа.

2 голосов
/ 04 апреля 2011

Практически все, что не соответствует ISO C 9899/1999, Приложение A.1 «Лексическая грамматика», является лексической ошибкой, если компилятор выполняет свой лексический анализ в соответствии с этой грамматикой. Вот несколько примеров:

"abc<EOF> // invalid string literal (from Ira Baxter's answer) (ISO C 9899/1999 6.4.4.5)

'a<EOF> // invalid char literal (6.4.4.4)

где EOF - конец файла.

double a = 1e*3; // misguided floating point literal (6.4.4.2)

int a = 0x0g; // invalid integer hex literal (6.4.4.1)

int a = 09; // invalid octal literal (6.4.4.1)

char a = 'aa'; // too long char literal (from Joel's answer, 6.4.4.4)

double a = 0x1p1q; // invalid hexadecimal floating point constant (6.4.4.2)
// instead of q, only a float suffix, that is 'f', 'l', 'F' or 'L' is allowed.

// invalid header name (6.4.7)
#include <<a.h>
#include ""a.h"
0 голосов
/ 06 апреля 2011

Лексические ошибки:

  1. Неоконченный комментарий
  2. Любая последовательность некомментированных и непробельных символов, которая не является допустимым токеном препроцессора
  3. Любой препроцессортокен, который не является допустимым токеном C;пример - 0xe-2, который выглядит как выражение, но на самом деле является синтаксической ошибкой согласно стандарту - случай с нечетным углом, вытекающий из правил для pp-токенов.
0 голосов
/ 04 апреля 2011

Недопустимый идентификатор

int 3d = 1;

Недопустимая директива препроцессора

#define x 1

Неожиданный токен

if [0] {}

неразрешимый идентификатор

while (0) {}            
0 голосов
/ 04 апреля 2011

Плохо сформированная константа с плавающей точкой (например, 123.34e или 123.45.33).

...