summaryrefslogtreecommitdiff
path: root/cpp/src/FreezeScript/Grammar.y
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/FreezeScript/Grammar.y')
-rw-r--r--cpp/src/FreezeScript/Grammar.y320
1 files changed, 320 insertions, 0 deletions
diff --git a/cpp/src/FreezeScript/Grammar.y b/cpp/src/FreezeScript/Grammar.y
new file mode 100644
index 00000000000..225be134a29
--- /dev/null
+++ b/cpp/src/FreezeScript/Grammar.y
@@ -0,0 +1,320 @@
+%{
+
+// **********************************************************************
+//
+// Copyright (c) 2004
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#include <FreezeScript/GrammarUtil.h>
+
+#ifdef _WIN32
+// I get these warnings from some bison versions:
+// warning C4102: 'yyoverflowlab' : unreferenced label
+# pragma warning( disable : 4102 )
+// warning C4065: switch statement contains 'default' but no 'case' labels
+# pragma warning( disable : 4065 )
+#endif
+
+using namespace std;
+using namespace FreezeScript;
+
+void
+freeze_script_error(const char* s)
+{
+ // yacc and recent versions of Bison use "syntax error" instead
+ // of "parse error".
+
+ if(strcmp(s, "parse error") == 0)
+ {
+ parseErrorReporter->expressionSyntaxError("syntax error");
+ }
+ else
+ {
+ parseErrorReporter->expressionSyntaxError(s);
+ }
+}
+
+%}
+
+%pure_parser
+%name_prefix="freeze_script_"
+
+%token TOK_AND
+%token TOK_OR
+%token TOK_NOT
+%token TOK_ADD
+%token TOK_SUB
+%token TOK_MUL
+%token TOK_DIV
+%token TOK_MOD
+%token TOK_LPAREN
+%token TOK_RPAREN
+%token TOK_LBRACKET
+%token TOK_RBRACKET
+%token TOK_LESS_THAN
+%token TOK_GREATER_THAN
+%token TOK_LESS_EQUAL
+%token TOK_GREATER_EQUAL
+%token TOK_EQUAL
+%token TOK_NEQ
+%token TOK_TRUE
+%token TOK_FALSE
+%token TOK_NIL
+%token TOK_SCOPE_DELIMITER
+%token TOK_IDENTIFIER
+%token TOK_STRING_LITERAL
+%token TOK_INTEGER_LITERAL
+%token TOK_FLOATING_POINT_LITERAL
+
+%left TOK_OR
+%left TOK_AND
+%nonassoc TOK_LESS_THAN TOK_GREATER_THAN TOK_LESS_EQUAL TOK_GREATER_EQUAL TOK_EQUAL TOK_NEQ
+%left TOK_ADD TOK_SUB
+%left TOK_MUL TOK_DIV TOK_MOD
+%right UNARY_OP
+
+%%
+
+// ----------------------------------------------------------------------
+start
+// ----------------------------------------------------------------------
+: expr
+{
+ parseResult = $1;
+}
+;
+
+// ----------------------------------------------------------------------
+expr
+// ----------------------------------------------------------------------
+: binary
+{
+ $$ = $1;
+}
+;
+
+// ----------------------------------------------------------------------
+binary
+// ----------------------------------------------------------------------
+: binary TOK_LESS_THAN binary
+{
+ $$ = new BinaryNode(BinOpLess, parseDataFactory, $1, $3);
+}
+| binary TOK_GREATER_THAN binary
+{
+ $$ = new BinaryNode(BinOpGreater, parseDataFactory, $1, $3);
+}
+| binary TOK_LESS_EQUAL binary
+{
+ $$ = new BinaryNode(BinOpLessEq, parseDataFactory, $1, $3);
+}
+| binary TOK_GREATER_EQUAL binary
+{
+ $$ = new BinaryNode(BinOpGrEq, parseDataFactory, $1, $3);
+}
+| binary TOK_EQUAL binary
+{
+ $$ = new BinaryNode(BinOpEq, parseDataFactory, $1, $3);
+}
+| binary TOK_NEQ binary
+{
+ $$ = new BinaryNode(BinOpNotEq, parseDataFactory, $1, $3);
+}
+| binary TOK_OR binary
+{
+ $$ = new BinaryNode(BinOpOr, parseDataFactory, $1, $3);
+}
+| binary TOK_AND binary
+{
+ $$ = new BinaryNode(BinOpAnd, parseDataFactory, $1, $3);
+}
+| binary TOK_MUL binary
+{
+ $$ = new BinaryNode(BinOpMul, parseDataFactory, $1, $3);
+}
+| binary TOK_DIV binary
+{
+ $$ = new BinaryNode(BinOpDiv, parseDataFactory, $1, $3);
+}
+| binary TOK_MOD binary
+{
+ $$ = new BinaryNode(BinOpMod, parseDataFactory, $1, $3);
+}
+| binary TOK_ADD binary
+{
+ $$ = new BinaryNode(BinOpAdd, parseDataFactory, $1, $3);
+}
+| binary TOK_SUB binary
+{
+ $$ = new BinaryNode(BinOpSub, parseDataFactory, $1, $3);
+}
+| unary
+{
+ $$ = $1;
+}
+;
+
+// ----------------------------------------------------------------------
+unary
+// ----------------------------------------------------------------------
+: TOK_LPAREN expr TOK_RPAREN
+{
+ $$ = $2;
+}
+| TOK_SUB unary %prec UNARY_OP
+{
+ $$ = new UnaryNode(UnaryOpNeg, parseDataFactory, $2);
+}
+| TOK_NOT unary %prec UNARY_OP
+{
+ $$ = new UnaryNode(UnaryOpNot, parseDataFactory, $2);
+}
+| TOK_INTEGER_LITERAL
+{
+ IntegerTokPtr intVal = IntegerTokPtr::dynamicCast($1);
+ assert(intVal);
+ $$ = new DataNode(parseDataFactory->createInteger(intVal->v, true));
+}
+| TOK_FLOATING_POINT_LITERAL
+{
+ FloatingTokPtr floatVal = FloatingTokPtr::dynamicCast($1);
+ assert(floatVal);
+ $$ = new DataNode(parseDataFactory->createDouble(floatVal->v, true));
+}
+| TOK_STRING_LITERAL
+{
+ StringTokPtr stringVal = StringTokPtr::dynamicCast($1);
+ assert(stringVal);
+ $$ = new DataNode(parseDataFactory->createString(stringVal->v, true));
+}
+| TOK_TRUE
+{
+ $$ = new DataNode(parseDataFactory->createBoolean(true, true));
+}
+| TOK_FALSE
+{
+ $$ = new DataNode(parseDataFactory->createBoolean(false, true));
+}
+| TOK_NIL
+{
+ $$ = new DataNode(parseDataFactory->createNil(true));
+}
+| entity
+{
+ $$ = $1;
+}
+| entity '.' function
+{
+ EntityNodePtr entity = EntityNodePtr::dynamicCast($1);
+ assert(entity);
+ FunctionNodePtr func = FunctionNodePtr::dynamicCast($3);
+ assert(func);
+ func->setTarget(entity);
+ $$ = $3;
+}
+| function
+{
+ $$ = $1;
+}
+| constant
+{
+ StringTokPtr stringVal = StringTokPtr::dynamicCast($1);
+ assert(stringVal);
+ $$ = new ConstantNode(stringVal->v);
+}
+;
+
+// ----------------------------------------------------------------------
+entity
+// ----------------------------------------------------------------------
+: entity TOK_LBRACKET expr TOK_RBRACKET
+{
+ EntityNodePtr entity = EntityNodePtr::dynamicCast($1);
+ assert(entity);
+ entity->append(new ElementNode($3));
+ $$ = $1;
+}
+| entity '.' TOK_IDENTIFIER
+{
+ StringTokPtr stringVal = StringTokPtr::dynamicCast($3);
+ assert(stringVal);
+ EntityNodePtr entity = EntityNodePtr::dynamicCast($1);
+ assert(entity);
+ entity->append(new IdentNode(stringVal->v));
+ $$ = $1;
+}
+| TOK_IDENTIFIER
+{
+ StringTokPtr stringVal = StringTokPtr::dynamicCast($1);
+ assert(stringVal);
+ $$ = new IdentNode(stringVal->v);
+}
+;
+
+// ----------------------------------------------------------------------
+function
+// ----------------------------------------------------------------------
+: TOK_IDENTIFIER TOK_LPAREN arg_list TOK_RPAREN
+{
+ StringTokPtr func = StringTokPtr::dynamicCast($1);
+ assert(func);
+ NodeListTokPtr args = NodeListTokPtr::dynamicCast($3);
+ assert(args);
+ $$ = new FunctionNode(func->v, args->v);
+}
+;
+
+// ----------------------------------------------------------------------
+arg_list
+// ----------------------------------------------------------------------
+: arg_list ',' expr
+{
+ NodeListTokPtr l = NodeListTokPtr::dynamicCast($1);
+ assert(l);
+ l->v.push_back($3);
+ $$ = $1;
+}
+| expr
+{
+ NodeListTokPtr result = new NodeListTok;
+ result->v.push_back($1);
+ $$ = result;
+}
+|
+{
+ $$ = new NodeListTok;
+}
+;
+
+// ----------------------------------------------------------------------
+constant
+// ----------------------------------------------------------------------
+: constant TOK_SCOPE_DELIMITER TOK_IDENTIFIER
+{
+ StringTokPtr stringVal = StringTokPtr::dynamicCast($1);
+ assert(stringVal);
+ StringTokPtr idVal = StringTokPtr::dynamicCast($3);
+ assert(idVal);
+ stringVal->v.append("::" + idVal->v);
+ $$ = $1;
+}
+| TOK_SCOPE_DELIMITER TOK_IDENTIFIER
+{
+ StringTokPtr idVal = StringTokPtr::dynamicCast($2);
+ assert(idVal);
+ StringTokPtr stringVal = new StringTok;
+ stringVal->v.append("::" + idVal->v);
+ $$ = stringVal;
+}
+;
+
+%%