Как установить bison windows
Обычный способ вызова Bison следующий:
Здесь вх_файл -- имя файла грамматики, обычно заканчивающееся `.y' . Имя файла анализатора получается заменой `.y' на `.tab.c' . Так, `bison foo.y' даст `foo.tab.c' , а `bison hack/foo.y' -- `hack/foo.tab.c' . Также возможно, если вы в своём файле грамматики пишете код на C++, а не на C, назвать его `foo.ypp' или `foo.y++' . Тогда выходные файлы будут иметь расширение, аналогичное расширению входного (соответственно `foo.tab.cpp' и `foo.tab.c++' ). Эта возможность влияет на все параметры, обрабатывающие имена файлов, такие как `-o' или `-d' .
создаст `вх_файл.tab.cxx' и `вх_файл.tab.hxx' , а
создаст `вых_файл.c++' и `вых_файл.h++' .
Bison поддерживает как традиционные однобуквенные параметры, так и длинные мнемонические имена параметров. Длинные имена параметров помечаются `--' вместо `-' . Сокращение имён параметров допустимо до такой длины, пока они остаются уникальными. Если длинный параметр принимает аргумент, как, например, `--file-prefix' , соедините имя параметра и аргумент знаком `=' .
Вот список параметров, которые можно использовать с Bison, в алфавитном порядке коротких параметров. Далее следует перекрёстный указатель в алфавитном порядке длинных параметров.
Режимы работы: -h --help Вывести обзор параметров командной строки Bison и завершить работу. -V --version Вывести версию Bison и завершить работу. -y --yacc --fixed-output-files Эквивалентно `-o y.tab.c' . Выходной файл анализатора называется `y.tab.c' , другие выходные файлы: `y.output' и `y.tab.h' . Назначение этого параметра в имитации соглашений по именованию выходных файлов Yacc. Так, следующий скрипт shell может заменить Yacc:
Регулирование вывода: -d --defines Как будто было задано %defines , т.е. записывает дополнительный выходной файл, содержащий макроопределения имён типов лексем, определённых в грамматике, и типа семантических значений YYSTYPE как несколько объявлений переменных extern . См. раздел 4.7.8 Обзор объявлений Bison. --defines= файл_определений То же, что и предыдущий, но записывает в файл файл_определений . -b префикс_файла --file-prefix= префикс Как будто было задано %file-prefix , т.е. задаёт префикс имён всех выходных файлов Bison. См. раздел 4.7.8 Обзор объявлений Bison. -v --verbose Как будто было задано %verbose , т.е. записывает дополнительный выходной файл, содержащий подробное описание грамматики и анализатора. См. раздел 4.7.8 Обзор объявлений Bison. -o имя_файла --output= имя_файла Именем файла анализатора будет имя_файла . Имена других выходных файлов получаются из имя_файла как описано для параметров `-v' и `-d' . -g Вывести определение VCG автомата LALR(1)-грамматики, вычисленного Bison. Если файл грамматики называется `foo.y' , выходной файл VCG будет `foo.vcg' . --graph= файл_графа Поведение --graph то же, что и `-g' . Единственное различие в том, что у него есть необязательный аргумент -- имя выходного файла графа.
Вот список переменных среды, оказывающих влияние на работу Bison. `BISON_SIMPLE' `BISON_HAIRY' Многие анализаторы, генерируемые Bison, дословно копируются из файла `bison.simple' . Если Bison не может найти этот файл или если вы хотите указать Bison использовать другую его копию, установка переменной среды BISON_SIMPLE на путь к файлу заставит Bison использовать эту копию. Когда используется объявление `%semantic_parser' , Bison копирует анализатор из файла `bison.hairy' . Расположение этого файла также может быть задано или переопределено аналогичным образом, переменной среды BISON_HAIRY .
Здесь приведён список параметров в алфавитном порядке длинных параметров, чтобы помочь вам найти соответствующий короткий параметр.
В системах DOS/Windows 9X возможность использования расширений имён выходных файлов, таких как `.tab.c' , зависит от используемой файловой системы. Простая файловая система DOS содержит ограничение на длину имени файла, не допускает использование определённого множества незаконных литер и не допускает более одной точки в имени файла.
Порт bison DJGPP определяет во время выполнения, доступны ли длинные имена файлов (ДИФ). Поддержка ДИФ будет доступны в сеансе DOS под Windows 9X и последующих версий. Для Windows NT 4.0 для правильной поддержки ДИФ в сеансе DOS нужен специальный драйвер ( `ntlfn09b.zip' или более поздний, доступный на любом зеркале simtelnet в каталоге /v2misc). Если поддержка ДИФ доступна, порт bison DJGPP будет использовать для выходных файлов стандартные расширения имён файлов POSIX. Если поддержка ДИФ недоступна, этот порт будет использовать расширения имён файлов для DOS.
В этой таблице указаны используемые расширения:
расширени ДИФ (Win9X) | расширение КИФ (просто DOS) |
`.tab.c' | `_tab.c' |
`.tab.h' | `_tab.h' |
`.tab.cpp' | `_tab.cpp' |
`.tab.hpp' | `_tab.hpp' |
`.output' | `.out' |
`.stype.h' | `.sth' |
`.guard.c' | `.guc' |
Синтаксис командной строки Bison под VMS является вариацией обычного синтаксиса команды Bison адаптированной для соответствия соглашениям VMS.
Чтобы найти VMS-эквивалент параметра Bison, возьмите длинную форму параметра, подставьте `/' вместо начального `--' , `_' -- вместо каждого `-' в имени длинного параметра. Например, такой вызов под VMS:
Введение в Flex и Bison и начать работу под Windows
FLEX используется в качестве лексического анализа, в то время как бизон, используемый в качестве грамматического анализа. Лексический анализ разлагает вход в одну значимующую фразу, называемый токеном; грамматический анализ определяет, как эти фразы связаны друг с другом (с использованием выражения дерева грамматики).
Flex генерирует лексический анализатор; Bison генерирует синтаксический анализатор.
Или вы также можете использовать LEX и YACC.
LEX и YACC являются инструментами с открытым исходным кодом, чтобы помочь разработчикам реализовать синтаксис, лексический анализ.
Насколько я понимаю этот инструмент, в основном, есть два способа; это предположение, что вы должны написать компилятор самостоятельно, вы должны использовать это, полностью рукописный лексический анализатор, грамматический анализатор нереально, рабочая нагрузка слишком велика; фильтрация пакетов Этот тип работы, его лексики и синтаксический анализ также сложны, и это также используется. Я изучал себя.
Один базовый пример использования Flex и Bison генерирует калькулятор;
Давайте посмотрим на базовое использование Flex под Windows;
Версия для Windows Restormate здесь;
После загрузки вы можете содержать следующий файл;
Создать файлбо .L в каталоге; содержимое выглядит следующим образом; это файл FLEX для калькулятора;
Затем выполните команду win_flex bo.l;
Создайте файл C кода C для Lex.yy.c;
Код довольно длинный, я не опубликован;
Затем создайте файл b.y в каталоге; содержимое выглядит следующим образом;
Выполнить следующую команду;
Generate B. Tab.C Code файл кода и файл заголовка B.Tab.h;
Эти два файла являются примерами ввода;
Добавьте генерируемый файл файлов C и заголовок в среду разработки и построить его;
Используйте CFREE 5.0, Win7 ниже;
Создайте следующую ошибку;
[Error] Y:\dddd\win_flex_bison-latest\lex.yy.c:1187: undefined reference to `yywrap'
Это проблема в совместимости FLEX;
Добавить функцию в конец файла Lex.yy.C, чтобы построить успех;
Бегать, калькулятор там;
Как долго вход может быть адаптирован; это с точки зрения слов и синтаксиса;
Это единственный пост в серии, в центре внимания которого — старообрядный сишный бизон, так надоевший некоторым. Тем, кто пишет не на Си, пост всё равно должен быть интересен, потому что похожие по принципу работы генераторы LR-парсеров существуют для очень многих языков. Тех же, кто идеологически не приемлет LR-парсеры, мне сегодня привлечь нечем.
Далее в посте:
- Компиляция грамматики
- Двухступенчатый парсер
- Что у него внутри?
- Конфликты в грамматике
- Как это работает?
Компиляция грамматики
Общий принцип такой же, как с flex в первой части: мы перечисляем правила грамматики, и напротив каждого правила пишем сишный код, который будет выполняться во время свёртки правила.
В прошлый раз упомянули, что во время свёртки мы вынимаем из стека набор символов (строк или переменных), смотрим на их значения, задаём значение для свернувшейся переменной, и кладём её в стек вместо вынутых.
Разбор кода
%%, как и в lex -файлах, разделяет область объявлений и область правил грамматики. Правила перечисляются в том же виде, как мы уже привыкли; в конце правила добавляем код свёртки. В коде свёртки, чтобы сослаться на значения символов на стеке парсера, используем $-теги. $$ ссылается на сворачиваемую переменную (левую часть правила), $1 на самый левый символ в правой части правила (самый глубокий в стеке парсера), $2 на второй слева, и т.д. Если в правой части правила N символов, то можно пользоваться значениями от $1 до $N .
Если код свёртки не задан, и в правой части правила один символ, то по умолчанию бизон «наследует» его значение: $$=$1
Самая первая объявленная переменная считается «корнем» грамматики, т.е. весь входной текст должен в итоге свернуться в этот корень. EXPR подходил бы в качестве корня, но тогда печать вычисленного выражения пришлось бы засунуть в свёртку EXPR ; а значит, печаталось бы ещё и значение каждого подвыражения по дороге. Для удобства печати заведём новую переменную EVALUATE , которая используется только в качестве корня. Это заодно даёт возможность прочитать в конце выражения перевод строки — кроме удобства печати, получаем удобство ввода.
При компиляции парсера нужно указать библиотеку liby , в которой лежит стандартная бизонья main() .
[tyomitch@home
]$ bison 2.y
[tyomitch@home
]$ cc -ly 2.tab.c
[tyomitch@home
]$ ./a.out
22+3*4-5
=29
[tyomitch@home
]$ ./a.out
2 + 2
syntax error
В отличие от калькулятора торговок с рынка, который умел игнорировать пробелы и комментарии, бизоний калькулятор понимает строго заданный синтаксис: цифры, знаки операций, перевод строки в конце. Чтобы предусмотреть, например, пробелы между любой парой символов, пришлось бы добавлять их в грамматику явно:
EXPR: TERM | EXPR WS '+' WS TERM | EXPR WS '-' WS TERM ;
TERM: NUM | TERM WS '*' WS NUM | TERM WS '/' WS NUM ;
NUM: DIGIT | NUM DIGIT ;
DIGIT: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ;
WS: | WS ' ' ;
Ясно, что это неудобно. Да и писать для распознавания цифр 10 разных правил неудобно; а если бы нам нужны были латинские буквы, например в именах переменных, мы бы задавали 52 правила?!
До чего здорово было бы совместить преимущества flex и bison ! Чтобы простые выражения (числа, пробелы) распознавать было просто, и чтобы сложные выражения распознавать было возможно.
Двухступенчатый парсер
Если у нас уже есть flex -парсер, который успешно распознаёт числа и удаляет комментарии и пробелы, то прогоним входной текст через него; а то, что получится, прогоним через продвинутый бизоний парсер. На самом деле, нет надобности хранить промежуточный результат: обе ступени можно выполнить за один проход. flex читает входной текст символ за символом, время от времени передавая «наверх» бизону токены — терминальные символы грамматики. Значения для токенов flex задаёт сам.
%%
Функция yylex нам больше не нужна: теперь входные символы будут поступать не из stdin , а от flex .
Кроме того, стёрли '\n' после EXPR (его проглотит flex ), и убрали все правила про NUM и DIGIT .
%option yylineno
%option noyywrap
Чтобы передать токен бизону, его значение записываем в глобальную (ох ужас!) переменную yylval , и возвращаем код токена.
Обычные символы передаём обычным способом (возвращаем код символа).
Опция noyywrap указывает, что входной текст один, и после чтения EOF не нужно пытаться перейти к следующему тексту. Эта опция устанавливалась автоматически, пока мы пользовались %option main , задававшей чтение с stdin . Сейчас main() будет бизонья, поэтому нам не нужно ни просить у flex стандартную main() , ни писать свою.
Компилируем двухступенчатый парсер:
[tyomitch@home
]$ lex 3.lex
[tyomitch@home
]$ bison -d 3.y
[tyomitch@home
]$ cc -ly lex.yy.c 3.tab.c
[tyomitch@home
]$ ./a.out
22+ // hello
3*4 - 5
=29
[tyomitch@home
]$ ./a.out
22+x
syntax error
По поводу терминологии: в такой двухступенчатой модели нижний парсер, распознающий токены, по традиции называют лексическим анализатором («лексером»), а верхний, распознающий конструкции из токенов — синтаксическим анализатором. Это указание именно роли парсера, а не его устройства: другие системы разбора могут, например, использовать для обеих ступеней магазинно-автоматные парсеры.
Что у него внутри?
Чтобы увидеть сгенерированный автомат, не нужно нырять в пучины сишного кода: у бизона могучие средства для отладки грамматик. Указываем ключ -v , и глядим в файл с суффиксом .output .
После переноса парсинга чисел в лексер, в автомате осталось 14 состояний, и описаны они примерно так:
Для каждого состояния указаны правила, которые в этом состоянии распознаются (вместе с их номерами в грамматике), и перечислены действия, выполняемые для каждого входного символа. Не указано следующее состояние после свёртки; вместо этого автомат возвращается в состояние, прочитанное из стека, и в нём ищет правило «go to», соответствующее свежесвёрнутому нетерминалу. Таким образом, таблица переходов автомата получается двумерной: в каждом состоянии действие зависит только от входного символа, и не зависит от содержимого стека. (Но из стека берётся следующее состояние после свёртки.)
%%
int main ()
Код после второго тега %% копируется в парсер неизменным так же, как если бы он был в % .
Теперь, раз мы определили main() сами, уже не нужно при компиляции подключать liby :
[tyomitch@home
]$ lex 3.lex
[tyomitch@home
]$ bison -dt 3.y
[tyomitch@home
]$ cc lex.yy.c 3.tab.c
[tyomitch@home
]$ ./a.out
Starting parse
Entering state 0
Reading a token: 22+3*4-5
Next token is token NUM (22)
Shifting token NUM, Entering state 1
Reducing stack by rule 5 (line 20), NUM -> TERM
Stack now 0
Entering state 4
Reading a token: Next token is token '+' (22)
Reducing stack by rule 2 (line 15), TERM -> EXPR
Stack now 0
Entering state 3
Next token is token '+' (22)
Shifting token '+', Entering state 6
Reading a token: Next token is token NUM (3)
Shifting token NUM, Entering state 1
Reducing stack by rule 5 (line 20), NUM -> TERM
Stack now 0 3 6
Entering state 10
Reading a token: Next token is token '*' (3)
Shifting token '*', Entering state 8
Reading a token: Next token is token NUM (4)
Shifting token NUM, Entering state 12
Reducing stack by rule 6 (line 21), TERM '*' NUM -> TERM
Stack now 0 3 6
Entering state 10
Reading a token: Next token is token '-' (4)
Reducing stack by rule 3 (line 16), EXPR '+' TERM -> EXPR
Stack now 0
Entering state 3
Next token is token '-' (4)
Shifting token '-', Entering state 7
Reading a token: Next token is token NUM (5)
Shifting token NUM, Entering state 1
Reducing stack by rule 5 (line 20), NUM -> TERM
Stack now 0 3 7
Entering state 11
Reading a token: Now at end of input.
Reducing stack by rule 4 (line 17), EXPR '-' TERM -> EXPR
Stack now 0
Entering state 3
Now at end of input.
Reducing stack by rule 1 (line 13), EXPR -> EVALUATE
=29
Stack now 0
Entering state 2
Now at end of input.
Из стека печатаются только состояния; типы символов в стеке, и их значения, остаётся угадывать из контекста.
Если макрос YYPRINT не задан, тогда угадывать придётся и значения прочитанных токенов: бизон будет печатать только пустые скобки.
Конфликты в грамматике
Поскольку типичный источник конфликтов — арифметические выражения, то и намёки даются в виде указания приоритета операторов (выполнять умножение раньше сложения) и их ассоциативности (из операторов с равным приоритетом, который выполнять раньше). Чем ниже оператор в списке, тем выше приоритет. Операторы в одной строчке списка получают одинаковый приоритет.
%%
Для правоассоциативных операторов есть директива %right .
Противоестественность хака с приоритетами можно оценить на примере двусмысленности if (1) if (2) foo(); else bar();
Чтобы она распарсилась привычным образом — if (1) < if (2) foo(); else bar(); >— нужно, чтобы приоритет else был выше, чем у ')'
Оба этих терминала тяжело назвать операторами, и тем более тяжело задать им «естественный» приоритет.
Зато это работает!
«Грамматика с намёками» компактнее однозначной и в исходном виде (короче вдвое), и в виде автомата (сэкономили одно состояние).
Даже в однозначной грамматике могут возникать конфликты, связанные с принципом работы магазинного автомата: во время выполнения каждого действия он видит только один следующий символ ввода. Например, грамматика — однозначная, и ей соответствует всего два слова — sail и sale. Когда парсер сдвинул первую букву 's' и видит после неё 'a', он не может сделать выбор, сворачивать S1 или S2 : правильная свёртка зависит от того, какая буква будет после 'a'; но её автомат ещё не видит.
Это вторая причина, по которой парсер делают двухступенчатым: за счёт того, что лексер сжимает строки в токены и отбрасывает ненужные символы между токенами, LR-парсеру удаётся «дальше» заглядывать: не на одну букву, а на один токен вперёд.
Как это работает?
Как и у flex , ядро парсера — таблица переходов и небольшой цикл. Используется два параллельных стека: стек состояний yyssa и стек значений yyvsa — всё равно состояния и символы входят и выходят из стека всегда парами.
Как и в прошлый раз, символы, идентичные с точки зрения парсера, объединены в классы. В данном случае, классов 7, и они перечислены в файле .output . Массив static const unsigned char yytranslate[259] сопоставляет всем терминалам класс. (От 0 до 255 — обычные символы; 258 — объявленный нами терминал NUM ).
Таблицы переходов хитроумно объединены. В основной таблице хранятся описания действий: для сдвига (положительное число) — в какое состояние перейти; для свёртки (отрицательное) — по какому правилу свернуть. Удивительно, что таблица не только одномерная, но даже элементов в ней меньше, чем наших состояний (их 14).
Трюк в том, что индекс первого действия для каждого состояния хранится в отдельной таблице: YYPACT_NINF означает, что состоянию не соответствует ни один элемент yytable ; иначе говоря, выполняемое действие не зависит от входного символа.
Действия по умолчанию для каждого состояния хранятся в другой отдельной таблице: Не зависеть от входного символа может только выполнение свёртки, поэтому значения в yydefact — номера правил грамматики, по которым нужно сворачивать.
По индексу из yypact[n] хранится действие для состояния n и для класса символов 0. Действие для класса символов k хранится в yytable[yypact[n]+k] ; поэтому в yypact могут быть отрицательные индексы — это лишь «база», к которой будет прибавляться номер класса.
Чтобы проверить, к которому символу относится каждое действие в yytable , есть ещё одна таблица: Что мы видим? yytable[0] относится к символам класса 4, yytable[1] к символам класса 5, и так далее.
Попробуем найти какое-нибудь действие, например приведённые выше:
Класс терминала NUM — 3.
Ищем первый сдвиг: yytable[yypact[7]+3]==yytable[4+3]==1 (и действительно, yycheck[yypact[7]+3]==3 )
Второй сдвиг: yytable[yypact[8]+3]==yytable[5+3]==12 (и действительно, yycheck[yypact[7]+3]==3 )
Аналогичным образом побита на три массива таблица «go to», которая задаёт, в какое состояние нужно перейти после свёртки.
Код собственно парсера: (неинтересные куски вырезаны, а интересные прокомментированы)
yynewstate :
*++yyssp = yystate; // кладём в стек текущее состояние
yyn = yypact[yystate]; // индекс первого действия
if (yyn == YYPACT_NINF)
goto yydefault; // не зависит от входного символа
yychar = yylex(); // читаем входной символ
yytoken = yytranslate[yychar]; // определяем класс
yyn += yytoken; // индекс внутрь yytable
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yydefault; // нет подходящего действия
yyn = yytable[yyn];
if (yyn <= 0 ) yyn = -yyn;
goto yyreduce;
>
*++yyvsp = yylval; // сдвигаем
yystate = yyn; // следующее состояние
goto yynewstate;
yydefault :
yyn = yydefact[yystate];
if (yyn == 0 ) // ошибка синтаксиса:
goto yyerrlab; // ни одно действие не подошло,
// и нет действия по умолчанию
yyreduce :
yylen = yyr2[yyn]; // длина правой части правила
yyval = yyvsp[ 1 -yylen]; // по умолчанию: унаследовать $1
// действия при свёртке:
// вместо $-тегов бизон подставил yyval слева и yyvsp[] справа
yyvsp -= yylen; // удаление из стека
yyssp -= yylen;
*++yyvsp = yyval; // кладём свежесвёрнутую переменную
yyn = yyr1[yyn]; // номер переменной по номеру правила
// вычисление следующего состояния после свёртки
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
if ( 0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate;
Вновь видим: весь парсер, вместе с вычислением выражения, уложился в пару страниц кода; да и то, его треть — мудрёный поиск по сжатым таблицам.
В следующий раз займёмся парсингом игрушечного языка программирования.
Достоинство бизона и ему подобных в том, что от усложнения языка вырастут в парсере только таблицы и свитч с действиями при свёртке, скопированными из .y -файла.
Весь остальной код парсера универсален: никаких спагетти, никаких рекурсивных функций, вызывающих друг друга в хитрых комбинациях. Правила грамматики действительно компилируются, а не обрамляются в синтаксис языка высокого уровня.
У меня есть файлы Lex и YACC для анализа моих файлов (файл .l и файл .y ).
Как скомпилировать эти файлы и как создать для них эквивалентный файл .c на платформе Windows?
На сегодняшний день (05.04.2011, обновлено 29.11.2017) вам потребуются самые последние версии:
После этого выполните полную установку в каталоге по вашему выбору без пробелов в имени . Я предлагаю C:\GnuWin32 . Не устанавливайте его в default (C: \ Program Files (x86) \ GnuWin32), потому что у bison есть проблемы с пробелами в именах каталогов, не говоря уже о скобках.
Также рассмотрите возможность установки Dev-CPP в каталог по умолчанию ( C:\Dev-Cpp )
После этого установите переменную PATH, чтобы включить каталоги бункеров gcc (в C:\Dev-Cpp\bin ) и flex\bison (в C:\GnuWin32\bin ). Для этого скопируйте это: ;C:\Dev-Cpp\bin;C:\GnuWin32\bin и добавьте его в конец переменной PATH , определенной в месте, показанном на этом рисунке:
Если изображение не в хорошем разрешении, вы можете увидеть пошаговые инструкции здесь.
Откройте приглашение, перейдите в каталог, в котором находятся ваши ".l" и ".y", и скомпилируйте их с помощью:
- flex hello.l
- bison -dy hello.y
- gcc lex.yy.c y.tab.c -o hello.exe
Вы сможете запустить программу. Я сделал исходники для простого теста (печально известного Hello World ):
Здравствуйте. L
Привет.
Отредактировано: избегая "предупреждения: неявное определение yyerror и yylex".
Отказ от ответственности: помните, что этот ответ очень старый (с 2011 года!), И если вы столкнетесь с проблемами из-за изменения версий и функций, вам может потребоваться дополнительное исследование, потому что я не могу обновить этот ответ, чтобы отразить новые вопросы. Спасибо, и я надеюсь, что это будет хорошей отправной точкой для вас, как и для многих.
У меня была такая же проблема, у нее очень простое решение.
Шаги по запуску программы Lex:
- Инструменты -> 'Компилятор файлов Lex'
- Инструменты -> 'Lex Build'
- Инструменты -> «Открыть CMD»
- Затем в командной строке введите пример 'name_of_file.exe' -> '1.exe'
- Затем введите весь ввод, нажмите Ctrl + Z и нажмите Enter.
Самый простой способ - загрузить и установить cygwin и загрузить пакеты gcc и flex во время установки. Затем, чтобы запустить файл lex, например. abc.l
Также стоит отметить, что WinFlexBison был упакован для Менеджер пакетов Chocolatey. Установите это, а затем перейдите:
. который на момент написания содержит Bison 2.7 и Flex 2.6.3.
Также существует winflexbison3 , который (на момент написания) имеет Bison 3.0.4 и Flex 2.6.3.
Выполните полную установку Git для Windows (с помощью инструмента Unix) и bison и flex будет вместе с ним в папке bin .
У меня есть файлы Lex и YACC для анализа моих файлов ( .l file и .y file).
Как скомпилировать эти файлы и как сделать эквивалентный файл .c для них на платформе Windows?
На сегодняшний день (2011-04-05, обновлено 2017-11-29) вам понадобятся последние версии:
После этого сделайте полную установку в каталоге вашего предпочтения без пробелов в названии. Я предлагаю C:\GnuWin32 . Do не установить его по умолчанию (C:\Program Files (x86)\GnuWin32), потому что bison имеет проблемы с пробелами в именах каталогов, а не в скобках.
Также рассмотрите возможность установки Dev-CPP в каталог по умолчанию ( C:\Dev-Cpp )
После этого установите переменную PATH для включения каталогов bin gcc (в C:\Dev-Cpp\bin ) и flex\bison (в C:\GnuWin32\bin ). Для этого скопируйте это: ;C:\Dev-Cpp\bin;C:\GnuWin32\bin и добавьте его в конец переменной PATH , определенную в месте, показанном на этом рисунке:
Если фигура не в хорошем разрешении, вы можете увидеть шаг за шагом здесь.
Откройте приглашение cd в каталог, где ваши ".l" и ".y" есть, и скомпилируйте их с помощью:
- flex hello.l
- bison -dy hello.y
- gcc lex.yy.c y.tab.c -o hello.exe
Вы сможете запустить программу. Я сделал источники для простого теста (печально известный Hello World ):
Hello.l
Hello.y
Отредактировано: избегать "предупреждения: неявное определение yyerror и yylex".
Отказ от ответственности: помните, этот ответ очень старый (с 2011 года!), и если у вас возникают проблемы из-за изменения версий и функций, вам может потребоваться больше исследований, потому что я не могу обновить этот ответ, чтобы отразить новые itens. Спасибо, и я надеюсь, что это будет хорошей отправной точкой для вас, как это было для многих.
Поскольку это неизбежно будет рекомендовано, я предостерег от использования Bison. Bison был первоначально написан Робертом Корбеттом, тем же парнем, который позже написал Byacc, и он открыто заявляет, что в то время он не знал и не понимал, что он делает. К сожалению, будучи молодым и глупым, он выпустил его под GPL, и теперь поклонники GPL подталкивают его как ответ на жизненные проблемы, хотя его собственный автор в основном говорит, что его следует рассматривать как по существу продукт для бета-тестирования, - но из-за запутанных аргументация поклонников GPL, лицензия byacc не имеет достаточных ограничений, чтобы квалифицироваться как "свободные"!
Читайте также: