Как большинство компиляторов C / C ++ создают маркеры для массивов?

OneAndOnly спросил: 28 марта 2018 в 02:59 в: compiler-errors

Итак, у меня есть 2 вопроса, связанных с большинством компиляторов c / c ++:

1. Когда сканер большинства компиляторов c / c ++ видит что-то вроде MyArray [20], что такое токен что он создает? большинство компиляторов создают маркер как array_token или array_token [const_int] или ...? (Я хочу знать, что происходит с размером массива после превращения его в токен), этот вопрос относится к моему второму вопросу.

2. Когда мы пишем что-то вроде MyArray [20.5] в середине нашего код (не в объявлении) анализирует ли этот синтаксис эту ошибку с использованием грамматики или мы можем ее обнаружить только с помощью семантических подпрограмм?

Важное примечание : Я говорю о большинстве компиляторов c / c ++ и наиболее общем способе, я знаю, что некоторые редкие компиляторы могут делать это по-другому, но как действуют большинство компиляторов? Какая норма? или, по крайней мере, как работает самый популярный компилятор? (На наших экзаменах они просто говорят свой компилятор ac / c ++, поэтому мы просто должны предположить, что он действует, как большинство компиляторов).

Возьмите второй вопрос:

Я думаю, что синтаксический анализатор не может обнаружить это, потому что мы можем иметь выражение внутри области действия, например MyArray [I j], поэтому у нас есть что-то вроде S - > array_token [expression] в нашей грамматике, и поскольку выражение может иметь float в нем, поэтому анализатор не обнаружит ошибку, но, пожалуйста, исправьте меня, если я ошибаюсь.


1 ответ

sepp2k ответил: 28 марта 2018 в 03:53
  1. В соответствии с лексическими правилами, описанными в стандарте ISO C, MyArray[20] - это идентификатор, за которым следует [, за которым следует целочисленная константа, после которой следует ]. Я ожидаю, что большинство (или даже все) компиляторы C будут представлять его именно так. Нет такой вещи, как маркер массива, определенный в стандарте, или какой-либо другой реализации, о которой я знаю.

  2. Правило грамматики для нижнего индекса массива:

    postfix-expression:  postfix-expression [ expression ]
    

    MyArray[20.5] соответствует этому правилу, поэтому оно синтаксически допустимо. Это ошибка типа, а не ошибка синтаксиса. Таким образом, задача семантического анализатора заключается в обнаружении этой ошибки.

  3. (в ответ на ваш комментарий)

    , если у нас есть что-то вроде массива INT [ 10.5] превращается в это ------- > int id [const_token], следовательно, парсер обнаружит это правильно? (на этот раз я говорю об этом в объявлении), поскольку в грамматике у нас может быть правило типа S - > id [int_const]

    Правило грамматики C89 1 для декларатора массива (часть, которая следует после int в вашем объявлении) следующим образом:

     direct-declarator: direct-declarator [ constant-expressionopt ]

    array[10.5] соответствует этому правилу (поскольку direct-declarator: identifier - это другое правило), поэтому int array[10.5] синтаксически правильное объявление. Опять же, это семантическая ошибка, а не синтаксическая.

    PS: обратите внимание, что constant-expression просто определяется как псевдоним для conditional-expression. Тот факт, что выражение должно быть на самом деле постоянным, не обеспечивается грамматикой и также является семантическим свойством.


1 я использовал Правило от C89, потому что это проще, чем в более поздних версиях. Однако более поздние версии не отличаются в зависимости от вопроса.

OneAndOnly ответил: 28 марта 2018 в 03:41
Спасибо за ответ! последний вопрос: так что если у нас есть что-то вроде массива INT [10.5], оно превращается в следующее: int id [const_token], поэтому парсер обнаружит, что это правильно? (на этот раз я говорю об этом в объявлении), поскольку в грамматике у нас может быть правило типа S - > Идентификатор [int_const]
Ira Baxter ответил: 28 марта 2018 в 03:48
Sepp2k прав. Смотрите stackoverflow.com/a/36681568/120163 репрезентативные выходные данные лексера для нашего внешнего интерфейса C. Вы можете видеть идентификаторы как одиночные токены. Там не показано: '[' и ']' также являются токенами; должно быть очевидно из-за токена для ';'.
sepp2k ответил: 28 марта 2018 в 03:54
@OneAndOnly Я добавил ответ на ваш комментарий в свой ответ.