2016-12-26 7 views
0

Как C/C++ tokeniser/parser не понимает использование '*', так как он может использоваться для умножения и для типа указателей. например :.Как парсер/лексер C/C++ делает разницу между «*» указателя и «*» умножения?

... { 
    ... 
    obj *var1; // * used to make var1 as pointer to obj 
    var1 * var2; // * used to multiply var1 and var2 
} 

Обновление 1: В то время как tokenising/синтаксический анализ, пока мы не можем сделать разницу между идентификатором, который ссылается на переменную, и идентификатор, который относится к типу.

Update 2: (контекста вопроса) Я разработка и реализация языка программирования/C семейства C++, где указатели объявляются как Pointer<int>, и я хочу использовать стиль C-указатель вместо этого.

Update 3 (30 декабря 2016 года): Некоторые ответы этого stackoverflow question about LR(1) parser and C++, кажется, рассматривать мой вопрос.

+0

"*' obj * var1; '*": Умножение типа и неопределенного токена не имеет смысла, поэтому это может быть определение переменной. – alk

+0

Зная, что такое 'obj' /' var1' ... Но ведь синтаксический анализ C++ является сложным. – Jarod42

+0

вот почему у нас есть ключевые слова и идентификаторы. –

ответ

2

Токенизер не делает различия между ними. Он просто рассматривает это как токен *.

Парсер знает, как искать имена. Он знает, что obj является типом, поэтому можно разобрать <type> * <identifier> иначе, чем <non-type> * <non-type>. Ваш инстинкт на что-то: невозможно разобрать только синтаксис C без реализации какой-либо семантики. Единственный способ получить правильный синтаксис синтаксиса C требует интерпретации деклараций и отслеживания имен имен имен и имени не-типов. Ваше обновление:

Пока токенизация/синтаксический анализ, мы пока не можем различать идентификатор, который относится к переменной и идентификатору, который относится к типу.

не совсем прав, так как предполагается, что токенизация/синтаксический анализ выполняется одновременно как отдельный шаг. Фактически, разбор и семантический анализ чередуются. Когда typedef int obj; анализируется, он интерпретируется и принимает значение obj теперь называет тип. Когда синтаксический анализ продолжается и отображается obj * var1;, результаты раннего семантического анализа доступны для использования.

+0

Вы заявляете о том, что «для получения правильного разбора ...» совершенно неверно! C - контекстная свободная грамматика. Парсер только ищет типы _after_ parsing. Тип не влияет на синтаксический анализ (контекст бесплатный!). В этом случае '*', используемый как оператор _unary_, является разыменованием, поэтому 'a ** b' означает разыменование' b' и умножение, которое с 'a' и' a * b' может означать только умножение. –

+0

См., Например, https://gist.github.com/codebrainz/2933703 для контекстной грамматики C99. –

+0

@PaulOgilvie 'a * b;' получает разбор по-разному в зависимости от того, является ли 'a' именем типа. Вы совершенно не правы, что 'a * b;' может означать только умножение, оно может альтернативно означать «объявлять' b' как указатель на тип 'a'. Грамматика, на которую вы ссылаетесь, показывает нереализованную функцию check_type, которую нужно добавить в lexer, чтобы вернуть либо «TYPE_NAME», либо «IDENTIFIER», в зависимости от того, что подходит. Реализация, которая требует частично реализации семантики C, точно так же, как я указал в своем ответе. – hvd

-1

* для указания переменной указателя используется только в контексте объявления переменной или для разыменования переменной указателя.

Ваша линия

var1 * var2; // * used to multiply var1 and var2 

будет недействительна с указателем var1.

+0

Да, но вы должны знать, что 'var1' не является типом, в чем заключался весь вопрос. – rici

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

  • Нет связанных вопросов^_^