Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright 2013 Florian Philipp
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- %option header-file="binaries.yy.hpp"
- %option outfile="binaries.yy.cpp"
- %option prefix="bin_"
- %option reentrant noyywrap nodefault
- %option extra-type="bin::scanner_t*"
- %top {
- # include <cstdio>
- # include <vector>
- namespace bin {
- /**
- * Parses the given file as a list of binary numbers or comments with ";"
- * \param input a file opened for reading such as stdout. The read position
- * after the function returns is either EOF or undefined in case of
- * an error
- * \param output a vector to which the binary numbers are appended.
- * \throw std::domain_error in case of a parser failure
- */
- void parse(FILE* input, std::vector<unsigned long>* output);
- class scanner_t;
- }
- }
- %{
- # include <cstdlib>
- # include <sstream>
- # include <stdexcept>
- namespace bin {
- struct scanner_t
- {
- std::vector<unsigned long>* output;
- int line;
- yyscan_t lex;
- scanner_t(std::vector<unsigned long>* output);
- void parse(FILE* input);
- ~scanner_t();
- };
- }
- %}
- %%
- [ \t]+ /* skip whitespace */
- ;.* /* skip comments */
- [01]+ { /* convert binary number */
- yyextra->output->push_back(std::strtoul(yytext, NULL /*end*/, 2 /*base*/));
- }
- \r?\n yyextra->line += 1; /* linebreak */
- . {
- std::ostringstream err;
- err << "Unrecognized character '" << yytext <<"' in line " << yyextra->line;
- throw std::domain_error(err.str());
- }
- <<EOF>> return 0;
- %%
- namespace bin {
- scanner_t::scanner_t(std::vector<unsigned long>* output):
- output(output), line(1)
- {
- bin_lex_init_extra(this, &lex);
- }
- void scanner_t::parse(FILE* input)
- {
- bin_set_in(input, lex);
- bin_lex(lex);
- }
- void parse(FILE* input, std::vector<unsigned long>* output)
- {
- scanner_t scanner(output);
- scanner.parse(input);
- }
- scanner_t::~scanner_t() { yylex_destroy(lex); }
- }
- int main(void)
- {
- std::vector<unsigned long> out;
- try {
- bin::parse(stdin, &out);
- } catch(std::domain_error& err) {
- fprintf(stderr, "Parser error: %s\n", err.what());
- }
- for(std::vector<unsigned long>::iterator i = out.begin(); i != out.end(); ++i)
- std::fprintf(stdout, "%lu\n", *i);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment