start with semantics

This commit is contained in:
Wolfgang Thaller 2014-10-06 17:03:25 +02:00
parent cb554ed40f
commit 2b3e533937
5 changed files with 237 additions and 37 deletions

View File

@ -43,6 +43,9 @@ add_executable(Rez
RezLexer.cc RezLexer.cc
RezLexerWaveToken.h RezLexerWaveToken.h
RezLexerNextToken.cc RezLexerNextToken.cc
ResourceDefinitions.cc
ResourceDefinitions.h
) )
target_link_libraries(Rez ${Boost_LIBRARIES}) target_link_libraries(Rez ${Boost_LIBRARIES})

View File

@ -0,0 +1,27 @@
#include "ResourceDefinitions.h"
#include <ostream>
ResourceDefinitions::ResourceDefinitions()
{
}
std::ostream &operator<<(std::ostream &out, ResType t)
{
char c1 = static_cast<char>((int)t >> 24);
char c2 = static_cast<char>((int)t >> 16);
char c3 = static_cast<char>((int)t >> 8);
char c4 = static_cast<char>((int)t);
out << "'" << c1 << c2 << c3 << c4 << "'";
return out;
}
std::ostream &operator<<(std::ostream &out, TypeSpec ts)
{
out << ts.getType();
if(ts.hasID())
out << " (" << ts.getID() << ")";
return out;
}

112
Rez/ResourceDefinitions.h Normal file
View File

@ -0,0 +1,112 @@
#ifndef RESOURCEDEFINITIONS_H
#define RESOURCEDEFINITIONS_H
#include <iosfwd>
#include <memory>
#include <map>
class ResType
{
int x;
public:
ResType() : x(0) {}
ResType(int x) : x(x) {}
operator int() const { return x; }
};
std::ostream& operator<<(std::ostream& out, ResType t);
class TypeSpec
{
ResType type;
int id;
public:
static const int noID = 65536;
TypeSpec() : id(noID) {}
TypeSpec(ResType type) : type(type), id(noID) {}
TypeSpec(ResType type, int id) : type(type), id(id) {}
ResType getType() const { return type; }
int getID() const { return id; }
bool hasID() const { return id != noID; }
};
std::ostream& operator<<(std::ostream& out, TypeSpec ts);
class Context
{
};
class Expression
{
public:
//virtual int evaluateInt(Context *ctx);
};
class StringExpr : public Expression
{
std::string str;
public:
StringExpr(const std::string& str) : str(str) {}
};
class IntExpr : public Expression
{
int val;
public:
IntExpr(int val) : val(val) {}
};
typedef std::shared_ptr<Expression> ExprPtr;
class Field
{
public:
virtual bool needsValue() { return true; }
};
typedef std::shared_ptr<Field> FieldPtr;
class SimpleField : public Field
{
public:
enum class Type
{
boolean, byte, integer, longint, rect, point, char_,
pstring, wstring, string, bitstring
};
enum class Attrs
{
none = 0, hex = 1, key = 2, unsigned_ = 4, literal = 8
};
Type type;
Attrs attrs = Attrs::none;
ExprPtr arrayCount;
ExprPtr value;
std::map<std::string, ExprPtr> namedValues;
void addNamedValue(std::string n) {}
void addNamedValue(std::string n, ExprPtr val) {}
};
typedef std::shared_ptr<SimpleField> SimpleFieldPtr;
inline SimpleField::Attrs operator|(SimpleField::Attrs a, SimpleField::Attrs b)
{
return SimpleField::Attrs( int(a) | int(b) );
}
class ResourceDefinitions
{
public:
ResourceDefinitions();
};
#endif // RESOURCEDEFINITIONS_H

View File

@ -49,6 +49,24 @@ static int readInt(const char *str)
return x; return x;
} }
static int readCharLit(const char *str)
{
const char *p = str + 1;
const char *e = str + strlen(str) - 1;
if(e - p != 4)
std::cout << "warning: CHAR LITERAL " << str << "\n";
int x = 0;
while(p != e)
{
x <<= 8;
x |= (*p) & 0xFF;
++p;
}
return x;
}
RezSymbol RezLexer::nextToken() RezSymbol RezLexer::nextToken()
{ {
for(auto tok = nextWave(); tok != T_EOI && tok != T_EOF; tok = nextWave()) for(auto tok = nextWave(); tok != T_EOI && tok != T_EOF; tok = nextWave())
@ -154,7 +172,7 @@ case T_ ## name: /*std::cout << #name << std::endl;*/ return RezParser::make_ ##
{ {
case T_INTLIT: return RezParser::make_INTLIT(readInt(tok.get_value().c_str()), loc); case T_INTLIT: return RezParser::make_INTLIT(readInt(tok.get_value().c_str()), loc);
case T_CHARLIT: return RezParser::make_CHARLIT(tok.get_value().c_str(), loc); case T_CHARLIT: return RezParser::make_CHARLIT(readCharLit(tok.get_value().c_str()), loc);
case T_STRINGLIT: return RezParser::make_STRINGLIT(tok.get_value().c_str(), loc); case T_STRINGLIT: return RezParser::make_STRINGLIT(tok.get_value().c_str(), loc);
NOVAL_TOK(LEFTBRACE); NOVAL_TOK(LEFTBRACE);

View File

@ -10,7 +10,7 @@
%define parse.assert %define parse.assert
%token<std::string> IDENTIFIER; %token<std::string> IDENTIFIER;
%token<std::string> CHARLIT; %token<int> CHARLIT;
%token<std::string> STRINGLIT; %token<std::string> STRINGLIT;
%token<int> INTLIT; %token<int> INTLIT;
@ -83,6 +83,8 @@
%param { RezLexer& lexer } %param { RezLexer& lexer }
%code requires { %code requires {
#include "ResourceDefinitions.h"
#define YY_NULLPTR nullptr #define YY_NULLPTR nullptr
class RezLexer; class RezLexer;
} }
@ -120,14 +122,6 @@ rez : %empty
| rez resource ";" | rez resource ";"
; ;
simpletype : "boolean"
| "bit" | "byte" | "word" | "integer" | "long" | "longint" | "rect"
| "point"
| "char"
| "pstring" array_count_opt
| "wstring" array_count_opt
| "string" array_count_opt;
| "bitstring" "[" expression "]";
type_definition : "type" type_spec "{" field_definitions "}" type_definition : "type" type_spec "{" field_definitions "}"
{ std::cout << "TYPE " << $2 << std::endl; } { std::cout << "TYPE " << $2 << std::endl; }
@ -135,9 +129,12 @@ type_definition : "type" type_spec "{" field_definitions "}"
{ std::cout << "TYPE " << $2 << std::endl; } { std::cout << "TYPE " << $2 << std::endl; }
; ;
%type <std::string> type_spec; %type <ResType> res_type;
type_spec : CHARLIT { $$ = $1; } res_type : CHARLIT { $$ = ResType($1); } ;
| CHARLIT "(" INTLIT ")" { $$ = $1; }
%type <TypeSpec> type_spec;
type_spec : res_type { $$ = TypeSpec($res_type); }
| res_type "(" INTLIT ")" { $$ = TypeSpec($res_type, $INTLIT); }
; ;
field_definitions : %empty field_definitions : %empty
@ -145,40 +142,78 @@ field_definitions : %empty
| field_definitions ";" | field_definitions ";"
| field_definitions field_definition ";" ; | field_definitions field_definition ";" ;
field_definition: simple_field_definition %type <FieldPtr> field_definition;
field_definition: simple_field_definition { $$ = $1; }
| array_definition | array_definition
| switch_definition | switch_definition
| fill_statement | fill_statement
| align_statement; | align_statement;
%type <SimpleFieldPtr> simple_field_definition;
simple_field_definition: field_attributes simpletype array_count_opt value_spec_opt
{
$$ = std::make_shared<SimpleField>();
$$->attrs = $field_attributes;
$$->type = $simpletype;
$$->arrayCount = $array_count_opt;
$$->value = $value_spec_opt;
}
| simple_field_definition IDENTIFIER
{ $$ = $1; $$->addNamedValue($IDENTIFIER); }
| simple_field_definition IDENTIFIER "=" value
{ $$ = $1; $$->addNamedValue($IDENTIFIER, $value); }
| simple_field_definition "," IDENTIFIER
{ $$ = $1; $$->addNamedValue($IDENTIFIER); }
| simple_field_definition "," IDENTIFIER "=" value
{ $$ = $1; $$->addNamedValue($IDENTIFIER, $value); }
;
%type <ExprPtr> array_count array_count_opt value_spec_opt value ;
%type <ExprPtr> expression expression1 expression2 ;
%type <ExprPtr> expression3 expression4 expression5 expression6;
%type <ExprPtr> expression7 expression8;
value_spec_opt : %empty { $$ = nullptr; } | "=" value { $$ = $2; } ;
%type <SimpleField::Type> simpletype;
simpletype : "boolean" { $$ = SimpleField::Type::boolean; }
| "byte" { $$ = SimpleField::Type::byte; }
| "integer" { $$ = SimpleField::Type::integer; }
| "longint" { $$ = SimpleField::Type::longint; }
| "rect" { $$ = SimpleField::Type::rect; }
| "point" { $$ = SimpleField::Type::point; }
| "char" { $$ = SimpleField::Type::char_; }
| "pstring" { $$ = SimpleField::Type::pstring; }
| "wstring" { $$ = SimpleField::Type::wstring; }
| "string" { $$ = SimpleField::Type::string; }
| "bitstring" { $$ = SimpleField::Type::bitstring; }
;
fill_statement : "fill" fill_unit array_count_opt; fill_statement : "fill" fill_unit array_count_opt;
align_statement : "align" fill_unit; align_statement : "align" fill_unit;
fill_unit : "bit" | "byte" | "word" | "long"; fill_unit : "bit" | "byte" | "word" | "long";
simple_field_definition: field_attributes simpletype value_spec;
value_spec : %empty
| named_values
| "=" expression;
named_values: named_value
| named_values "," named_value
| named_values named_value;
named_value : IDENTIFIER
| IDENTIFIER "=" expression ;
array_definition: array_attributes "array" array_name_opt array_count_opt "{" field_definitions "}" ; array_definition: array_attributes "array" array_name_opt array_count_opt "{" field_definitions "}" ;
array_count : "[" expression "]" ; array_count : "[" expression "]" { $$ = $2; }
array_count_opt : %empty | array_count ; array_count_opt : %empty { $$ = nullptr; } | array_count;
array_name_opt : %empty | IDENTIFIER ; array_name_opt : %empty | IDENTIFIER ;
array_attributes: %empty | "wide" ; array_attributes: %empty | "wide" ;
field_attributes: %empty | field_attributes field_attribute;
field_attribute : "hex" | "key" | "unsigned" | "literal"; %type <SimpleField::Attrs> field_attributes field_attribute;
field_attributes: %empty { $$ = SimpleField::Attrs::none; }
| field_attributes field_attribute { $$ = $1 | $2; }
;
field_attribute : "hex" { $$ = SimpleField::Attrs::hex; }
| "key" { $$ = SimpleField::Attrs::key; }
| "unsigned" { $$ = SimpleField::Attrs::unsigned_; }
| "literal" { $$ = SimpleField::Attrs::literal; }
;
switch_definition: "switch" "{" switch_definition: "switch" "{"
switch_cases switch_cases
@ -206,6 +241,11 @@ expression
; ;
*/ */
value : expression
| "{" resource_body "}"
| STRINGLIT { $$ = std::make_shared<StringExpr>($1); }
;
expression : expression1 expression : expression1
| expression "^" expression1 | expression "^" expression1
; ;
@ -243,20 +283,20 @@ expression7 : expression8
| "~" expression7 | "~" expression7
; ;
expression8 : INTLIT expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
| CHARLIT | CHARLIT { $$ = std::make_shared<IntExpr>($1); }
| STRINGLIT
| IDENTIFIER | IDENTIFIER
| IDENTIFIER "(" function_argument_list ")" | IDENTIFIER "(" function_argument_list ")"
| IDENTIFIER "[" function_argument_list1 "]" | IDENTIFIER "[" function_argument_list1 "]"
| "(" expression ")" | "(" expression ")" { $$ = $2; }
| "{" resource_body "}"
; ;
function_argument_list : %empty | function_argument_list1 ; function_argument_list : %empty | function_argument_list1 ;
function_argument_list1 : expression | function_argument_list "," expression ; function_argument_list1 : expression | function_argument_list "," expression ;
resource: "resource" CHARLIT "(" function_argument_list ")" "{" resource_body "}" resource: "resource" res_type "(" function_argument_list ")" "{" resource_body "}"
{ std::cout << "RESOURCE " << $2 << std::endl; } { std::cout << "RESOURCE " << $2 << std::endl; }
resource_body : %empty | resource_body1 ; resource_body : %empty | resource_body1 ;
@ -266,6 +306,6 @@ resource_body1 : resource_item
| resource_body1 ";" | resource_body1 ";"
; ;
resource_item : expression | IDENTIFIER "{" resource_body "}" ; resource_item : value | IDENTIFIER "{" resource_body "}" ;
%% %%