From e82d62219c661a2594286e0f867354864514bd87 Mon Sep 17 00:00:00 2001 From: Gabriel Dos Reis Date: Sun, 15 Jan 2017 23:47:28 -0800 Subject: Use library parser for bemol. --- src/ChangeLog | 4 ++ src/boot/bemol.cc | 109 +++++++++++++++----------------------------------- src/syntax/Parser.cxx | 43 ++++++++++++++++++++ 3 files changed, 79 insertions(+), 77 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index ac10c246..62acb9ce 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2017-01-15 Gabriel Dos Reis + + * boot/bemol.cc: Use parser from libopen-axiom-core + 2017-01-15 Gabriel Dos Reis * include/open-axiom/token (TokenValue::Indent, diff --git a/src/boot/bemol.cc b/src/boot/bemol.cc index ab50f459..c0020608 100644 --- a/src/boot/bemol.cc +++ b/src/boot/bemol.cc @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2014-2015, Gabriel Dos Reis. +// Copyright (C) 2014-2017, Gabriel Dos Reis. // All rights reserved. // Written by Gabriel Dos Reis. // @@ -34,93 +34,48 @@ // --% Author: Gabriel Dos Reis // --% Description: -#include -#include -#include -#include -#include +#include #include -#include -#include -#include +#include #include - -using namespace OpenAxiom; - -// -// -- Decomposing source files into lexical units of information -- -// - -static std::ostream& -operator<<(std::ostream& os, const Token& t) { - os << t.category << '{' << t.start << '-' << t.end << '}'; - return os; -} - -using TokenSequence = OpenAxiom::TokenStream; - -// -- +#include namespace { - struct Parser { - TokenSequence* tokens; - }; -} + const char* path_basename(const char* begin, const char* end) { + while (end > begin and end[-1] != '/' and end[-1] != '\\') + --end; + return end; + } -// -- + const char* path_type(const char* begin, const char* end) { + while (end > begin and end[-1] != '.') + --end; + return end; + } -static void -translate_source_file(SourceInput& src, std::ostream& out, const char* path) { - while (auto f = src.get()) { - out << "================================================\n"; - out << f; - try { - TokenSequence ts { f, OpenAxiom::Language::Boot }; - for (auto& t : ts) { - out << '\t' << t; - switch (t.category) { - case TokenCategory::Junk: - case TokenCategory::Unclassified: - out //<< f[t.start.line].sub_string(t.start.column, t.end.column) - << " in file " << path - << " at line " << t.start.line - << ", column " << t.start.column; - break; - default: - break; - } - out << '\n'; - } + int process_file(const char* path) { + auto end = path + strlen(path); + if (path == end) { + std::cerr << "error: empty input file path\n"; + return -1; } - catch(const OpenAxiom::EndOfStringUnseen& e) { - std::cerr << path << ": syntax error: " - << "premature end of line before matching quote " - << "of string literal on line " << e.line - << " at column " << e.column - << std::endl; + + auto base = path_basename(path, end); + if (base == end) { + std::cerr << "error: invalid input file path\n"; + return -1; } - catch (const OpenAxiom::MissingExponent& e) { - std::cerr << path << ": syntax error: " - << "missing exponent of floating point constant " - << "on line " << e.line - << ", column " << e.column - << std::endl; + + auto type = path_type(base, end); + if (base == type) { + std::cerr << "error: input file base without basename\n"; + return -1; } - out << "================================================\n"; - } - out << std::flush; -} -static void -process_file(const char* path) { - std::ifstream in { path }; - if (!in) { - std::cerr << "error: could not open file `" << path << "'" - << std::endl; - return; + std::string output { base, type }; + output += "out"; + return OpenAxiom::boot_to_lisp(path, output.c_str()); } - SourceInput src { in }; - translate_source_file(src, std::cout, path); } int main(int argc, char* argv[]) { diff --git a/src/syntax/Parser.cxx b/src/syntax/Parser.cxx index e8759d2b..d78d3157 100644 --- a/src/syntax/Parser.cxx +++ b/src/syntax/Parser.cxx @@ -49,6 +49,46 @@ namespace { using TokenSequence = TokenStream; + struct ParsingContext { + explicit ParsingContext(TokenSequence& ts) + : tokens{ ts }, position{ } + { } + + bool exhausted() const { + return position >= tokens.size(); + } + + const Token* current_token() const { + if (exhausted()) + return nullptr; + return &tokens[position]; + } + + void advance() { ++position; } + + private: + TokenSequence& tokens; + TokenSequence::size_type position; + }; + + const Token* next_token(ParsingContext& ctx) { + while (auto t = ctx.current_token()) { + switch (t->category) { + case TokenCategory::Whitespace: + break; + + case TokenCategory::Comment: + if (t->value == TokenValue::Wisecrack) + break; + + default: + return t; + } + ctx.advance(); + } + return nullptr; + } + // Simple wrapper around standard file streams, along with the pathname // to the file. template @@ -75,6 +115,9 @@ namespace { // FIXME: This is just a stub to get a native parsing entry point // into the bootsys and interpsys images. void transpile_boot_to_lisp(InputFile& in, OutputFile& out) { + out.stream << "## Input: " << in.path << '\n' + << "## Output: " << out.path << '\n'; + SourceInput src { in.stream }; while (auto f = src.get()) { out.stream << "================================================\n"; -- cgit v1.2.3