Size: a a a

Compiler Development

2021 May 24

h

hazer_hazer in Compiler Development
а. ну. если ещё какой-нибудь delimiter типа ,
то


skip First
bool first = true
while not EOF
   if Follow: break
   if first: first = false
   else skip `,`
   // Parse element...
skip Follow
источник

h

hazer_hazer in Compiler Development
или я вас неправильно понял?
источник

РС

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

h

hazer_hazer in Compiler Development
да. ну можно заморочиться и хранить состояние для разного кол-ва элементов.
либо сделать менее быстрым путем — спарсить всё, а потом если элементов 0 — то это, если 1 — то другое, если 2-3 — то что-то ещё
источник

h

hazer_hazer in Compiler Development
вот пример для наглядности, как я это делал. Вроде как работает 😉. https://github.com/hazer-hazer/Jacy/blob/85967aa3f72a0181a0a4fb535eedb8982959ec45/src/parser/Parser.cpp#L1192
источник

РС

Роман Соловьев... in Compiler Development
2100 строк😨
источник

AT

Alexey Tkachenko in Compiler Development
1763 sloc всего же
источник

h

hazer_hazer in Compiler Development
пробелов просто много и wrap'ов вызовов функций
источник

h

hazer_hazer in Compiler Development
а как вы sloc'и считаете?
источник

AT

Alexey Tkachenko in Compiler Development
дык оно само
источник

AT

Alexey Tkachenko in Compiler Development
источник

h

hazer_hazer in Compiler Development
ваф
источник

РС

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

Declaration = "var" Variable ("=" Additive)? ";"

("=" Additive)? - группа, у которой есть свой квантор.

Но для групп я First и Follow не считал, а видимо без этого никак😬
источник

TW

Tony Werner in Compiler Development
есть удобная утилитка еще
https://github.com/cgag/loc
источник

h

hazer_hazer in Compiler Development
ну. во-первых. я бы стал включать в граматику отдельных statement'ов ;.
Лучше делать
statement: ForStmt | VarStmt;

statements: (statement ;)*

Для групп вроде = AssignExpr вам не нужен First Follow
Вам нужно просто if '=' => parse expression
источник

h

hazer_hazer in Compiler Development
Точнее. Правильнее так — Мы разделяем statement'ы на те, которые оканчиваются блоком (то есть у них есть тело обернутое в {}, тогда нам не нужен semi ;), и на те, что требуют ;.
и парсить statement: BlockStatement | Statement ;``, где BlockStatement: IfStatement, а Statement: VarDeclStatement. Для IfStatement: IF expression '{' statements '}' Нам очевидно ; не нужен в конце
источник

РС

Роман Соловьев... in Compiler Development
а как  обрабатывать , например, такую группу:

Variable = (Letter | Underscore) (Char)*

нужно же понять, когда Char'ы закончились
источник

h

hazer_hazer in Compiler Development
ну. если Char это всякие digit'ы, то вот так должно получиться.
VariableStart: '_' | Letter;
Variable: VariableStart (VariableStart | Digit)*

но это мы уже про лексинг тогда говорим
источник

РС

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

Float = Int "." Int
Variable = (Letter | Underscore) (Char)*
Int = Numeral+
Char = Letter | Numeral | Underscore
Letter = [[a-zA-Z]]
Numeral = [[0-9]]
Underscore = "_"
источник

А⚙

Антон ⚙️ in Compiler Development
> писать парсер на C++
источник