Как использовать добавление отступа в качестве разделителей блока с бизоном и гибким проводом

Я задаюсь вопросом, как реализовать добавление отступа как разделители блока у бизона + гибкий провод. Точно так же, как в Python. Я пишу свой собственный язык программирования (главным образом для забавы, но я намереваюсь использовать его вместе с игровым механизмом), я попытаюсь придумать что-то специальное, которое минимизирует шаблон и максимизирует dev скорость.

Я уже записал компилятор (на самом деле 'langToy' к переводчику Nasm) в C, но перестал работать. Некоторой причиной это только смогло обработать одну строку в целом исходном файле (хорошо, я бодрствовал больше 48 часов - так... Вы знаете, мозговой крах).

Я не знаю, начинаются ли фигурные скобки и/или->, конец легче реализовать (у меня нет проблемы при выполнении этого), или если это - просто мой мозг, который запирается.

Заранее спасибо!


Обновление: Хорошо, у меня нет подсказки о том, как сделать это с гибким проводом. У меня есть проблемы с возвратом нескольких DEDENTs к синтаксическому анализатору. Flex/Бизон относительно плохо мне знаком.


Обновление 2: Это - файл гибкого провода, который я придумал до сих пор; это действительно не совсем получает его:

%x t
%option noyywrap

%{
  int lineno = 0, ntab = 0, ltab = 0, dedent = 0;
%}

%%

<*>\n  { ntab = 0; BEGIN(t); }
<t>\t  { ++ntab; }
<t>.   { int i; /* my compiler complains not c99 if i use for( int i=0... */
         if( ntab > ltab )
           printf("> indent >\n");
         else if( ntab < ltab )
           for( i = 0; i < ltab - ntab; i++ )
             printf("< dedent <\n");
         else
           printf("=        =\n");

         ltab = ntab; ntab = 0;
         BEGIN(INITIAL);
         /* move to next rule */
         REJECT;}
.    /* ignore everything else for now */

%%

main()
{
  yyin = fopen( "test", "r" );
  yylex();
}

Можно попытаться играть вокруг с ним, возможно, Вы видит то, что я пропускаю. возврат нескольких dedents был бы простотой в Haxe (возвратите t_dedent (цифра);).

Этот код не всегда соответствует indents/dedents правильно.


Обновление 3: Я думаю, что оставлю надежду относительно гибкого провода и сделаю это мой собственный путь, Если кто-либо будет знать, как сделать это в гибком проводе, я был бы рад услышать его так или иначе.

10
задан 7 revs, 4 users 53% 10 March 2019 в 13:38
поделиться

3 ответа

Что вам нужно сделать, так это сделать так, чтобы модуль flex подсчитывал количество пробелов в начале каждой строки и вставлял соответствующее количество токенов INDENT / UNINDENT для использования анализатором для группировки. Один вопрос заключается в том, что вы хотите делать с вкладками и пробелами - вы просто хотите, чтобы они были эквивалентны фиксированным позициям табуляции, или вы хотите, чтобы отступы были согласованными (так, если одна строка начинается с табуляции, а следующая с пробелом вы сигнализируете об ошибке, что, вероятно, немного сложнее).

Предполагая, что вам нужны фиксированные табуляции с 8 столбцами, вы можете использовать что-то вроде

%{
/* globals to track current indentation */
int current_line_indent = 0;   /* indentation of the current line */
int indent_level = 0;          /* indentation level passed to the parser */
%}

%x indent /* start state for parsing the indentation */
%s normal /* normal start state for everything else */

%%
<indent>" "      { current_line_indent++; }
<indent>"\t"     { current_line_indent = (current_line_indent + 8) & ~7; }
<indent>"\n"     { current_line_indent = 0; /*ignoring blank line */ }
<indent>.        {
                   unput(*yytext);
                   if (current_line_indent > indent_level) {
                       indent_level++;
                       return INDENT;
                   } else if (current_line_indent < indent_level) {
                       indent_level--;
                       return UNINDENT;
                   } else {
                       BEGIN normal;
                   }
                 }

<normal>"\n"     { current_line_indent = 0; BEGIN indent; }
... other flex rules ...

. Убедитесь, что вы начали синтаксический анализ в режиме отступа (чтобы получить отступ в первой строке).

14
ответ дан 3 December 2019 в 18:35
поделиться

Фигурные скобки (и тому подобное) проще, если вы используете токенизатор, который удаляет все пробелы (используется только для разделения токенов). См. эту страницу (раздел «Как компилятор анализирует отступы?») Для получения некоторых идей по токенизации Python.

Если вы не выполняете токенизацию перед синтаксическим анализом, то может потребоваться дополнительная работа , это зависит от того, как вы строите синтаксический анализатор.

1
ответ дан 3 December 2019 в 18:35
поделиться

You need a rule that looks analogous to this(supposing you use tabs for your indents):

\t: {return TABDENT; }

Frankly, I've always found braces(or begin/end) to be easier to write and to read, both as a human and as a lexer/parser writer.

0
ответ дан 3 December 2019 в 18:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: