Size: a a a

Compiler Development

2021 May 24

h

hazer_hazer in Compiler Development
ждал этого коммента
источник

h

hazer_hazer in Compiler Development
да. но тогда вам придется проверять пробелы на уровне парсинга, а обычно пробелы вне строк всегда пропускают.
вам придется либо добавить токен пробела, либо для всех мест, где важно отсутствие пробелов делать два разных токена, например Underscore и UnderscoreNoWS
источник

РС

Роман Соловьев... in Compiler Development
а почему вы так думаете? в каких кейсах могут возникнуть проблемы из-за пробела?
источник

h

hazer_hazer in Compiler Development
ну смотрите.
aaa bbb, если вы на уровне лексера сделаете три токена Letter{'a'} и три токена Letter{'b'}, то на уровне парсера у вас будет 6 токенов Letter и получится просто `Variable{'aaabbb'}
Тогда вам придется создать отдельный токен для пробелов — что довольно странно.
Либо, вам придется создать специальный токен LetterNoWS, и тогда у вас будет два токена LetterNoWS{'a'} потом один Letter{'a'}. И когда вы будете парсить Variable, надо будет проверять, что внутри Variable только LetterNoWS, а в конце может быть либо Letter либо любой другой токен, который вообще не может быть в Variable.
И это очень сильно усложняет всё в принципе. Так что советую идентификаторы на уровне лексера собирать
источник

РС

Роман Соловьев... in Compiler Development
вы правы, но тут ведь неоднозначность на уровне грамматики получается
источник

РС

Роман Соловьев... in Compiler Development
условно, если пользователь пишет грамматику для подобных конструкций - его задача это предусмотреть
источник

h

hazer_hazer in Compiler Development
неа. никакой неоднозначности.
asadasdasdas1232132131 — это идентификатор
asdasd  eiwubfewu — это два идентификаторы
asdasd{} — это идентификатор, потом токен {, потом токен }
источник

h

hazer_hazer in Compiler Development
то есть. у вас простые правила.
идентификатор может начинаться только с _ или буквы, а дальше к этому добавляются ещё и цифры. Но вы продолжаете собирать символы для идентификатора пока не встретите токен, который не может быть частью идентификаторы (и пробел в их числе).
источник

РС

Роман Соловьев... in Compiler Development
а как тогда в грамматике описать что переменные могут начинаться только с нижнего подчеркивания и могут состоять только из 3-х символов
источник

h

hazer_hazer in Compiler Development
не хотелось бы это делать опять, так как я никаким образом не хороший пример, но вот лексер — он оооочень простой:
https://github.com/hazer-hazer/Jacy/blob/85967aa3f72a0181a0a4fb535eedb8982959ec45/src/parser/Lexer.cpp#L201
источник

h

hazer_hazer in Compiler Development
ну. парсить бесконечно. а потом сказать "НЕЛЬЗЯ"
источник

DP

Dmitry Popov in Compiler Development
LR мощнее, чем монадные парсер-комбинаторы? А можно примеров?
источник

K

Kir in Compiler Development
LR(1) мощнее, чем LL(1).

Пример:
S = Add
Add = Add + Factor | Factor
Factor = Factor * Term | Term
Term = "(" Add ")" | int

из-за левой рекурсии, для применения LL(1) или комбинаторов нужно переделать эту грамматику в не-леворекурсивную.

А у комбинаторов вместо choice оператор left-biased choice. Так что LR(1) с приоритетами мощнее комбинаторов.
источник

K

Kir in Compiler Development
В лексере описать, это ж не часть парсера
источник

h

hazer_hazer in Compiler Development
Ну. Можно же использовать left-corner хак в LL
источник

h

hazer_hazer in Compiler Development
И это не LR фича
источник

K

Kir in Compiler Development
Это фича рекурсивного подъёма, частным случаем которого является LR
источник

h

hazer_hazer in Compiler Development
Возможно. Но... Почему бы не использовать
источник

K

Kir in Compiler Development
Использовать что? Где?
источник

K

Kir in Compiler Development
В LL это можно сделать примерно никак, потому что LL - это рекурсивный спуск, а не подъём
источник