Commit c8daa4d8 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

modify the plist parser to emit sexprs instead

parent 811362d9
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "sexpr_parser.h"
#include "sexpr_conv.h"
#include "sexpr_util.h"
#include "plist_parser.h"
#include "typographic_reader.h"

#include "plot/areas.h"
@@ -94,12 +95,14 @@ ReturnCode eval(
ReturnCode eval(
    Context* ctx,
    const std::string& input) {
  ExprStorage expr;
  if (auto rc = expr_parse(input.data(), input.length(), &expr); !rc) {
    return rc;
  ExprStorage plist;

  PropertyListParser parser(input.data(), input.size());
  if (!parser.parse(&plist)) {
    return {ERROR, parser.get_error()};
  }

  return eval(ctx, expr.get());
  return eval(ctx, plist.get());
}

} // namespace clip

src/plist.cc

deleted100644 → 0
+0 −133
Original line number Diff line number Diff line
/**
 * This file is part of the "plotfx" project
 *   Copyright (c) 2018 Paul Asmuth
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * 
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <assert.h>
#include "plist.h"

namespace clip {

const Property& Property::operator[](size_t i) const {
  assert(next);
  assert(i < next->size());
  return (*next)[i];
}

size_t Property::size() const {
  if (next) {
    return next->size();
  } else {
    return 0;
  }
}

Property::operator const std::string&() const {
  return value;
}

bool is_map(const Property& prop) {
  return prop.kind == PropertyKind::MAP;
}

bool is_list(const Property& prop) {
  return prop.kind == PropertyKind::LIST;
}

bool is_tuple(const Property& prop) {
  return prop.kind == PropertyKind::TUPLE;
}

bool is_enum(const Property& prop) {
  return prop.kind == PropertyKind::ENUM;
}

bool is_enum(const Property& prop, const std::string& cmp) {
  return prop.kind == PropertyKind::ENUM && prop.value == cmp;
}

bool is_value(const Property& prop) {
  switch (prop.kind) {
    case PropertyKind::VALUE_LITERAL:
    case PropertyKind::VALUE:
      return true;
    default:
      return false;
  }
}

bool is_value(const Property& prop, const std::string& cmp) {
  switch (prop.kind) {
    case PropertyKind::VALUE_LITERAL:
    case PropertyKind::VALUE:
      break;
    default:
      return false;
  }

  return prop.value == cmp;
}

bool is_value_literal(const Property& prop) {
  return prop.kind == PropertyKind::VALUE_LITERAL;
}

bool is_value_literal(const Property& prop, const std::string& cmp) {
  return prop.kind == PropertyKind::VALUE_LITERAL && prop.value == cmp;
}

bool is_value_quoted(const Property& prop) {
  return prop.kind == PropertyKind::VALUE;
}

bool is_value_quoted(const Property& prop, const std::string& cmp) {
  return prop.kind == PropertyKind::VALUE && prop.value == cmp;
}

std::vector<std::string> flatten(const Property& prop) {
  switch (prop.kind) {
    case PropertyKind::VALUE_LITERAL:
    case PropertyKind::VALUE:
      return {prop.value};
    case PropertyKind::TUPLE:
    case PropertyKind::LIST:
      break;
    default:
      return {};
  }

  std::vector<std::string> flat;
  for (const auto& n : *prop.next) {
    auto next = flatten(n);
    flat.insert(flat.end(), next.begin(), next.end());
  }

  return flat;
}

} // namespace clip

src/plist.h

deleted100644 → 0
+0 −72
Original line number Diff line number Diff line
/**
 * This file is part of the "plotfx" project
 *   Copyright (c) 2018 Paul Asmuth
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * 
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once
#include <memory>
#include <string>
#include <vector>

namespace clip {
struct Property;

using PropertyList = std::vector<Property>;

enum class PropertyKind {
  MAP, TUPLE, LIST, ENUM, VALUE, VALUE_LITERAL
};

struct Property {
  std::string name;
  PropertyKind kind;
  std::unique_ptr<std::vector<Property>> next;
  std::string value;

  const Property& operator[](size_t i) const;
  size_t size() const;

  operator const std::string&() const;

};

bool is_map(const Property& prop);
bool is_list(const Property& prop);
bool is_tuple(const Property& prop);
bool is_enum(const Property& prop);
bool is_enum(const Property& prop, const std::string& cmp);
bool is_value(const Property& prop);
bool is_value(const Property& prop, const std::string& cmp);
bool is_value_literal(const Property& prop);
bool is_value_literal(const Property& prop, const std::string& cmp);
bool is_value_quoted(const Property& prop);
bool is_value_quoted(const Property& prop, const std::string& cmp);

std::vector<std::string> flatten(const Property& prop);

} // namespace clip
+33 −99
Original line number Diff line number Diff line
@@ -49,11 +49,11 @@ const std::string& PropertyListParser::get_error() const {
  return error_msg_;
}

bool PropertyListParser::parse(PropertyList* plist) {
bool PropertyListParser::parse(ExprStorage* plist) {
  TokenType ttype;
  std::string tbuf;
  while (getToken(&ttype, &tbuf)) {
    if (!parsePropertyOrMap(plist)) {
  for (auto tail = plist; getToken(&ttype, &tbuf); tail = expr_get_next_storage(&**tail)) {
    if (!parsePropertyOrMap(tail)) {
      return false;
    }
  }
@@ -61,7 +61,7 @@ bool PropertyListParser::parse(PropertyList* plist) {
  return true;
}

bool PropertyListParser::parsePropertyOrMap(PropertyList* plist) {
bool PropertyListParser::parsePropertyOrMap(ExprStorage* plist) {
  std::string pname;
  if (!expectAndConsumeString(&pname)) {
    return false;
@@ -94,127 +94,66 @@ bool PropertyListParser::parsePropertyOrMap(PropertyList* plist) {
              printToken(ttype, tbuf)));
      return false;
  }
}

bool PropertyListParser::parseProperty(const std::string& pname, PropertyList* plist) {
  Property prop;
  prop.name = pname;

  PropertyList args;
  if (!parsePropertyListOrTuple(&args)) {
    return false;
  }

  if (args.size() == 1) {
    prop.kind = args[0].kind;
    prop.value = args[0].value;
    prop.next = std::move(args[0].next);
  } else {
    prop.kind = PropertyKind::LIST;
    prop.next = std::make_unique<PropertyList>(std::move(args));
  }

  plist->emplace_back(std::move(prop));
  return true;
}

bool PropertyListParser::parsePropertyListOrTuple(PropertyList* plist) {
  TokenType ttype;
  std::string tbuf;
  while (getToken(&ttype, &tbuf) && ttype != T_SEMICOLON) {
    Property prop;
    if (!parsePropertyTupleOrValue(&prop)) {
      return false;
    }

    plist->emplace_back(std::move(prop));
bool PropertyListParser::parseProperty(const std::string& pname, ExprStorage* plist) {
  auto args = expr_create_value_literal(pname);

    if (!getToken(&ttype, &tbuf)) {
  if (!parsePropertyValues(expr_get_next_storage(args.get()))) {
    return false;
  }

    switch (ttype) {
      case T_SEMICOLON:
        return true;

      case T_RPAREN:
        return true;

      case T_COMMA:
        consumeToken();
        continue;

      default:
        setError(
            fmt::format(
                "unexpected token '{}'; expected SEMICOLON OR COMMA",
                printToken(ttype, tbuf)));
        return false;
    }
  }

  *plist = expr_create_list(std::move(args));
  return true;
}

bool PropertyListParser::parsePropertyTupleOrValue(Property* prop) {
  PropertyList args;
  if (!parsePropertyTuple(&args)) {
    return false;
  }
bool PropertyListParser::parsePropertyValues(ExprStorage* plist) {
  auto tail = plist;

  if (args.size() == 1) {
    prop->kind = args[0].kind;
    prop->value = args[0].value;
    prop->next = std::move(args[0].next);
  } else {
    prop->kind = PropertyKind::TUPLE;
    prop->next = std::make_unique<PropertyList>(std::move(args));
  }

  return true;
}

bool PropertyListParser::parsePropertyTuple(PropertyList* plist) {
  TokenType ttype;
  std::string tbuf;
  while (getToken(&ttype, &tbuf) && ttype != T_SEMICOLON) {
    switch (ttype) {
      case T_STRING_QUOTED:
      case T_STRING: {
        Property prop;
        if (!parsePropertyValueOrEnum(&prop)) {
        if (!parsePropertyValueOrEnum(tail)) {
          return false;
        }

        plist->emplace_back(std::move(prop));
        tail = expr_get_next_storage(tail->get());
        break;
      }

      case T_SEMICOLON:
        return true;

      case T_RPAREN:
        return true;

      case T_COMMA:
        return true;
        consumeToken();
        continue;

      default:
        setError(
            fmt::format(
                "unexpected token '{}'; expected STRING",
                "unexpected token '{}'; expected SEMICOLON OR COMMA",
                printToken(ttype, tbuf)));
        return false;
    }

  }

  return true;
}

bool PropertyListParser::parsePropertyValueOrEnum(Property* prop) {
bool PropertyListParser::parsePropertyValueOrEnum(ExprStorage* prop) {
  if (!parsePropertyValue(prop)) {
    return false;
  }

  if (prop->kind != PropertyKind::VALUE_LITERAL) {
  if (!expr_is_value_literal(prop->get())) {
    return true;
  }

@@ -224,21 +163,19 @@ bool PropertyListParser::parsePropertyValueOrEnum(Property* prop) {
    return true;
  }

  prop->kind = PropertyKind::ENUM;
  prop->next = std::make_unique<PropertyList>();

  expectAndConsumeToken(T_LPAREN);

  if (!parsePropertyListOrTuple(prop->next.get())) {
  if (!parsePropertyValues(expr_get_next_storage(prop->get()))) {
    return false;
  }

  expectAndConsumeToken(T_RPAREN);

  *prop = expr_create_list(std::move(*prop));
  return true;
}

bool PropertyListParser::parsePropertyValue(Property* prop) {
bool PropertyListParser::parsePropertyValue(ExprStorage* prop) {
  TokenType ttype;
  std::string tbuf;
  if (!getToken(&ttype, &tbuf)) {
@@ -247,13 +184,11 @@ bool PropertyListParser::parsePropertyValue(Property* prop) {

  switch (ttype) {
    case T_STRING_QUOTED:
      prop->kind = PropertyKind::VALUE;
      prop->value = tbuf;
      *prop = expr_create_value(tbuf);
      consumeToken();
      break;
    case T_STRING:
      prop->kind = PropertyKind::VALUE_LITERAL;
      prop->value = tbuf;
      *prop = expr_create_value_literal(tbuf);
      consumeToken();
      break;
    default:
@@ -264,25 +199,24 @@ bool PropertyListParser::parsePropertyValue(Property* prop) {
      return false;
  }


  return true;
}

bool PropertyListParser::parsePropertyMap(const std::string& pname, PropertyList* plist) {
  Property prop;
  prop.name = pname;
  prop.kind = PropertyKind::MAP;
  prop.next = std::make_unique<PropertyList>();
bool PropertyListParser::parsePropertyMap(const std::string& pname, ExprStorage* plist) {
  auto args = expr_create_value_literal(pname);
  auto tail = expr_get_next_storage(args.get());

  TokenType ttype;
  std::string tbuf;
  while (getToken(&ttype, &tbuf) && ttype != T_RCBRACE) {
    if (!parsePropertyOrMap(prop.next.get())) {
    if (!parsePropertyOrMap(tail)) {
      return false;
    }

    tail = expr_get_next_storage(tail->get());
  }

  plist->emplace_back(std::move(prop));
  *plist = expr_create_list(std::move(args));
  return true;
}

+9 −11
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
#include <atomic>
#include <memory>
#include <string>
#include "plist.h"
#include "sexpr.h"

namespace clip {

@@ -42,7 +42,7 @@ public:
      const char* input,
      size_t input_len);

  bool parse(PropertyList* plist);
  bool parse(ExprStorage* plist);

  const std::string& get_error() const;

@@ -68,15 +68,13 @@ protected:

  bool consumeToken();

  bool parsePropertyOrMap(PropertyList* plist);
  bool parseProperty(const std::string& pname, PropertyList* plist);
  bool parsePropertyListOrTuple(PropertyList* plist);
  bool parsePropertyTupleOrValue(Property* prop);
  bool parsePropertyTuple(PropertyList* plist);
  bool parsePropertyValueOrEnum(Property* prop);
  bool parsePropertyEnum(Property* prop);
  bool parsePropertyValue(Property* prop);
  bool parsePropertyMap(const std::string& pname, PropertyList* plist);
  bool parsePropertyOrMap(ExprStorage* plist);
  bool parseProperty(const std::string& pname, ExprStorage* plist);
  bool parsePropertyValues(ExprStorage* plist);
  bool parsePropertyValueOrEnum(ExprStorage* prop);
  bool parsePropertyValue(ExprStorage* prop);
  bool parsePropertyEnum(ExprStorage* prop);
  bool parsePropertyMap(const std::string& pname, ExprStorage* plist);

  bool getToken(
      TokenType* type,