Implement tuple declarations for Imperative syntax

This commit is contained in:
IRBorisov 2024-05-13 11:47:08 +03:00
parent f991763bb7
commit 28e24462f6
37 changed files with 1512 additions and 1020 deletions

View File

@ -398,15 +398,15 @@ void OpRelativation::ModifyExpressions() {
termID, // 1 termID, // 1
baseName, // 2 baseName, // 2
updated, // 3 updated, // 3
Token::Str(TokenID::PUNC_ITERATE), // 4 Token::Str(TokenID::ITERATE), // 4
Token::Str(TokenID::PUNC_ASSIGN)); // 5 Token::Str(TokenID::ASSIGN)); // 5
#else #else
std::string newExpression = "I{("; std::string newExpression = "I{(";
newExpression += baseID + ", " + termID; newExpression += baseID + ", " + termID;
newExpression += ") | "; newExpression += ") | ";
newExpression += baseID + Token::Str(TokenID::PUNC_ITERATE) + baseName; newExpression += baseID + Token::Str(TokenID::ITERATE) + baseName;
newExpression += "; "; newExpression += "; ";
newExpression += termID + Token::Str(TokenID::PUNC_ASSIGN) + updated + "}"; newExpression += termID + Token::Str(TokenID::ASSIGN) + updated + "}";
#endif #endif
resultSchema->SetExpressionFor(entity, newExpression); resultSchema->SetExpressionFor(entity, newExpression);
break; break;

View File

@ -10,14 +10,14 @@ class Normalizer {
public: public:
using TupleSubstitutes = std::unordered_map<std::string, std::vector<Index>>; using TupleSubstitutes = std::unordered_map<std::string, std::vector<Index>>;
using NodeSubstitutes = std::unordered_map<std::string, const SyntaxTree::Node*>; using NodeSubstitutes = std::unordered_map<std::string, const SyntaxTree::Node*>;
using NameSubstitutes = std::unordered_map<std::string, std::string>;
private: private:
SyntaxTreeContext termFuncs; SyntaxTreeContext termFuncs;
TupleSubstitutes tuples{}; TupleSubstitutes tupleSubstitutes{};
NodeSubstitutes nodes{}; NodeSubstitutes nodeSubstitutes{};
NameSubstitutes nameSubstitutes{};
std::unordered_map<std::string, std::string> nameSubstitutes{};
uint32_t localVarBase{ 0 }; uint32_t localVarBase{ 0 };
public: public:
@ -29,14 +29,17 @@ public:
private: private:
void Quantifier(SyntaxTree::Node& quant); void Quantifier(SyntaxTree::Node& quant);
void Imperative(SyntaxTree::Node& root);
void Recursion(SyntaxTree::Node& root);
void Declarative(SyntaxTree::Node& root);
void Function(SyntaxTree::Node& func);
static void EnumDeclaration(SyntaxTree::Node& quant); static void EnumDeclaration(SyntaxTree::Node& quant);
void TupleDeclaration(SyntaxTree::Node& declaration, SyntaxTree::Node& predicate); void TupleDeclaration(SyntaxTree::Node& declaration, SyntaxTree::Node& predicate);
void TupleDeclaration(SyntaxTree::Node& target);
[[nodiscard]] std::string CreateTupleName(const SyntaxTree::Node& root); [[nodiscard]] std::string ProcessTupleDeclaration(SyntaxTree::Node& root);
void SubstituteTupleVariables(SyntaxTree::Node& target, const std::string& newName); void SubstituteTupleVariables(SyntaxTree::Node& target, const std::string& newName);
void Function(SyntaxTree::Node& func);
[[nodiscard]] static std::vector<std::string> ArgNames(const SyntaxTree::Node& declaration); [[nodiscard]] static std::vector<std::string> ArgNames(const SyntaxTree::Node& declaration);
void SubstituteArgs(SyntaxTree::Node& target, StrRange pos); void SubstituteArgs(SyntaxTree::Node& target, StrRange pos);
}; };

View File

@ -1,6 +1,6 @@
// AsciiLexerImpl.hpp generated by reflex 4.2.0 from AsciiLexerImpl.l // AsciiLexerImpl.hpp generated by reflex 4.2.1 from AsciiLexerImpl.l
#define REFLEX_VERSION "4.2.0" #define REFLEX_VERSION "4.2.1"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// // // //
@ -76,8 +76,10 @@ class AsciiLexerImpl : public reflex::AbstractLexer<reflex::Matcher> {
public: public:
[[nodiscard]] StrRange Range() const { [[nodiscard]] StrRange Range() const {
// Note: returning byte position, not code point! Assume input is ASCII // Note: returning byte position, not code point! Assume input is ASCII
return StrRange{ static_cast<StrPos>(matcher().first()), return StrRange{
static_cast<StrPos>(matcher().last()) }; static_cast<StrPos>(matcher().first()),
static_cast<StrPos>(matcher().last())
};
} }
public: public:
@ -152,196 +154,196 @@ ccl::rslang::TokenID ccl::rslang::detail::asciilex::AsciiLexerImpl::lex(void)
return ccl::rslang::TokenID(); return ccl::rslang::TokenID();
} }
break; break;
case 1: // rule AsciiLexerImpl.l:45: "\A" : case 1: // rule AsciiLexerImpl.l:47: "\A" :
{ return TokenID::FORALL; } { return TokenID::FORALL; }
break; break;
case 2: // rule AsciiLexerImpl.l:46: "\E" : case 2: // rule AsciiLexerImpl.l:48: "\E" :
{ return TokenID::EXISTS; } { return TokenID::EXISTS; }
break; break;
case 3: // rule AsciiLexerImpl.l:48: "\neg" : case 3: // rule AsciiLexerImpl.l:50: "\neg" :
{ return TokenID::NOT; } { return TokenID::NOT; }
break; break;
case 4: // rule AsciiLexerImpl.l:49: "\and" : case 4: // rule AsciiLexerImpl.l:51: "\and" :
{ return TokenID::AND; } { return TokenID::AND; }
break; break;
case 5: // rule AsciiLexerImpl.l:50: "\or" : case 5: // rule AsciiLexerImpl.l:52: "\or" :
{ return TokenID::OR; } { return TokenID::OR; }
break; break;
case 6: // rule AsciiLexerImpl.l:51: "\impl" : case 6: // rule AsciiLexerImpl.l:53: "\impl" :
{ return TokenID::IMPLICATION; } { return TokenID::IMPLICATION; }
break; break;
case 7: // rule AsciiLexerImpl.l:52: "\equiv" : case 7: // rule AsciiLexerImpl.l:54: "\equiv" :
{ return TokenID::EQUIVALENT; } { return TokenID::EQUIVALENT; }
break; break;
case 8: // rule AsciiLexerImpl.l:54: "\plus" : case 8: // rule AsciiLexerImpl.l:56: "\plus" :
{ return TokenID::PLUS; } { return TokenID::PLUS; }
break; break;
case 9: // rule AsciiLexerImpl.l:55: "\minus" : case 9: // rule AsciiLexerImpl.l:57: "\minus" :
{ return TokenID::MINUS; } { return TokenID::MINUS; }
break; break;
case 10: // rule AsciiLexerImpl.l:56: "\multiply" : case 10: // rule AsciiLexerImpl.l:58: "\multiply" :
{ return TokenID::MULTIPLY; } { return TokenID::MULTIPLY; }
break; break;
case 11: // rule AsciiLexerImpl.l:57: "\gr" : case 11: // rule AsciiLexerImpl.l:59: "\gr" :
{ return TokenID::GREATER; } { return TokenID::GREATER; }
break; break;
case 12: // rule AsciiLexerImpl.l:58: "\ls" : case 12: // rule AsciiLexerImpl.l:60: "\ls" :
{ return TokenID::LESSER; } { return TokenID::LESSER; }
break; break;
case 13: // rule AsciiLexerImpl.l:59: "\ge" : case 13: // rule AsciiLexerImpl.l:61: "\ge" :
{ return TokenID::GREATER_OR_EQ; } { return TokenID::GREATER_OR_EQ; }
break; break;
case 14: // rule AsciiLexerImpl.l:60: "\le" : case 14: // rule AsciiLexerImpl.l:62: "\le" :
{ return TokenID::LESSER_OR_EQ; } { return TokenID::LESSER_OR_EQ; }
break; break;
case 15: // rule AsciiLexerImpl.l:62: "\eq" : case 15: // rule AsciiLexerImpl.l:64: "\eq" :
{ return TokenID::EQUAL; } { return TokenID::EQUAL; }
break; break;
case 16: // rule AsciiLexerImpl.l:63: "\noteq" : case 16: // rule AsciiLexerImpl.l:65: "\noteq" :
{ return TokenID::NOTEQUAL; } { return TokenID::NOTEQUAL; }
break; break;
case 17: // rule AsciiLexerImpl.l:65: "\in" : case 17: // rule AsciiLexerImpl.l:67: "\in" :
{ return TokenID::IN; } { return TokenID::IN; }
break; break;
case 18: // rule AsciiLexerImpl.l:66: "\notin" : case 18: // rule AsciiLexerImpl.l:68: "\notin" :
{ return TokenID::NOTIN; } { return TokenID::NOTIN; }
break; break;
case 19: // rule AsciiLexerImpl.l:67: "\subseteq" : case 19: // rule AsciiLexerImpl.l:69: "\subseteq" :
{ return TokenID::SUBSET_OR_EQ; } { return TokenID::SUBSET_OR_EQ; }
break; break;
case 20: // rule AsciiLexerImpl.l:68: "\subset" : case 20: // rule AsciiLexerImpl.l:70: "\subset" :
{ return TokenID::SUBSET; } { return TokenID::SUBSET; }
break; break;
case 21: // rule AsciiLexerImpl.l:69: "\notsubset" : case 21: // rule AsciiLexerImpl.l:71: "\notsubset" :
{ return TokenID::NOTSUBSET; } { return TokenID::NOTSUBSET; }
break; break;
case 22: // rule AsciiLexerImpl.l:71: "*" : case 22: // rule AsciiLexerImpl.l:73: "*" :
{ return TokenID::DECART; } { return TokenID::DECART; }
break; break;
case 23: // rule AsciiLexerImpl.l:72: "\union" : case 23: // rule AsciiLexerImpl.l:74: "\union" :
{ return TokenID::UNION; } { return TokenID::UNION; }
break; break;
case 24: // rule AsciiLexerImpl.l:73: "\intersect" : case 24: // rule AsciiLexerImpl.l:75: "\intersect" :
{ return TokenID::INTERSECTION; } { return TokenID::INTERSECTION; }
break; break;
case 25: // rule AsciiLexerImpl.l:74: "\setminus" : case 25: // rule AsciiLexerImpl.l:76: "\setminus" :
{ return TokenID::SET_MINUS; } { return TokenID::SET_MINUS; }
break; break;
case 26: // rule AsciiLexerImpl.l:75: "\symmdiff" : case 26: // rule AsciiLexerImpl.l:77: "\symmdiff" :
{ return TokenID::SYMMINUS; } { return TokenID::SYMMINUS; }
break; break;
case 27: // rule AsciiLexerImpl.l:76: "B" : case 27: // rule AsciiLexerImpl.l:78: "B" :
{ return TokenID::BOOLEAN; } { return TokenID::BOOLEAN; }
break; break;
case 28: // rule AsciiLexerImpl.l:78: pr{index} : case 28: // rule AsciiLexerImpl.l:80: pr{index} :
{ return TokenID::SMALLPR; } { return TokenID::SMALLPR; }
break; break;
case 29: // rule AsciiLexerImpl.l:79: Pr{index} : case 29: // rule AsciiLexerImpl.l:81: Pr{index} :
{ return TokenID::BIGPR; } { return TokenID::BIGPR; }
break; break;
case 30: // rule AsciiLexerImpl.l:80: Fi{index} : case 30: // rule AsciiLexerImpl.l:82: Fi{index} :
{ return TokenID::FILTER; } { return TokenID::FILTER; }
break; break;
case 31: // rule AsciiLexerImpl.l:81: card : case 31: // rule AsciiLexerImpl.l:83: card :
{ return TokenID::CARD; } { return TokenID::CARD; }
break; break;
case 32: // rule AsciiLexerImpl.l:82: bool : case 32: // rule AsciiLexerImpl.l:84: bool :
{ return TokenID::BOOL; } { return TokenID::BOOL; }
break; break;
case 33: // rule AsciiLexerImpl.l:83: red : case 33: // rule AsciiLexerImpl.l:85: red :
{ return TokenID::REDUCE; } { return TokenID::REDUCE; }
break; break;
case 34: // rule AsciiLexerImpl.l:84: debool : case 34: // rule AsciiLexerImpl.l:86: debool :
{ return TokenID::DEBOOL; } { return TokenID::DEBOOL; }
break; break;
case 35: // rule AsciiLexerImpl.l:86: D : case 35: // rule AsciiLexerImpl.l:88: D :
{ return TokenID::DECLARATIVE; } { return TokenID::DECLARATIVE; }
break; break;
case 36: // rule AsciiLexerImpl.l:87: R : case 36: // rule AsciiLexerImpl.l:89: R :
{ return TokenID::RECURSIVE; } { return TokenID::RECURSIVE; }
break; break;
case 37: // rule AsciiLexerImpl.l:88: I : case 37: // rule AsciiLexerImpl.l:90: I :
{ return TokenID::IMPERATIVE; } { return TokenID::IMPERATIVE; }
break; break;
case 38: // rule AsciiLexerImpl.l:90: Z : case 38: // rule AsciiLexerImpl.l:92: Z :
{ return TokenID::LIT_INTSET; } { return TokenID::LIT_INTSET; }
break; break;
case 39: // rule AsciiLexerImpl.l:91: "{}" : case 39: // rule AsciiLexerImpl.l:93: "{}" :
{ return TokenID::LIT_EMPTYSET; } { return TokenID::LIT_EMPTYSET; }
break; break;
case 40: // rule AsciiLexerImpl.l:92: {number} : case 40: // rule AsciiLexerImpl.l:94: {number} :
{ return TokenID::LIT_INTEGER; } { return TokenID::LIT_INTEGER; }
break; break;
case 41: // rule AsciiLexerImpl.l:94: F{number} : case 41: // rule AsciiLexerImpl.l:96: F{number} :
{ return TokenID::ID_FUNCTION; } { return TokenID::ID_FUNCTION; }
break; break;
case 42: // rule AsciiLexerImpl.l:95: P{number} : case 42: // rule AsciiLexerImpl.l:97: P{number} :
{ return TokenID::ID_PREDICATE; } { return TokenID::ID_PREDICATE; }
break; break;
case 43: // rule AsciiLexerImpl.l:96: R{number} : case 43: // rule AsciiLexerImpl.l:98: R{number} :
{ return TokenID::ID_RADICAL; } { return TokenID::ID_RADICAL; }
break; break;
case 44: // rule AsciiLexerImpl.l:98: {global_id} : case 44: // rule AsciiLexerImpl.l:100: {global_id} :
{ return TokenID::ID_GLOBAL; } { return TokenID::ID_GLOBAL; }
break; break;
case 45: // rule AsciiLexerImpl.l:99: {local_id} : case 45: // rule AsciiLexerImpl.l:101: {local_id} :
{ return TokenID::ID_LOCAL; } { return TokenID::ID_LOCAL; }
break; break;
case 46: // rule AsciiLexerImpl.l:101: "\assign" : case 46: // rule AsciiLexerImpl.l:103: "\assign" :
{ return TokenID::PUNC_ASSIGN; } { return TokenID::ASSIGN; }
break; break;
case 47: // rule AsciiLexerImpl.l:102: "\from" : case 47: // rule AsciiLexerImpl.l:104: "\from" :
{ return TokenID::PUNC_ITERATE; } { return TokenID::ITERATE; }
break; break;
case 48: // rule AsciiLexerImpl.l:103: "\defexpr" : case 48: // rule AsciiLexerImpl.l:105: "\defexpr" :
{ return TokenID::PUNC_DEFINE; } { return TokenID::PUNC_DEFINE; }
break; break;
case 49: // rule AsciiLexerImpl.l:104: "\deftype" : case 49: // rule AsciiLexerImpl.l:106: "\deftype" :
{ return TokenID::PUNC_STRUCT; } { return TokenID::PUNC_STRUCT; }
break; break;
case 50: // rule AsciiLexerImpl.l:105: "(" : case 50: // rule AsciiLexerImpl.l:107: "(" :
{ return TokenID::PUNC_PL; } { return TokenID::PUNC_PL; }
break; break;
case 51: // rule AsciiLexerImpl.l:106: ")" : case 51: // rule AsciiLexerImpl.l:108: ")" :
{ return TokenID::PUNC_PR; } { return TokenID::PUNC_PR; }
break; break;
case 52: // rule AsciiLexerImpl.l:107: "{" : case 52: // rule AsciiLexerImpl.l:109: "{" :
{ return TokenID::PUNC_CL; } { return TokenID::PUNC_CL; }
break; break;
case 53: // rule AsciiLexerImpl.l:108: "}" : case 53: // rule AsciiLexerImpl.l:110: "}" :
{ return TokenID::PUNC_CR; } { return TokenID::PUNC_CR; }
break; break;
case 54: // rule AsciiLexerImpl.l:109: "[" : case 54: // rule AsciiLexerImpl.l:111: "[" :
{ return TokenID::PUNC_SL; } { return TokenID::PUNC_SL; }
break; break;
case 55: // rule AsciiLexerImpl.l:110: "]" : case 55: // rule AsciiLexerImpl.l:112: "]" :
{ return TokenID::PUNC_SR; } { return TokenID::PUNC_SR; }
break; break;
case 56: // rule AsciiLexerImpl.l:111: "|" : case 56: // rule AsciiLexerImpl.l:113: "|" :
{ return TokenID::PUNC_BAR; } { return TokenID::PUNC_BAR; }
break; break;
case 57: // rule AsciiLexerImpl.l:112: "," : case 57: // rule AsciiLexerImpl.l:114: "," :
{ return TokenID::PUNC_COMMA; } { return TokenID::PUNC_COMMA; }
break; break;
case 58: // rule AsciiLexerImpl.l:113: ";" : case 58: // rule AsciiLexerImpl.l:115: ";" :
{ return TokenID::PUNC_SEMICOLON; } { return TokenID::PUNC_SEMICOLON; }
break; break;
case 59: // rule AsciiLexerImpl.l:115: {ws} : case 59: // rule AsciiLexerImpl.l:117: {ws} :
; ;
break; break;
case 60: // rule AsciiLexerImpl.l:117: . : case 60: // rule AsciiLexerImpl.l:119: . :
{ return TokenID::INTERRUPT; } { return TokenID::INTERRUPT; }
break; break;

View File

@ -41,16 +41,15 @@ private:
bool ViQuantifier(Cursor iter); bool ViQuantifier(Cursor iter);
bool ViNegation(Cursor iter); bool ViNegation(Cursor iter);
bool ViLogicBinary(Cursor iter); bool ViLogicBinary(Cursor iter);
bool ViEquals(Cursor iter); bool ViEquals(Cursor iter) { return OutputBinary(iter); }
bool ViIntegerPredicate(Cursor iter) { return ViEquals(iter); } bool ViIntegerPredicate(Cursor iter) { return OutputBinary(iter); }
bool ViSetexprPredicate(Cursor iter) { return ViEquals(iter); } bool ViSetexprPredicate(Cursor iter) { return OutputBinary(iter); }
bool ViDeclarative(Cursor iter); bool ViDeclarative(Cursor iter);
bool ViImperative(Cursor iter);
bool ViImpDeclare(Cursor iter);
bool ViImpAssign(Cursor iter);
bool ViImpCheck(Cursor iter);
bool ViRecursion(Cursor iter); bool ViRecursion(Cursor iter);
bool ViImperative(Cursor iter);
bool ViIterate(Cursor iter) { return OutputBinary(iter); }
bool ViAssign(Cursor iter) { return OutputBinary(iter); }
bool ViDecart(Cursor iter); bool ViDecart(Cursor iter);
bool ViBoolean(Cursor iter); bool ViBoolean(Cursor iter);
@ -71,9 +70,10 @@ private:
void Clear() noexcept; void Clear() noexcept;
void OutputChild(const Cursor& iter, Index index, bool addBrackets = false); void OutputChild(const Cursor& iter, Index index, bool addBrackets = false);
bool OutputBinary(const Cursor& iter);
void EnumChildren(const Cursor& iter, const std::string& separator); bool EnumChildren(const Cursor& iter, const std::string& separator);
void EnumChildren(const Cursor& iter, char left, char right, const std::string& separator); bool EnumChildren(const Cursor& iter, char left, char right, const std::string& separator);
}; };
} // namespace ccl::rslang } // namespace ccl::rslang

View File

@ -1,6 +1,6 @@
// MathLexerImpl.hpp generated by reflex 4.2.0 from MathLexerImpl.l // MathLexerImpl.hpp generated by reflex 4.2.1 from MathLexerImpl.l
#define REFLEX_VERSION "4.2.0" #define REFLEX_VERSION "4.2.1"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// // // //
@ -81,8 +81,10 @@ public:
StrPos lineBase{ 0 }; StrPos lineBase{ 0 };
[[nodiscard]] StrRange Range() const { [[nodiscard]] StrRange Range() const {
return StrRange{ static_cast<StrPos>(lineBase + columno()), return StrRange{
static_cast<StrPos>(lineBase + columno() + columns()) }; static_cast<StrPos>(lineBase + columno()),
static_cast<StrPos>(lineBase + columno() + columns())
};
} }
@ -158,199 +160,199 @@ ccl::rslang::TokenID ccl::rslang::detail::rslex::MathLexerImpl::lex(void)
return ccl::rslang::TokenID(); return ccl::rslang::TokenID();
} }
break; break;
case 1: // rule MathLexerImpl.l:48: "+" : case 1: // rule MathLexerImpl.l:50: "+" :
{ return TokenID::PLUS; } { return TokenID::PLUS; }
break; break;
case 2: // rule MathLexerImpl.l:49: "-" : case 2: // rule MathLexerImpl.l:51: "-" :
{ return TokenID::MINUS; } { return TokenID::MINUS; }
break; break;
case 3: // rule MathLexerImpl.l:50: "*" : case 3: // rule MathLexerImpl.l:52: "*" :
{ return TokenID::MULTIPLY; } { return TokenID::MULTIPLY; }
break; break;
case 4: // rule MathLexerImpl.l:51: ">" : case 4: // rule MathLexerImpl.l:53: ">" :
{ return TokenID::GREATER; } { return TokenID::GREATER; }
break; break;
case 5: // rule MathLexerImpl.l:52: "<" : case 5: // rule MathLexerImpl.l:54: "<" :
{ return TokenID::LESSER; } { return TokenID::LESSER; }
break; break;
case 6: // rule MathLexerImpl.l:53: \x{2265} : case 6: // rule MathLexerImpl.l:55: \x{2265} :
{ return TokenID::GREATER_OR_EQ; } { return TokenID::GREATER_OR_EQ; }
break; break;
case 7: // rule MathLexerImpl.l:54: \x{2264} : case 7: // rule MathLexerImpl.l:56: \x{2264} :
{ return TokenID::LESSER_OR_EQ; } { return TokenID::LESSER_OR_EQ; }
break; break;
case 8: // rule MathLexerImpl.l:56: "=" : case 8: // rule MathLexerImpl.l:58: "=" :
{ return TokenID::EQUAL; } { return TokenID::EQUAL; }
break; break;
case 9: // rule MathLexerImpl.l:57: \x{2260} : case 9: // rule MathLexerImpl.l:59: \x{2260} :
{ return TokenID::NOTEQUAL; } { return TokenID::NOTEQUAL; }
break; break;
case 10: // rule MathLexerImpl.l:59: \x{2200} : case 10: // rule MathLexerImpl.l:61: \x{2200} :
{ return TokenID::FORALL; } { return TokenID::FORALL; }
break; break;
case 11: // rule MathLexerImpl.l:60: \x{2203} : case 11: // rule MathLexerImpl.l:62: \x{2203} :
{ return TokenID::EXISTS; } { return TokenID::EXISTS; }
break; break;
case 12: // rule MathLexerImpl.l:62: \x{00AC} : case 12: // rule MathLexerImpl.l:64: \x{00AC} :
{ return TokenID::NOT; } { return TokenID::NOT; }
break; break;
case 13: // rule MathLexerImpl.l:63: "&" : case 13: // rule MathLexerImpl.l:65: "&" :
{ return TokenID::AND; } { return TokenID::AND; }
break; break;
case 14: // rule MathLexerImpl.l:64: \x{2228} : case 14: // rule MathLexerImpl.l:66: \x{2228} :
{ return TokenID::OR; } { return TokenID::OR; }
break; break;
case 15: // rule MathLexerImpl.l:65: \x{21D2} : case 15: // rule MathLexerImpl.l:67: \x{21D2} :
{ return TokenID::IMPLICATION; } { return TokenID::IMPLICATION; }
break; break;
case 16: // rule MathLexerImpl.l:66: \x{21D4} : case 16: // rule MathLexerImpl.l:68: \x{21D4} :
{ return TokenID::EQUIVALENT; } { return TokenID::EQUIVALENT; }
break; break;
case 17: // rule MathLexerImpl.l:68: :\x{2208} : case 17: // rule MathLexerImpl.l:70: :\x{2208} :
{ return TokenID::PUNC_ITERATE; } { return TokenID::ITERATE; }
break; break;
case 18: // rule MathLexerImpl.l:69: \x{2208} : case 18: // rule MathLexerImpl.l:71: \x{2208} :
{ return TokenID::IN; } { return TokenID::IN; }
break; break;
case 19: // rule MathLexerImpl.l:70: \x{2209} : case 19: // rule MathLexerImpl.l:72: \x{2209} :
{ return TokenID::NOTIN; } { return TokenID::NOTIN; }
break; break;
case 20: // rule MathLexerImpl.l:71: \x{2286} : case 20: // rule MathLexerImpl.l:73: \x{2286} :
{ return TokenID::SUBSET_OR_EQ; } { return TokenID::SUBSET_OR_EQ; }
break; break;
case 21: // rule MathLexerImpl.l:72: \x{2282} : case 21: // rule MathLexerImpl.l:74: \x{2282} :
{ return TokenID::SUBSET; } { return TokenID::SUBSET; }
break; break;
case 22: // rule MathLexerImpl.l:73: \x{2284} : case 22: // rule MathLexerImpl.l:75: \x{2284} :
{ return TokenID::NOTSUBSET; } { return TokenID::NOTSUBSET; }
break; break;
case 23: // rule MathLexerImpl.l:75: \x{00D7} : case 23: // rule MathLexerImpl.l:77: \x{00D7} :
{ return TokenID::DECART; } { return TokenID::DECART; }
break; break;
case 24: // rule MathLexerImpl.l:76: \x{222A} : case 24: // rule MathLexerImpl.l:78: \x{222A} :
{ return TokenID::UNION; } { return TokenID::UNION; }
break; break;
case 25: // rule MathLexerImpl.l:77: \x{2229} : case 25: // rule MathLexerImpl.l:79: \x{2229} :
{ return TokenID::INTERSECTION; } { return TokenID::INTERSECTION; }
break; break;
case 26: // rule MathLexerImpl.l:78: \x{005C} : case 26: // rule MathLexerImpl.l:80: \x{005C} :
{ return TokenID::SET_MINUS; } { return TokenID::SET_MINUS; }
break; break;
case 27: // rule MathLexerImpl.l:79: \x{2206} : case 27: // rule MathLexerImpl.l:81: \x{2206} :
{ return TokenID::SYMMINUS; } { return TokenID::SYMMINUS; }
break; break;
case 28: // rule MathLexerImpl.l:80: \x{212C} : case 28: // rule MathLexerImpl.l:82: \x{212C} :
{ return TokenID::BOOLEAN; } { return TokenID::BOOLEAN; }
break; break;
case 29: // rule MathLexerImpl.l:82: pr{index} : case 29: // rule MathLexerImpl.l:84: pr{index} :
{ return TokenID::SMALLPR; } { return TokenID::SMALLPR; }
break; break;
case 30: // rule MathLexerImpl.l:83: Pr{index} : case 30: // rule MathLexerImpl.l:85: Pr{index} :
{ return TokenID::BIGPR; } { return TokenID::BIGPR; }
break; break;
case 31: // rule MathLexerImpl.l:84: Fi{index} : case 31: // rule MathLexerImpl.l:86: Fi{index} :
{ return TokenID::FILTER; } { return TokenID::FILTER; }
break; break;
case 32: // rule MathLexerImpl.l:85: card : case 32: // rule MathLexerImpl.l:87: card :
{ return TokenID::CARD; } { return TokenID::CARD; }
break; break;
case 33: // rule MathLexerImpl.l:86: bool : case 33: // rule MathLexerImpl.l:88: bool :
{ return TokenID::BOOL; } { return TokenID::BOOL; }
break; break;
case 34: // rule MathLexerImpl.l:87: red : case 34: // rule MathLexerImpl.l:89: red :
{ return TokenID::REDUCE; } { return TokenID::REDUCE; }
break; break;
case 35: // rule MathLexerImpl.l:88: debool : case 35: // rule MathLexerImpl.l:90: debool :
{ return TokenID::DEBOOL; } { return TokenID::DEBOOL; }
break; break;
case 36: // rule MathLexerImpl.l:90: D : case 36: // rule MathLexerImpl.l:92: D :
{ return TokenID::DECLARATIVE; } { return TokenID::DECLARATIVE; }
break; break;
case 37: // rule MathLexerImpl.l:91: R : case 37: // rule MathLexerImpl.l:93: R :
{ return TokenID::RECURSIVE; } { return TokenID::RECURSIVE; }
break; break;
case 38: // rule MathLexerImpl.l:92: I : case 38: // rule MathLexerImpl.l:94: I :
{ return TokenID::IMPERATIVE; } { return TokenID::IMPERATIVE; }
break; break;
case 39: // rule MathLexerImpl.l:94: Z : case 39: // rule MathLexerImpl.l:96: Z :
{ return TokenID::LIT_INTSET; } { return TokenID::LIT_INTSET; }
break; break;
case 40: // rule MathLexerImpl.l:95: \x{2205} : case 40: // rule MathLexerImpl.l:97: \x{2205} :
{ return TokenID::LIT_EMPTYSET; } { return TokenID::LIT_EMPTYSET; }
break; break;
case 41: // rule MathLexerImpl.l:96: {number} : case 41: // rule MathLexerImpl.l:98: {number} :
{ return TokenID::LIT_INTEGER; } { return TokenID::LIT_INTEGER; }
break; break;
case 42: // rule MathLexerImpl.l:98: F{number} : case 42: // rule MathLexerImpl.l:100: F{number} :
{ return TokenID::ID_FUNCTION; } { return TokenID::ID_FUNCTION; }
break; break;
case 43: // rule MathLexerImpl.l:99: P{number} : case 43: // rule MathLexerImpl.l:101: P{number} :
{ return TokenID::ID_PREDICATE; } { return TokenID::ID_PREDICATE; }
break; break;
case 44: // rule MathLexerImpl.l:100: R{number} : case 44: // rule MathLexerImpl.l:102: R{number} :
{ return TokenID::ID_RADICAL; } { return TokenID::ID_RADICAL; }
break; break;
case 45: // rule MathLexerImpl.l:102: {global_id} : case 45: // rule MathLexerImpl.l:104: {global_id} :
{ return TokenID::ID_GLOBAL; } { return TokenID::ID_GLOBAL; }
break; break;
case 46: // rule MathLexerImpl.l:103: {local_id} : case 46: // rule MathLexerImpl.l:105: {local_id} :
{ return TokenID::ID_LOCAL; } { return TokenID::ID_LOCAL; }
break; break;
case 47: // rule MathLexerImpl.l:105: ":=" : case 47: // rule MathLexerImpl.l:107: ":=" :
{ return TokenID::PUNC_ASSIGN; } { return TokenID::ASSIGN; }
break; break;
case 48: // rule MathLexerImpl.l:106: ":==" : case 48: // rule MathLexerImpl.l:108: ":==" :
{ return TokenID::PUNC_DEFINE; } { return TokenID::PUNC_DEFINE; }
break; break;
case 49: // rule MathLexerImpl.l:107: "::=" : case 49: // rule MathLexerImpl.l:109: "::=" :
{ return TokenID::PUNC_STRUCT; } { return TokenID::PUNC_STRUCT; }
break; break;
case 50: // rule MathLexerImpl.l:108: "(" : case 50: // rule MathLexerImpl.l:110: "(" :
{ return TokenID::PUNC_PL; } { return TokenID::PUNC_PL; }
break; break;
case 51: // rule MathLexerImpl.l:109: ")" : case 51: // rule MathLexerImpl.l:111: ")" :
{ return TokenID::PUNC_PR; } { return TokenID::PUNC_PR; }
break; break;
case 52: // rule MathLexerImpl.l:110: "{" : case 52: // rule MathLexerImpl.l:112: "{" :
{ return TokenID::PUNC_CL; } { return TokenID::PUNC_CL; }
break; break;
case 53: // rule MathLexerImpl.l:111: "}" : case 53: // rule MathLexerImpl.l:113: "}" :
{ return TokenID::PUNC_CR; } { return TokenID::PUNC_CR; }
break; break;
case 54: // rule MathLexerImpl.l:112: "[" : case 54: // rule MathLexerImpl.l:114: "[" :
{ return TokenID::PUNC_SL; } { return TokenID::PUNC_SL; }
break; break;
case 55: // rule MathLexerImpl.l:113: "]" : case 55: // rule MathLexerImpl.l:115: "]" :
{ return TokenID::PUNC_SR; } { return TokenID::PUNC_SR; }
break; break;
case 56: // rule MathLexerImpl.l:114: "|" : case 56: // rule MathLexerImpl.l:116: "|" :
{ return TokenID::PUNC_BAR; } { return TokenID::PUNC_BAR; }
break; break;
case 57: // rule MathLexerImpl.l:115: "," : case 57: // rule MathLexerImpl.l:117: "," :
{ return TokenID::PUNC_COMMA; } { return TokenID::PUNC_COMMA; }
break; break;
case 58: // rule MathLexerImpl.l:116: ";" : case 58: // rule MathLexerImpl.l:118: ";" :
{ return TokenID::PUNC_SEMICOLON; } { return TokenID::PUNC_SEMICOLON; }
break; break;
case 59: // rule MathLexerImpl.l:118: \n : case 59: // rule MathLexerImpl.l:120: \n :
{ lineBase += static_cast<StrPos>(columno() + 1); } { lineBase += static_cast<StrPos>(columno() + 1); }
break; break;
case 60: // rule MathLexerImpl.l:119: [ \t]+ : case 60: // rule MathLexerImpl.l:121: [ \t]+ :
; ;
break; break;
case 61: // rule MathLexerImpl.l:121: . : case 61: // rule MathLexerImpl.l:123: . :
{ return TokenID::INTERRUPT; } { return TokenID::INTERRUPT; }
break; break;

View File

@ -87,8 +87,8 @@ RawNode FunctionDeclaration(
RawNode FunctionCall( RawNode FunctionCall(
RawNode function, RawNode function,
RawNode args, RawNode RawNode args,
rs RawNode rs
); );
RawNode FilterCall( RawNode FilterCall(
@ -109,7 +109,12 @@ RawNode TermDeclaration(
RawNode declaration, RawNode declaration,
RawNode domain, RawNode domain,
RawNode predicate, RawNode predicate,
RawNode rc); RawNode rc
);
RawNode TupleDeclaration(
ParserState* state,
RawNode tuple
);
RawNode FullRecursion( RawNode FullRecursion(
RawNode rec, RawNode rec,
@ -137,7 +142,7 @@ RawNode Imperative(
} // namespace ccl::rslang::detail } // namespace ccl::rslang::detail
#line 141 "../header/RSParserImpl.h" #line 146 "../header/RSParserImpl.h"
# include <cassert> # include <cassert>
# include <cstdlib> // std::abort # include <cstdlib> // std::abort
@ -267,7 +272,7 @@ RawNode Imperative(
#line 15 "RSParserImpl.y" #line 15 "RSParserImpl.y"
namespace ccl { namespace rslang { namespace detail { namespace ccl { namespace rslang { namespace detail {
#line 271 "../header/RSParserImpl.h" #line 276 "../header/RSParserImpl.h"
@ -351,10 +356,10 @@ namespace ccl { namespace rslang { namespace detail {
RST_DECLARATIVE = 300, // DECLARATIVE RST_DECLARATIVE = 300, // DECLARATIVE
RST_RECURSIVE = 301, // RECURSIVE RST_RECURSIVE = 301, // RECURSIVE
RST_IMPERATIVE = 302, // IMPERATIVE RST_IMPERATIVE = 302, // IMPERATIVE
RST_DEFINE = 303, // DEFINE RST_ITERATE = 303, // ITERATE
RST_STRUCT = 304, // STRUCT RST_ASSIGN = 304, // ASSIGN
RST_ASSIGN = 305, // ASSIGN RST_DEFINE = 305, // DEFINE
RST_ITERATE = 306, // ITERATE RST_STRUCT = 306, // STRUCT
RST_LP = 307, // LP RST_LP = 307, // LP
RST_RP = 308, // RP RST_RP = 308, // RP
RST_LC = 309, // LC RST_LC = 309, // LC
@ -430,10 +435,10 @@ namespace ccl { namespace rslang { namespace detail {
S_DECLARATIVE = 45, // DECLARATIVE S_DECLARATIVE = 45, // DECLARATIVE
S_RECURSIVE = 46, // RECURSIVE S_RECURSIVE = 46, // RECURSIVE
S_IMPERATIVE = 47, // IMPERATIVE S_IMPERATIVE = 47, // IMPERATIVE
S_DEFINE = 48, // DEFINE S_ITERATE = 48, // ITERATE
S_STRUCT = 49, // STRUCT S_ASSIGN = 49, // ASSIGN
S_ASSIGN = 50, // ASSIGN S_DEFINE = 50, // DEFINE
S_ITERATE = 51, // ITERATE S_STRUCT = 51, // STRUCT
S_LP = 52, // LP S_LP = 52, // LP
S_RP = 53, // RP S_RP = 53, // RP
S_LC = 54, // LC S_LC = 54, // LC
@ -451,38 +456,34 @@ namespace ccl { namespace rslang { namespace detail {
S_arguments = 66, // arguments S_arguments = 66, // arguments
S_declaration = 67, // declaration S_declaration = 67, // declaration
S_variable = 68, // variable S_variable = 68, // variable
S_var_enum = 69, // var_enum S_variable_pack = 69, // variable_pack
S_var_all = 70, // var_all S_logic = 70, // logic
S_logic = 71, // logic S_logic_no_binary = 71, // logic_no_binary
S_logic_all = 72, // logic_all S_logic_all = 72, // logic_all
S_logic_par = 73, // logic_par S_logic_par = 73, // logic_par
S_logic_predicates = 74, // logic_predicates S_logic_predicates = 74, // logic_predicates
S_binary_predicate = 75, // binary_predicate S_binary_predicate = 75, // binary_predicate
S_logic_unary = 76, // logic_unary S_logic_unary = 76, // logic_unary
S_logic_no_binary = 77, // logic_no_binary S_quantifier = 77, // quantifier
S_quantifier = 78, // quantifier S_logic_binary = 78, // logic_binary
S_quant_var = 79, // quant_var S_setexpr = 79, // setexpr
S_quant_var_enum = 80, // quant_var_enum S_text_function = 80, // text_function
S_logic_binary = 81, // logic_binary S_setexpr_enum = 81, // setexpr_enum
S_setexpr = 82, // setexpr S_setexpr_enum_min2 = 82, // setexpr_enum_min2
S_text_function = 83, // text_function S_literal = 83, // literal
S_setexpr_enum = 84, // setexpr_enum S_identifier = 84, // identifier
S_setexpr_enum_min2 = 85, // setexpr_enum_min2 S_setexpr_binary = 85, // setexpr_binary
S_literal = 86, // literal S_setexpr_generators = 86, // setexpr_generators
S_identifier = 87, // identifier S_enumeration = 87, // enumeration
S_setexpr_binary = 88, // setexpr_binary S_tuple = 88, // tuple
S_setexpr_generators = 89, // setexpr_generators S_boolean = 89, // boolean
S_enumeration = 90, // enumeration S_filter_expression = 90, // filter_expression
S_tuple = 91, // tuple S_declarative = 91, // declarative
S_boolean = 92, // boolean S_recursion = 92, // recursion
S_filter_expression = 93, // filter_expression S_imperative = 93, // imperative
S_declarative = 94, // declarative S_imp_blocks = 94, // imp_blocks
S_recursion = 95, // recursion S_RPE = 95, // RPE
S_imperative = 96, // imperative S_RCE = 96 // RCE
S_imp_blocks = 97, // imp_blocks
S_imp_block = 98, // imp_block
S_RPE = 99, // RPE
S_RCE = 100 // RCE
}; };
}; };
@ -980,9 +981,9 @@ namespace ccl { namespace rslang { namespace detail {
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 640, ///< Last index in yytable_. yylast_ = 620, ///< Last index in yytable_.
yynnts_ = 40, ///< Number of nonterminal symbols. yynnts_ = 36, ///< Number of nonterminal symbols.
yyfinal_ = 87 ///< Termination state number. yyfinal_ = 89 ///< Termination state number.
}; };
@ -994,7 +995,7 @@ namespace ccl { namespace rslang { namespace detail {
#line 15 "RSParserImpl.y" #line 15 "RSParserImpl.y"
} } } // ccl::rslang::detail } } } // ccl::rslang::detail
#line 998 "../header/RSParserImpl.h" #line 999 "../header/RSParserImpl.h"

View File

@ -81,11 +81,10 @@ protected:
bool ViBoolean(Cursor iter); bool ViBoolean(Cursor iter);
bool ViDeclarative(Cursor iter); bool ViDeclarative(Cursor iter);
bool ViImperative(Cursor iter);
//bool ViImpDeclare(Cursor iter);
//bool ViImpAssign(Cursor iter);
//bool ViImpCheck(Cursor iter);
bool ViRecursion(Cursor iter); bool ViRecursion(Cursor iter);
bool ViImperative(Cursor iter);
//bool ViIterate(Cursor iter);
//bool ViAssign(Cursor iter);
bool ViTuple(Cursor iter); bool ViTuple(Cursor iter);
bool ViEnumeration(Cursor iter); bool ViEnumeration(Cursor iter);

View File

@ -30,8 +30,11 @@ public:
lex->lex(); lex->lex();
auto token = lex->MakeToken(); auto token = lex->MakeToken();
if (token.id == TokenID::INTERRUPT && lex->reporter.has_value()) { if (token.id == TokenID::INTERRUPT && lex->reporter.has_value()) {
lex->reporter.value()(Error{ static_cast<uint32_t>(LexerEID::unknownSymbol), lex->reporter.value()(Error{
token.pos.start, { lex->Text() } }); static_cast<uint32_t>(LexerEID::unknownSymbol),
token.pos.start,
{ lex->Text() }
});
} }
return token; return token;
}; };

View File

@ -57,10 +57,10 @@ public:
} }
} }
void CreateSyntaxTree(RawNode root); bool CreateSyntaxTree(RawNode root);
void FinalizeExpression(RawNode expr); bool FinalizeExpression(RawNode expr);
void FinalizeCstEmpty(RawNode cst, RawNode mode); bool FinalizeCstEmpty(RawNode cst, RawNode mode);
void FinalizeCstExpression(RawNode cst, RawNode mode, RawNode data); bool FinalizeCstExpression(RawNode cst, RawNode mode, RawNode data);
}; };
} // namespace ccl::rslang::detail } // namespace ccl::rslang::detail

View File

@ -17,6 +17,7 @@ enum class ParseEID : uint32_t {
missingParenthesis = 0x8406, // Пропущена скобка ')' missingParenthesis = 0x8406, // Пропущена скобка ')'
missingCurlyBrace = 0x8407, // Пропущена скобка '}' missingCurlyBrace = 0x8407, // Пропущена скобка '}'
invalidQuantifier = 0x8408, // Некорректная кванторная декларация invalidQuantifier = 0x8408, // Некорректная кванторная декларация
invalidImperative = 0x8409, // Использование императивного синтаксиса вне императивного блока
expectedDeclaration = 0x8414, // Ожидалось объявление аргументов expectedDeclaration = 0x8414, // Ожидалось объявление аргументов
expectedLocal = 0x8415, // Ожидалось имя локальной переменной expectedLocal = 0x8415, // Ожидалось имя локальной переменной
}; };

View File

@ -82,11 +82,13 @@ enum class TokenID : uint32_t { // NOLINT(performance-enum-size)
RECURSIVE, RECURSIVE,
IMPERATIVE, IMPERATIVE,
// Imperative operators
ITERATE,
ASSIGN,
// Punctuation // Punctuation
PUNC_DEFINE, PUNC_DEFINE,
PUNC_STRUCT, PUNC_STRUCT,
PUNC_ASSIGN,
PUNC_ITERATE,
PUNC_PL, PUNC_PL,
PUNC_PR, PUNC_PR,
PUNC_CL, PUNC_CL,
@ -113,10 +115,6 @@ enum class TokenID : uint32_t { // NOLINT(performance-enum-size)
NT_RECURSIVE_FULL, // Полная рекурсия NT_RECURSIVE_FULL, // Полная рекурсия
NT_RECURSIVE_SHORT, // Сокращенная рекурсия NT_RECURSIVE_SHORT, // Сокращенная рекурсия
NT_IMP_DECLARE, // Блок декларации
NT_IMP_ASSIGN, // Блок присвоения
NT_IMP_LOGIC, // Блок проверки
// ======= Helper tokens ======== // ======= Helper tokens ========
INTERRUPT, INTERRUPT,
END, END,

View File

@ -232,21 +232,19 @@ public:
assert(ChildrenCount() == 2); assert(ChildrenCount() == 2);
return visitor.ViSetexprPredicate(*this); return visitor.ViSetexprPredicate(*this);
case TokenID::ITERATE:
assert(ChildrenCount() == 2);
return visitor.ViIterate(*this);
case TokenID::ASSIGN:
assert(ChildrenCount() == 2);
return visitor.ViAssign(*this);
case TokenID::NT_DECLARATIVE_EXPR: case TokenID::NT_DECLARATIVE_EXPR:
assert(ChildrenCount() == 3); assert(ChildrenCount() == 3);
return visitor.ViDeclarative(*this); return visitor.ViDeclarative(*this);
case TokenID::NT_IMPERATIVE_EXPR: case TokenID::NT_IMPERATIVE_EXPR:
assert(ChildrenCount() > 1); assert(ChildrenCount() > 1);
return visitor.ViImperative(*this); return visitor.ViImperative(*this);
case TokenID::NT_IMP_DECLARE:
assert(ChildrenCount() == 2);
return visitor.ViImpDeclare(*this);
case TokenID::NT_IMP_ASSIGN:
assert(ChildrenCount() == 2);
return visitor.ViImpAssign(*this);
case TokenID::NT_IMP_LOGIC:
assert(ChildrenCount() == 1);
return visitor.ViImpCheck(*this);
case TokenID::DECART: case TokenID::DECART:
assert(ChildrenCount() > 1); assert(ChildrenCount() > 1);
@ -349,11 +347,10 @@ private:
bool ViSetexprPredicate(Cursor iter) { return this->BaseT().VisitDefault(iter); } bool ViSetexprPredicate(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViDeclarative(Cursor iter) { return this->BaseT().VisitDefault(iter); } bool ViDeclarative(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViImperative(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViImpDeclare(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViImpAssign(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViImpCheck(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViRecursion(Cursor iter) { return this->BaseT().VisitDefault(iter); } bool ViRecursion(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViImperative(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViIterate(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViAssign(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViDecart(Cursor iter) { return this->BaseT().VisitDefault(iter); } bool ViDecart(Cursor iter) { return this->BaseT().VisitDefault(iter); }
bool ViBoolean(Cursor iter) { return this->BaseT().VisitDefault(iter); } bool ViBoolean(Cursor iter) { return this->BaseT().VisitDefault(iter); }

View File

@ -104,11 +104,10 @@ protected:
bool ViBoolean(Cursor iter); bool ViBoolean(Cursor iter);
bool ViDeclarative(Cursor iter); bool ViDeclarative(Cursor iter);
bool ViImperative(Cursor iter);
bool ViImpDeclare(Cursor iter);
bool ViImpAssign(Cursor iter);
bool ViImpCheck(Cursor iter) { return VisitAllAndSetCurrent(iter, LogicT{}); }
bool ViRecursion(Cursor iter); bool ViRecursion(Cursor iter);
bool ViImperative(Cursor iter);
bool ViIterate(Cursor iter);
bool ViAssign(Cursor iter);
bool ViTuple(Cursor iter); bool ViTuple(Cursor iter);
bool ViEnumeration(Cursor iter); bool ViEnumeration(Cursor iter);

View File

@ -65,10 +65,9 @@ protected:
bool ViDeclarative(Cursor iter); bool ViDeclarative(Cursor iter);
bool ViImperative(Cursor iter); bool ViImperative(Cursor iter);
bool ViImpDeclare(Cursor iter) { return AssertChildIsValue(iter, 1); }
bool ViImpAssign(Cursor iter) { return AssertChildIsValue(iter, 1); }
bool ViImpCheck(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
bool ViRecursion(Cursor iter) { return AssertAllValues(iter); } bool ViRecursion(Cursor iter) { return AssertAllValues(iter); }
bool ViIterate(Cursor iter) { return AssertChildIsValue(iter, 1); }
bool ViAssign(Cursor iter) { return AssertChildIsValue(iter, 1); }
bool ViTuple(Cursor iter) { return AssertAllValues(iter); } bool ViTuple(Cursor iter) { return AssertAllValues(iter); }
bool ViEnumeration(Cursor iter) { return AssertAllValues(iter); } bool ViEnumeration(Cursor iter) { return AssertAllValues(iter); }

View File

@ -25,7 +25,7 @@ public:
private: private:
struct BlockMeta { struct BlockMeta {
TokenID type{ TokenID::NT_IMP_LOGIC }; TokenID rootID{};
uint32_t arg{}; uint32_t arg{};
std::optional<object::StructuredData> domain{}; std::optional<object::StructuredData> domain{};
}; };
@ -44,21 +44,22 @@ public:
CreateBlockMetadata(); CreateBlockMetadata();
for (current = 0; ; ++current) { for (current = 0; ; ++current) {
incrementIter = false; incrementIter = false;
if (IsDone()) { if (HasReachedEnd()) {
if (!SaveElement()) { if (!SaveElement()) {
return false; return false;
} }
} else { } else if (!ProcessBlock()) {
if (!ProcessBlock()) {
return false; return false;
} }
}
if (incrementIter && !PrepareNextIteration()) { if (incrementIter && !PrepareNextIteration()) {
return true; return true;
} }
if (++parent.iterationCounter > MAX_ITERATIONS) { if (++parent.iterationCounter > MAX_ITERATIONS) {
parent.OnError(ValueEID::iterationsLimit, imperative->pos.start, parent.OnError(
std::to_string(MAX_ITERATIONS)); ValueEID::iterationsLimit,
imperative->pos.start,
std::to_string(MAX_ITERATIONS)
);
return false; return false;
} }
} }
@ -70,24 +71,23 @@ private:
iter.MoveToChild(1); iter.MoveToChild(1);
do { do {
BlockMeta newBlock{}; BlockMeta newBlock{};
newBlock.type = iter->id; newBlock.rootID = iter->id;
switch (newBlock.type) { switch (newBlock.rootID) {
case TokenID::NT_IMP_DECLARE: { case TokenID::ITERATE: {
newBlock.arg = *begin(parent.nodeVars[iter.Child(0).get()]); newBlock.arg = *begin(parent.nodeVars[iter.Child(0).get()]);
break; break;
} }
case TokenID::NT_IMP_ASSIGN: { case TokenID::ASSIGN: {
newBlock.arg = *begin(parent.nodeVars[iter.Child(0).get()]); newBlock.arg = *begin(parent.nodeVars[iter.Child(0).get()]);
break; break;
} }
default: default: break;
case TokenID::NT_IMP_LOGIC: break;
} }
metaData.emplace_back(std::move(newBlock)); metaData.emplace_back(std::move(newBlock));
} while (iter.MoveToNextSibling()); } while (iter.MoveToNextSibling());
} }
[[nodiscard]] bool IsDone() const noexcept { [[nodiscard]] bool HasReachedEnd() const noexcept {
return current + 1 >= imperative.ChildrenCount(); return current + 1 >= imperative.ChildrenCount();
} }
@ -107,45 +107,41 @@ private:
child.MoveToChild(static_cast<Index>(current + 1)); child.MoveToChild(static_cast<Index>(current + 1));
auto& meta = metaData.at(static_cast<size_t>(current)); auto& meta = metaData.at(static_cast<size_t>(current));
switch (meta.type) { switch (meta.rootID) {
default: default: {
case TokenID::NT_IMP_LOGIC: { const auto predicatValue = parent.EvaluateChild(imperative, static_cast<Index>(current + 1));
const auto predicatValue = parent.EvaluateChild(child, 0); if (!predicatValue.has_value() || !std::holds_alternative<bool>(predicatValue.value())) {
if (!predicatValue.has_value()) {
return false; return false;
} else { }
incrementIter = !std::get<bool>(predicatValue.value()); incrementIter = !std::get<bool>(predicatValue.value());
return true; return true;
} }
} case TokenID::ITERATE: {
case TokenID::NT_IMP_DECLARE: {
const auto domain = parent.ExtractDomain(child); const auto domain = parent.ExtractDomain(child);
if (!domain.has_value()) { if (!domain.has_value()) {
return false; return false;
} else if (domain->B().IsEmpty()) { }
if (domain->B().IsEmpty()) {
incrementIter = true; incrementIter = true;
return true;
} else { } else {
meta.domain = domain.value(); meta.domain = domain.value();
auto element = std::begin(meta.domain->B()); auto element = std::begin(meta.domain->B());
parent.idsData[meta.arg] = *element; parent.idsData[meta.arg] = *element;
blockStack.emplace(current); blockStack.emplace(current);
iterStack.emplace(element); iterStack.emplace(element);
}
return true; return true;
} }
} case TokenID::ASSIGN: {
case TokenID::NT_IMP_ASSIGN: {
const auto localValue = parent.ExtractDomain(child); const auto localValue = parent.ExtractDomain(child);
if (!localValue.has_value()) { if (!localValue.has_value()) {
return false; return false;
} else { }
parent.idsData[meta.arg] = localValue.value(); parent.idsData[meta.arg] = localValue.value();
return true; return true;
} }
} }
} }
}
[[nodiscard]] bool PrepareNextIteration() { [[nodiscard]] bool PrepareNextIteration() {
while (!empty(blockStack)) { while (!empty(blockStack)) {
@ -275,7 +271,11 @@ bool ASTInterpreter::ViCard(Cursor iter) {
} }
const auto size = std::get<StructuredData>(base.value()).B().Cardinality(); const auto size = std::get<StructuredData>(base.value()).B().Cardinality();
if (size == StructuredData::SET_INFINITY) { if (size == StructuredData::SET_INFINITY) {
OnError(ValueEID::typedOverflow, iter->pos.start, std::to_string(StructuredData::SET_INFINITY)); OnError(
ValueEID::typedOverflow,
iter->pos.start,
std::to_string(StructuredData::SET_INFINITY)
);
return false; return false;
} }
return SetCurrent(Factory::Val(size)); return SetCurrent(Factory::Val(size));
@ -291,13 +291,19 @@ bool ASTInterpreter::ViQuantifier(Cursor iter) {
const auto isUniversal = iter->id == TokenID::FORALL; const auto isUniversal = iter->id == TokenID::FORALL;
for (const auto& child : domain->B()) { for (const auto& child : domain->B()) {
if (++iterationCounter > MAX_ITERATIONS) { if (++iterationCounter > MAX_ITERATIONS) {
OnError(ValueEID::iterationsLimit, iter->pos.start, std::to_string(MAX_ITERATIONS)); OnError(
ValueEID::iterationsLimit,
iter->pos.start,
std::to_string(MAX_ITERATIONS)
);
return false; return false;
} }
idsData[varID] = child; idsData[varID] = child;
if (const auto iterationValue = EvaluateChild(iter, 2); !iterationValue.has_value()) { const auto iterationValue = EvaluateChild(iter, 2);
if (!iterationValue.has_value()) {
return false; return false;
} else if (std::get<bool>(iterationValue.value()) != isUniversal) { }
if (std::get<bool>(iterationValue.value()) != isUniversal) {
return SetCurrent(!isUniversal); return SetCurrent(!isUniversal);
} }
} }
@ -345,8 +351,7 @@ bool ASTInterpreter::ViLogicBinary(Cursor iter) {
} }
bool ASTInterpreter::TryEvaluateFromFirstArg(TokenID operation, bool firstArgValue) noexcept { bool ASTInterpreter::TryEvaluateFromFirstArg(TokenID operation, bool firstArgValue) noexcept {
if ((operation == TokenID::AND && !firstArgValue) || if ((operation == TokenID::AND && !firstArgValue) || (operation == TokenID::OR && firstArgValue)) {
(operation == TokenID::OR && firstArgValue)) {
return SetCurrent(firstArgValue); return SetCurrent(firstArgValue);
} else if (operation == TokenID::IMPLICATION && !firstArgValue) { } else if (operation == TokenID::IMPLICATION && !firstArgValue) {
return SetCurrent(!firstArgValue); return SetCurrent(!firstArgValue);
@ -396,7 +401,11 @@ bool ASTInterpreter::ViDeclarative(Cursor iter) {
auto result = Factory::EmptySet(); auto result = Factory::EmptySet();
for (const auto& child : setDomain->B()) { for (const auto& child : setDomain->B()) {
if (++iterationCounter > MAX_ITERATIONS) { if (++iterationCounter > MAX_ITERATIONS) {
OnError(ValueEID::iterationsLimit, iter->pos.start, std::to_string(MAX_ITERATIONS)); OnError(
ValueEID::iterationsLimit,
iter->pos.start,
std::to_string(MAX_ITERATIONS)
);
return false; return false;
} }
idsData[varID] = child; idsData[varID] = child;
@ -428,7 +437,11 @@ bool ASTInterpreter::ViRecursion(Cursor iter) {
StructuredData current = initial.value(); StructuredData current = initial.value();
do { do {
if (++iterationCounter > MAX_ITERATIONS) { if (++iterationCounter > MAX_ITERATIONS) {
OnError(ValueEID::iterationsLimit, iter->pos.start, std::to_string(MAX_ITERATIONS)); OnError(
ValueEID::iterationsLimit,
iter->pos.start,
std::to_string(MAX_ITERATIONS)
);
return false; return false;
} }
@ -454,16 +467,21 @@ bool ASTInterpreter::ViRecursion(Cursor iter) {
bool ASTInterpreter::ViDecart(Cursor iter) { bool ASTInterpreter::ViDecart(Cursor iter) {
std::vector<StructuredData> args{}; std::vector<StructuredData> args{};
for (Index child = 0; child < iter.ChildrenCount(); ++child) { for (Index child = 0; child < iter.ChildrenCount(); ++child) {
if (const auto childValue = EvaluateChild(iter, child); !childValue.has_value()) { const auto childValue = EvaluateChild(iter, child);
if (!childValue.has_value()) {
return false; return false;
} else {
args.emplace_back(std::get<StructuredData>(childValue.value()));
} }
args.emplace_back(std::get<StructuredData>(childValue.value()));
} }
curValue = Factory::Decartian(args); curValue = Factory::Decartian(args);
if (std::get<StructuredData>(curValue).B().Cardinality() == StructuredData::SET_INFINITY) { const auto cardinality = std::get<StructuredData>(curValue).B().Cardinality();
OnError(ValueEID::typedOverflow, iter->pos.start, std::to_string(StructuredData::SET_INFINITY)); if (cardinality == StructuredData::SET_INFINITY) {
OnError(
ValueEID::typedOverflow,
iter->pos.start,
std::to_string(StructuredData::SET_INFINITY)
);
return false; return false;
} }
return true; return true;
@ -627,7 +645,10 @@ bool ASTInterpreter::ViDebool(Cursor iter) {
} }
const auto value = std::get<StructuredData>(childValue.value()); const auto value = std::get<StructuredData>(childValue.value());
if (value.B().Cardinality() != 1) { if (value.B().Cardinality() != 1) {
OnError(ValueEID::invalidDebool, iter->pos.start); OnError(
ValueEID::invalidDebool,
iter->pos.start
);
return false; return false;
} }
return SetCurrent(std::get<StructuredData>(childValue.value()).B().Debool()); return SetCurrent(std::get<StructuredData>(childValue.value()).B().Debool());

View File

@ -15,11 +15,16 @@ void Normalizer::Normalize(SyntaxTree::Node& root) {
break; break;
} }
case TokenID::NT_RECURSIVE_FULL: case TokenID::NT_RECURSIVE_FULL:
case TokenID::NT_RECURSIVE_SHORT: case TokenID::NT_RECURSIVE_SHORT: {
case TokenID::NT_DECLARATIVE_EXPR: { Recursion(root);
if (root(0).token.id == TokenID::NT_TUPLE_DECL) { break;
TupleDeclaration(root);
} }
case TokenID::NT_DECLARATIVE_EXPR: {
Declarative(root);
break;
}
case TokenID::NT_IMPERATIVE_EXPR: {
Imperative(root);
break; break;
} }
case TokenID::NT_FUNC_CALL: { case TokenID::NT_FUNC_CALL: {
@ -42,6 +47,46 @@ void Normalizer::Quantifier(SyntaxTree::Node& quant) {
} }
} }
void Normalizer::Declarative(SyntaxTree::Node& root) {
if (root(0).token.id != TokenID::NT_TUPLE_DECL) {
return;
}
const auto newName = ProcessTupleDeclaration(root(0));
SubstituteTupleVariables(root(1), newName);
SubstituteTupleVariables(root(2), newName);
}
void Normalizer::Recursion(SyntaxTree::Node& root) {
if (root(0).token.id != TokenID::NT_TUPLE_DECL) {
return;
}
const auto newName = ProcessTupleDeclaration(root(0));
SubstituteTupleVariables(root(2), newName);
if (root.token.id == TokenID::NT_RECURSIVE_FULL) {
SubstituteTupleVariables(root(3), newName);
}
}
void Normalizer::Imperative(SyntaxTree::Node& root) {
for (Index child = 1; child < root.ChildrenCount(); ++child) {
const auto childID = root(child).token.id;
if (childID != TokenID::ITERATE && childID != TokenID::ASSIGN) {
continue;
}
auto& declRoot = root(child);
if (declRoot(0).token.id != TokenID::NT_TUPLE_DECL) {
continue;
}
const auto newName = ProcessTupleDeclaration(declRoot(0));
for (Index child2 = 0; child2 < root.ChildrenCount(); ++child2) {
if (child2 != child) {
SubstituteTupleVariables(root(child2), newName);
}
}
SubstituteTupleVariables(root, newName);
}
}
void Normalizer::EnumDeclaration(SyntaxTree::Node& quant) { void Normalizer::EnumDeclaration(SyntaxTree::Node& quant) {
auto newQuant = std::make_unique<SyntaxTree::Node>(quant.token); auto newQuant = std::make_unique<SyntaxTree::Node>(quant.token);
newQuant->AddChildCopy(quant(0)); newQuant->AddChildCopy(quant(0));
@ -61,32 +106,12 @@ void Normalizer::TupleDeclaration(
SyntaxTree::Node& declaration, SyntaxTree::Node& declaration,
SyntaxTree::Node& predicate SyntaxTree::Node& predicate
) { ) {
const auto newName = CreateTupleName(declaration); const auto newName = ProcessTupleDeclaration(declaration);
declaration.RemoveAll();
declaration.token.data = TokenData{ newName };
declaration.token.id = TokenID::ID_LOCAL;
SubstituteTupleVariables(predicate, newName); SubstituteTupleVariables(predicate, newName);
} }
void Normalizer::TupleDeclaration(SyntaxTree::Node& target) { std::string Normalizer::ProcessTupleDeclaration(SyntaxTree::Node& root) {
const auto token = target.token.id; tupleSubstitutes.clear();
auto newName = CreateTupleName(target(0));
target(0).RemoveAll();
target(0).token.id = TokenID::ID_LOCAL;
target(0).token.data = TokenData{ newName };
if (token == TokenID::NT_DECLARATIVE_EXPR) {
SubstituteTupleVariables(target(1), newName);
}
SubstituteTupleVariables(target(2), newName);
if (token == TokenID::NT_RECURSIVE_FULL) {
SubstituteTupleVariables(target(3), newName);
}
}
std::string Normalizer::CreateTupleName(const SyntaxTree::Node& root) {
tuples.clear();
std::string newName{ '@' }; std::string newName{ '@' };
std::stack<const SyntaxTree::Node*> nodeStack{}; std::stack<const SyntaxTree::Node*> nodeStack{};
@ -101,7 +126,7 @@ std::string Normalizer::CreateTupleName(const SyntaxTree::Node& root) {
if (curNode->token.id == TokenID::ID_LOCAL) { if (curNode->token.id == TokenID::ID_LOCAL) {
const auto& name = curNode->token.data.ToText(); const auto& name = curNode->token.data.ToText();
newName += name; newName += name;
tuples.insert({ name, curPath }); tupleSubstitutes.insert({ name, curPath });
} else if (const auto childCount = curNode->ChildrenCount(); childCount > 0) { } else if (const auto childCount = curNode->ChildrenCount(); childCount > 0) {
for (auto child = static_cast<Index>(childCount - 1); child >= 0; --child) { for (auto child = static_cast<Index>(childCount - 1); child >= 0; --child) {
curPath.emplace_back(static_cast<Index>(child + 1)); curPath.emplace_back(static_cast<Index>(child + 1));
@ -111,15 +136,20 @@ std::string Normalizer::CreateTupleName(const SyntaxTree::Node& root) {
} }
} }
} }
root.RemoveAll();
root.token.data = TokenData{ newName };
root.token.id = TokenID::ID_LOCAL;
return newName; return newName;
} }
void Normalizer::SubstituteTupleVariables(SyntaxTree::Node& target, const std::string& newName) { void Normalizer::SubstituteTupleVariables(SyntaxTree::Node& target, const std::string& newName) {
for (Index child = 0; child < target.ChildrenCount(); ++child) { for (Index child = 0; child < target.ChildrenCount(); ++child) {
if (target(child).token.id == TokenID::ID_LOCAL) { if (target(child).token.id != TokenID::ID_LOCAL) {
SubstituteTupleVariables(target(child), newName);
} else {
const auto& localName = target(child).token.data.ToText(); const auto& localName = target(child).token.data.ToText();
if (tuples.contains(localName)) { if (tupleSubstitutes.contains(localName)) {
const auto& indexes = tuples.at(localName); const auto& indexes = tupleSubstitutes.at(localName);
target(child).token.data = TokenData{ newName }; target(child).token.data = TokenData{ newName };
for (const auto prIndex : indexes) { for (const auto prIndex : indexes) {
target.ExtendChild(child, TokenID::SMALLPR); target.ExtendChild(child, TokenID::SMALLPR);
@ -127,21 +157,19 @@ void Normalizer::SubstituteTupleVariables(SyntaxTree::Node& target, const std::s
target(child).token.data = TokenData{ std::vector<Index>{ prIndex } }; target(child).token.data = TokenData{ std::vector<Index>{ prIndex } };
} }
} }
} else {
SubstituteTupleVariables(target(child), newName);
} }
} }
} }
void Normalizer::Function(SyntaxTree::Node& func) { void Normalizer::Function(SyntaxTree::Node& func) {
nodes.clear(); nodeSubstitutes.clear();
nameSubstitutes.clear(); nameSubstitutes.clear();
const auto* funcTree = termFuncs(func(0).token.data.ToText()); const auto* funcTree = termFuncs(func(0).token.data.ToText());
if (funcTree != nullptr) { if (funcTree != nullptr) {
const auto argNames = ArgNames(funcTree->root->At(1).At(0)); const auto argNames = ArgNames(funcTree->root->At(1).At(0));
for (Index child = 1; child < func.ChildrenCount(); ++child) { for (Index child = 1; child < func.ChildrenCount(); ++child) {
nodes.insert({ argNames.at(static_cast<size_t>(child) - 1), &func(child) }); nodeSubstitutes.insert({ argNames.at(static_cast<size_t>(child) - 1), &func(child) });
} }
SyntaxTree newTree = *funcTree; SyntaxTree newTree = *funcTree;
SubstituteArgs(newTree.root->At(1).At(1), func.token.pos); SubstituteArgs(newTree.root->At(1).At(1), func.token.pos);
@ -167,8 +195,8 @@ void Normalizer::SubstituteArgs(SyntaxTree::Node& target, const StrRange pos) {
} }
} else { } else {
const auto& localName = target.token.ToString(); const auto& localName = target.token.ToString();
if (nodes.contains(localName)) { if (nodeSubstitutes.contains(localName)) {
target = *nodes.at(localName); target = *nodeSubstitutes.at(localName);
} else { } else {
const auto& oldName = target.token.ToString(); const auto& oldName = target.token.ToString();
std::string newName{}; std::string newName{};

View File

@ -100,8 +100,8 @@ R{number} { return TokenID::ID_RADICAL; }
{global_id} { return TokenID::ID_GLOBAL; } {global_id} { return TokenID::ID_GLOBAL; }
{local_id} { return TokenID::ID_LOCAL; } {local_id} { return TokenID::ID_LOCAL; }
"\assign" { return TokenID::PUNC_ASSIGN; } "\assign" { return TokenID::ASSIGN; }
"\from" { return TokenID::PUNC_ITERATE; } "\from" { return TokenID::ITERATE; }
"\defexpr" { return TokenID::PUNC_DEFINE; } "\defexpr" { return TokenID::PUNC_DEFINE; }
"\deftype" { return TokenID::PUNC_STRUCT; } "\deftype" { return TokenID::PUNC_STRUCT; }
"(" { return TokenID::PUNC_PL; } "(" { return TokenID::PUNC_PL; }

View File

@ -147,13 +147,6 @@ bool GeneratorImplAST::ViLogicBinary(Cursor iter) {
return true; return true;
} }
bool GeneratorImplAST::ViEquals(Cursor iter) {
OutputChild(iter, 0);
rsText += iter->ToString(syntax);
OutputChild(iter, 1);
return true;
}
bool GeneratorImplAST::ViDeclarative(Cursor iter) { bool GeneratorImplAST::ViDeclarative(Cursor iter) {
rsText += Token::Str(TokenID::DECLARATIVE, syntax); rsText += Token::Str(TokenID::DECLARATIVE, syntax);
rsText += '{'; rsText += '{';
@ -181,30 +174,11 @@ bool GeneratorImplAST::ViImperative(Cursor iter) {
return true; return true;
} }
bool GeneratorImplAST::ViImpDeclare(Cursor iter) {
OutputChild(iter, 0);
rsText += Token::Str(TokenID::PUNC_ITERATE, syntax);
OutputChild(iter, 1);
return true;
}
bool GeneratorImplAST::ViImpAssign(Cursor iter) {
OutputChild(iter, 0);
rsText += Token::Str(TokenID::PUNC_ASSIGN, syntax);
OutputChild(iter, 1);
return true;
}
bool GeneratorImplAST::ViImpCheck(Cursor iter) {
OutputChild(iter, 0);
return true;
}
bool GeneratorImplAST::ViRecursion(Cursor iter) { bool GeneratorImplAST::ViRecursion(Cursor iter) {
rsText += Token::Str(TokenID::RECURSIVE, syntax); rsText += Token::Str(TokenID::RECURSIVE, syntax);
rsText += '{'; rsText += '{';
OutputChild(iter, 0); OutputChild(iter, 0);
rsText += Token::Str(TokenID::PUNC_ASSIGN); rsText += Token::Str(TokenID::ASSIGN);
OutputChild(iter, 1); OutputChild(iter, 1);
rsText += R"( | )"; rsText += R"( | )";
OutputChild(iter, 2); OutputChild(iter, 2);
@ -252,19 +226,28 @@ void GeneratorImplAST::OutputChild(const Cursor& iter, const Index index, const
} }
} }
void GeneratorImplAST::EnumChildren(const Cursor& iter, const std::string& separator) { bool GeneratorImplAST::OutputBinary(const Cursor& iter) {
OutputChild(iter, 0);
rsText += iter->ToString(syntax);
OutputChild(iter, 1);
return true;
}
bool GeneratorImplAST::EnumChildren(const Cursor& iter, const std::string& separator) {
for (Index child = 0; child < iter.ChildrenCount(); ++child) { for (Index child = 0; child < iter.ChildrenCount(); ++child) {
if (child > 0) { if (child > 0) {
rsText += separator; rsText += separator;
} }
OutputChild(iter, child); OutputChild(iter, child);
} }
return true;
} }
void GeneratorImplAST::EnumChildren(const Cursor& iter, const char left, const char right, const std::string& separator) { bool GeneratorImplAST::EnumChildren(const Cursor& iter, const char left, const char right, const std::string& separator) {
rsText += left; rsText += left;
EnumChildren(iter, separator); EnumChildren(iter, separator);
rsText += right; rsText += right;
return true;
} }
} // namespace ccl::rslang } // namespace ccl::rslang

View File

@ -67,7 +67,7 @@ local_id (_|{lower}){alnum}*
\x{21D2} { return TokenID::IMPLICATION; } \x{21D2} { return TokenID::IMPLICATION; }
\x{21D4} { return TokenID::EQUIVALENT; } \x{21D4} { return TokenID::EQUIVALENT; }
:\x{2208} { return TokenID::PUNC_ITERATE; } :\x{2208} { return TokenID::ITERATE; }
\x{2208} { return TokenID::IN; } \x{2208} { return TokenID::IN; }
\x{2209} { return TokenID::NOTIN; } \x{2209} { return TokenID::NOTIN; }
\x{2286} { return TokenID::SUBSET_OR_EQ; } \x{2286} { return TokenID::SUBSET_OR_EQ; }
@ -104,7 +104,7 @@ R{number} { return TokenID::ID_RADICAL; }
{global_id} { return TokenID::ID_GLOBAL; } {global_id} { return TokenID::ID_GLOBAL; }
{local_id} { return TokenID::ID_LOCAL; } {local_id} { return TokenID::ID_LOCAL; }
":=" { return TokenID::PUNC_ASSIGN; } ":=" { return TokenID::ASSIGN; }
":==" { return TokenID::PUNC_DEFINE; } ":==" { return TokenID::PUNC_DEFINE; }
"::=" { return TokenID::PUNC_STRUCT; } "::=" { return TokenID::PUNC_STRUCT; }
"(" { return TokenID::PUNC_PL; } "(" { return TokenID::PUNC_PL; }

View File

@ -93,14 +93,13 @@ bool ASTInterpreter::NameCollector::ViImperative(Cursor iter) {
child.MoveToChild(1); child.MoveToChild(1);
do { do {
switch (child->id) { switch (child->id) {
case TokenID::NT_IMP_ASSIGN: case TokenID::ITERATE:
case TokenID::NT_IMP_DECLARE: { case TokenID::ASSIGN: {
const auto varID = *begin(parent.nodeVars[iter.Child(0).get()]); const auto varID = *begin(parent.nodeVars[iter.Child(0).get()]);
vars.erase(std::remove(begin(vars), end(vars), varID), end(vars)); vars.erase(std::remove(begin(vars), end(vars), varID), end(vars));
break; break;
} }
default: default: break;
case TokenID::NT_IMP_LOGIC: break;
} }
} while (child.MoveToNextSibling()); } while (child.MoveToNextSibling());
return true; return true;

View File

@ -18,6 +18,7 @@
#endif #endif
#include <optional> #include <optional>
#include <unordered_map>
namespace ccl::rslang::detail { namespace ccl::rslang::detail {
@ -186,6 +187,26 @@ RawNode TermDeclaration(
return result; return result;
} }
RawNode TupleDeclaration(ParserState* state, RawNode tuple) {
// TODO: check tuple contains only local variables, ParseEID::expectedLocal
std::vector<Node*> stack{ tuple.get()};
while (!stack.empty()) {
auto node = stack.back();
const auto id = node->token.id;
stack.pop_back();
if (id == TokenID::NT_TUPLE) {
node->token.id = TokenID::NT_TUPLE_DECL;
} else if (id != TokenID::ID_LOCAL) {
state->OnError(ParseEID::expectedLocal, node->token.pos.start);
return nullptr;
}
for (const auto& child: node->children) {
stack.emplace_back(child.get());
}
}
return tuple;
}
RawNode FullRecursion( RawNode FullRecursion(
RawNode rec, RawNode rec,
RawNode declaration, RawNode declaration,
@ -232,6 +253,30 @@ RawNode Imperative(RawNode imp, RawNode value, RawNode actions, RawNode rc) {
return result; return result;
} }
bool SemanticCheck(ParserState* state, RawNode root) {
std::vector<Node*> stack{ root.get() };
std::vector<Node*> parents{ nullptr };
while (!stack.empty()) {
const auto node = stack.back();
stack.pop_back();
const auto parent = parents.back();
parents.pop_back();
const auto id = node->token.id;
if (id == TokenID::ASSIGN || id == TokenID::ITERATE) {
if (parent == nullptr || parent->token.id != TokenID::NT_IMPERATIVE_EXPR) {
state->OnError(ParseEID::invalidImperative, node->token.pos.start);
return false;
}
}
for (const auto& child: node->children) {
stack.emplace_back(child.get());
parents.emplace_back(node);
}
}
return true;
}
SyntaxTree::RawNode CreateNodeRecursive(Node& astNode) { SyntaxTree::RawNode CreateNodeRecursive(Node& astNode) {
if (astNode.token.id == TokenID::PUNC_PL) { if (astNode.token.id == TokenID::PUNC_PL) {
return CreateNodeRecursive(*astNode.children.at(0)); return CreateNodeRecursive(*astNode.children.at(0));
@ -244,25 +289,29 @@ SyntaxTree::RawNode CreateNodeRecursive(Node& astNode) {
} }
} }
void ParserState::CreateSyntaxTree(RawNode root) { bool ParserState::CreateSyntaxTree(RawNode root) {
if (!SemanticCheck(this, root)) {
return false;
}
parsedTree = std::make_unique<SyntaxTree>(CreateNodeRecursive(*root)); parsedTree = std::make_unique<SyntaxTree>(CreateNodeRecursive(*root));
return true;
} }
void ParserState::FinalizeExpression(RawNode expr) { bool ParserState::FinalizeExpression(RawNode expr) {
CreateSyntaxTree(expr); return CreateSyntaxTree(expr);
} }
void ParserState::FinalizeCstEmpty(RawNode cst, RawNode mode) { bool ParserState::FinalizeCstEmpty(RawNode cst, RawNode mode) {
mode->token.pos = StrRange{ cst->token.pos.start, mode->token.pos.finish }; mode->token.pos = StrRange{ cst->token.pos.start, mode->token.pos.finish };
mode->children.emplace_back(cst); mode->children.emplace_back(cst);
CreateSyntaxTree(mode); return CreateSyntaxTree(mode);
} }
void ParserState::FinalizeCstExpression(RawNode cst, RawNode mode, RawNode data) { bool ParserState::FinalizeCstExpression(RawNode cst, RawNode mode, RawNode data) {
mode->token.pos = StrRange{ cst->token.pos.start, data->token.pos.finish }; mode->token.pos = StrRange{ cst->token.pos.start, data->token.pos.finish };
mode->children.emplace_back(cst); mode->children.emplace_back(cst);
mode->children.emplace_back(data); mode->children.emplace_back(data);
CreateSyntaxTree(mode); return CreateSyntaxTree(mode);
} }
} // namespace ccl::rslang::detail } // namespace ccl::rslang::detail

File diff suppressed because it is too large Load Diff

View File

@ -86,8 +86,8 @@ RawNode FunctionDeclaration(
RawNode FunctionCall( RawNode FunctionCall(
RawNode function, RawNode function,
RawNode args, RawNode RawNode args,
rs RawNode rs
); );
RawNode FilterCall( RawNode FilterCall(
@ -108,7 +108,12 @@ RawNode TermDeclaration(
RawNode declaration, RawNode declaration,
RawNode domain, RawNode domain,
RawNode predicate, RawNode predicate,
RawNode rc); RawNode rc
);
RawNode TupleDeclaration(
ParserState* state,
RawNode tuple
);
RawNode FullRecursion( RawNode FullRecursion(
RawNode rec, RawNode rec,
@ -233,12 +238,15 @@ RawNode Imperative(
IMPERATIVE // ImperativeDefinition IMPERATIVE // ImperativeDefinition
// ------------- Imperative operators -------------------
ITERATE // SetIteration (IsElement)
ASSIGN // Assignment (IsEqual)
// ------------- Punctuation and Syntactic sugar ---------- // ------------- Punctuation and Syntactic sugar ----------
%token %token
DEFINE // Global definition separator DEFINE // Global definition separator
STRUCT // Global structure domain separator STRUCT // Global structure domain separator
ASSIGN // Assignment (IsEqual)
ITERATE // SetIteration (IsElement)
LP // ( LP // (
RP // ) RP // )
LC // { LC // {
@ -260,16 +268,16 @@ RawNode Imperative(
// ------------------------- Language Expression ------------------------------ // ------------------------- Language Expression ------------------------------
expression expression
: global_declaration : global_declaration
| logic_or_setexpr { state->FinalizeExpression($1); } | logic_or_setexpr { if(!state->FinalizeExpression($1)) YYABORT; }
| function_definition { state->FinalizeExpression($1); } | function_definition { if(!state->FinalizeExpression($1)) YYABORT; }
; ;
global_declaration global_declaration
: GLOBAL DEFINE { state->FinalizeCstEmpty($1, $2); } : GLOBAL DEFINE { if(!state->FinalizeCstEmpty($1, $2)) YYABORT; }
| GLOBAL STRUCT setexpr { state->FinalizeCstExpression($1, $2, $3); } | GLOBAL STRUCT setexpr { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
| GLOBAL DEFINE logic_or_setexpr { state->FinalizeCstExpression($1, $2, $3); } | GLOBAL DEFINE logic_or_setexpr { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
| FUNCTION DEFINE function_definition { state->FinalizeCstExpression($1, $2, $3); } | FUNCTION DEFINE function_definition { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
| PREDICATE DEFINE function_definition { state->FinalizeCstExpression($1, $2, $3); } | PREDICATE DEFINE function_definition { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
; ;
logic_or_setexpr logic_or_setexpr
@ -295,15 +303,12 @@ declaration
variable variable
: LOCAL : LOCAL
| LP var_enum RPE { $$ = ReplaceBrackets(TokenID::NT_TUPLE_DECL, $1, $2, $3); } | tuple { $$ = TupleDeclaration(state, $1); if (!$$) YYABORT; }
; ;
var_enum variable_pack
: var_all COMMA var_all { $$ = Enumeration(TokenID::INTERRUPT, $1, $3); }
| var_all COMMA error { state->OnError(ParseEID::expectedLocal); YYABORT; }
;
var_all
: variable : variable
| var_enum | variable_pack COMMA variable_pack { $$ = Enumeration(TokenID::NT_ENUM_DECL, $1, $3); }
| variable_pack COMMA error { state->OnError(ParseEID::expectedLocal); YYABORT; }
; ;
// ------------------------- Logic Expressions -------------------------------- // ------------------------- Logic Expressions --------------------------------
@ -312,6 +317,11 @@ logic
| logic_unary | logic_unary
| logic_binary | logic_binary
; ;
logic_no_binary
: logic_predicates
| logic_unary
| logic_par
;
logic_all logic_all
: logic : logic
| logic_par | logic_par
@ -323,6 +333,8 @@ logic_par
logic_predicates logic_predicates
: setexpr binary_predicate setexpr { $$ = BinaryOperation($1, $2, $3); } : setexpr binary_predicate setexpr { $$ = BinaryOperation($1, $2, $3); }
| variable ITERATE setexpr { $$ = BinaryOperation($1, $2, $3); }
| variable ASSIGN setexpr { $$ = BinaryOperation($1, $2, $3); }
; ;
binary_predicate binary_predicate
: IN : IN
@ -340,28 +352,14 @@ binary_predicate
logic_unary logic_unary
: NOT logic_no_binary { $$ = UnaryOperation($1, $2);} : NOT logic_no_binary { $$ = UnaryOperation($1, $2);}
| quantifier quant_var IN setexpr logic_no_binary { $$ = Quantifier($1, $2, $4, $5);} | quantifier variable_pack IN setexpr logic_no_binary { $$ = Quantifier($1, $2, $4, $5);}
| quantifier error { state->OnError(ParseEID::invalidQuantifier); YYABORT; } | quantifier error { state->OnError(ParseEID::invalidQuantifier); YYABORT; }
| PREDICATE LS setexpr_enum RS { $$ = FunctionCall($1, $3, $4); } | PREDICATE LS setexpr_enum RS { $$ = FunctionCall($1, $3, $4); }
; ;
logic_no_binary
: logic_predicates
| logic_unary
| logic_par
;
quantifier quantifier
: FORALL : FORALL
| EXISTS | EXISTS
; ;
quant_var
: variable
| quant_var_enum
| LP error { state->OnError(ParseEID::invalidQuantifier); YYABORT; }
;
quant_var_enum
: quant_var COMMA quant_var { $$ = Enumeration(TokenID::NT_ENUM_DECL, $1, $3); }
| quant_var COMMA error { state->OnError(ParseEID::expectedLocal); YYABORT; }
;
logic_binary logic_binary
: logic_all EQUIVALENT logic_all { $$ = BinaryOperation($1, $2, $3); } : logic_all EQUIVALENT logic_all { $$ = BinaryOperation($1, $2, $3); }
@ -457,14 +455,9 @@ imperative
: IMPERATIVE LC setexpr BAR imp_blocks RCE { $$ = Imperative($1, $3, $5, $6); } : IMPERATIVE LC setexpr BAR imp_blocks RCE { $$ = Imperative($1, $3, $5, $6); }
; ;
imp_blocks imp_blocks
: imp_block { $$ = AddNode(TokenID::INTERRUPT, $1); } : logic { $$ = AddNode(TokenID::INTERRUPT, $1); }
| imp_blocks SEMICOLON imp_blocks { $$ = Enumeration(TokenID::INTERRUPT, $1, $3); } | imp_blocks SEMICOLON imp_blocks { $$ = Enumeration(TokenID::INTERRUPT, $1, $3); }
; ;
imp_block
: LOCAL ITERATE setexpr { $$ = AddNode(TokenID::NT_IMP_DECLARE, $1, $3); }
| LOCAL ASSIGN setexpr { $$ = AddNode(TokenID::NT_IMP_ASSIGN, $1, $3); }
| logic { $$ = AddNode(TokenID::NT_IMP_LOGIC, $1); }
;
// ------------------------- Error helpers ------------------------------------ // ------------------------- Error helpers ------------------------------------

View File

@ -93,10 +93,6 @@ std::string ConvertID(std::string_view id, const Syntax syntax) {
case TokenID::NT_IMPERATIVE_EXPR: return "IMPERATIVE"; case TokenID::NT_IMPERATIVE_EXPR: return "IMPERATIVE";
case TokenID::NT_RECURSIVE_FULL: return "REC_FULL"; case TokenID::NT_RECURSIVE_FULL: return "REC_FULL";
case TokenID::NT_RECURSIVE_SHORT: return "REC_SHORT"; case TokenID::NT_RECURSIVE_SHORT: return "REC_SHORT";
case TokenID::NT_IMP_DECLARE: return "IDECLARE";
case TokenID::NT_IMP_ASSIGN: return "IASSIGN";
case TokenID::NT_IMP_LOGIC: return "ICHECK";
} }
} }
@ -133,6 +129,9 @@ std::string ConvertID(std::string_view id, const Syntax syntax) {
case TokenID::SUBSET_OR_EQ: return R"( \subseteq )"; case TokenID::SUBSET_OR_EQ: return R"( \subseteq )";
case TokenID::NOTSUBSET: return R"( \notsubset )"; case TokenID::NOTSUBSET: return R"( \notsubset )";
case TokenID::ASSIGN: return R"( \assign )";
case TokenID::ITERATE: return R"( \from )";
case TokenID::UNION: return R"( \union )"; case TokenID::UNION: return R"( \union )";
case TokenID::INTERSECTION: return R"( \intersect )"; case TokenID::INTERSECTION: return R"( \intersect )";
case TokenID::SET_MINUS: return R"( \setminus )"; case TokenID::SET_MINUS: return R"( \setminus )";
@ -143,8 +142,6 @@ std::string ConvertID(std::string_view id, const Syntax syntax) {
case TokenID::PUNC_DEFINE: return R"( \defexpr )"; case TokenID::PUNC_DEFINE: return R"( \defexpr )";
case TokenID::PUNC_STRUCT: return R"( \deftype )"; case TokenID::PUNC_STRUCT: return R"( \deftype )";
case TokenID::PUNC_ASSIGN: return R"( \assign )";
case TokenID::PUNC_ITERATE: return R"( \from )";
} }
} }
@ -174,10 +171,8 @@ std::string ConvertID(std::string_view id, const Syntax syntax) {
case TokenID::IMPLICATION: return "\xE2\x87\x92"; // \u21D2 case TokenID::IMPLICATION: return "\xE2\x87\x92"; // \u21D2
case TokenID::EQUIVALENT: return "\xE2\x87\x94"; // \u21D4 case TokenID::EQUIVALENT: return "\xE2\x87\x94"; // \u21D4
case TokenID::PUNC_DEFINE: return ":=="; case TokenID::ASSIGN: return ":=";
case TokenID::PUNC_STRUCT: return "::="; case TokenID::ITERATE: return ":\xE2\x88\x88"; // \u2208
case TokenID::PUNC_ASSIGN: return ":=";
case TokenID::PUNC_ITERATE: return ":\xE2\x88\x88"; // \u2208
case TokenID::IN: return "\xE2\x88\x88"; // \u2208 case TokenID::IN: return "\xE2\x88\x88"; // \u2208
case TokenID::NOTIN: return "\xE2\x88\x89"; // \u2209 case TokenID::NOTIN: return "\xE2\x88\x89"; // \u2209
@ -192,6 +187,9 @@ std::string ConvertID(std::string_view id, const Syntax syntax) {
case TokenID::DECART: return "\xC3\x97"; // \u00D7 case TokenID::DECART: return "\xC3\x97"; // \u00D7
case TokenID::BOOLEAN: return "\xE2\x84\xAC"; // \u212C case TokenID::BOOLEAN: return "\xE2\x84\xAC"; // \u212C
case TokenID::PUNC_DEFINE: return ":==";
case TokenID::PUNC_STRUCT: return "::=";
} }
} }
@ -259,12 +257,16 @@ std::string Token::ToString(const Syntax syntax) const {
case TokenID::FILTER: { case TokenID::FILTER: {
const auto& indicies = data.ToTuple(); const auto& indicies = data.ToTuple();
std::string result = Str(id) + std::to_string(*begin(indicies)); std::string result = Str(id) + std::to_string(*begin(indicies));
result += std::accumulate(next(begin(indicies)), end(indicies), std::string{}, result += std::accumulate(
next(begin(indicies)),
end(indicies),
std::string{},
[](std::string text, const Index index) -> decltype(auto) { [](std::string text, const Index index) -> decltype(auto) {
text += ','; text += ',';
text += std::to_string(index); text += std::to_string(index);
return text; return text;
}); }
);
return result; return result;
} }
} }

View File

@ -698,13 +698,13 @@ bool TypeAuditor::ViImperative(Cursor iter) {
return SetCurrent(std::get<Typification>(type.value()).Bool()); return SetCurrent(std::get<Typification>(type.value()).Bool());
} }
bool TypeAuditor::ViImpDeclare(Cursor iter) { bool TypeAuditor::ViIterate(Cursor iter) {
const auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); const auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation);
return domain.has_value() return domain.has_value()
&& VisitChildDeclaration(iter, 0, domain.value()); && VisitChildDeclaration(iter, 0, domain.value());
} }
bool TypeAuditor::ViImpAssign(Cursor iter) { bool TypeAuditor::ViAssign(Cursor iter) {
const auto domain = ChildType(iter, 1); const auto domain = ChildType(iter, 1);
return domain.has_value() return domain.has_value()
&& VisitChildDeclaration(iter, 0, std::get<Typification>(domain.value())); && VisitChildDeclaration(iter, 0, std::get<Typification>(domain.value()));

View File

@ -235,6 +235,8 @@ TEST_F(UTSyntaxTree, CursorDispatchVisit) {
} }
TEST_F(UTSyntaxTree, FindMinimalNode) { TEST_F(UTSyntaxTree, FindMinimalNode) {
using namespace ccl::rslang;
SyntaxTree::Node root{ Token{ TokenID::AND, StrRange{0, 10} } }; SyntaxTree::Node root{ Token{ TokenID::AND, StrRange{0, 10} } };
root.AddChildCopy(SyntaxTree::Node{ Token{ TokenID::OR, StrRange{0, 5} } }); root.AddChildCopy(SyntaxTree::Node{ Token{ TokenID::OR, StrRange{0, 5} } });
root.AddChildCopy(SyntaxTree::Node{ Token{ TokenID::BOOL, StrRange{6, 10} } }); root.AddChildCopy(SyntaxTree::Node{ Token{ TokenID::BOOL, StrRange{6, 10} } });
@ -242,15 +244,15 @@ TEST_F(UTSyntaxTree, FindMinimalNode) {
root(0).AddChildCopy(SyntaxTree::Node{ Token{ TokenID::CARD, StrRange{4, 5} } }); root(0).AddChildCopy(SyntaxTree::Node{ Token{ TokenID::CARD, StrRange{4, 5} } });
const SyntaxTree::Cursor cursor{root}; const SyntaxTree::Cursor cursor{root};
EXPECT_FALSE(ccl::rslang::FindMinimalNode(cursor, StrRange{11, 11}).has_value()); EXPECT_FALSE(FindMinimalNode(cursor, StrRange{11, 11}).has_value());
EXPECT_FALSE(ccl::rslang::FindMinimalNode(cursor, StrRange{-1, -1}).has_value()); EXPECT_FALSE(FindMinimalNode(cursor, StrRange{-1, -1}).has_value());
EXPECT_FALSE(ccl::rslang::FindMinimalNode(cursor, StrRange{0, 11}).has_value()); EXPECT_FALSE(FindMinimalNode(cursor, StrRange{0, 11}).has_value());
EXPECT_EQ(ccl::rslang::FindMinimalNode(cursor, StrRange{ 0, 0 }).value()->id, TokenID::BIGPR); EXPECT_EQ(FindMinimalNode(cursor, StrRange{ 0, 0 }).value()->id, TokenID::BIGPR);
EXPECT_EQ(ccl::rslang::FindMinimalNode(cursor, StrRange{ 4, 5 }).value()->id, TokenID::CARD); EXPECT_EQ(FindMinimalNode(cursor, StrRange{ 4, 5 }).value()->id, TokenID::CARD);
EXPECT_EQ(ccl::rslang::FindMinimalNode(cursor, StrRange{ 3, 4 }).value()->id, TokenID::OR); EXPECT_EQ(FindMinimalNode(cursor, StrRange{ 3, 4 }).value()->id, TokenID::OR);
EXPECT_EQ(ccl::rslang::FindMinimalNode(cursor, StrRange{ 0, 10 }).value()->id, TokenID::AND); EXPECT_EQ(FindMinimalNode(cursor, StrRange{ 0, 10 }).value()->id, TokenID::AND);
EXPECT_EQ(ccl::rslang::FindMinimalNode(cursor, StrRange{ 5, 6 }).value()->id, TokenID::AND); EXPECT_EQ(FindMinimalNode(cursor, StrRange{ 5, 6 }).value()->id, TokenID::AND);
} }
TEST_F(UTSyntaxTree, ASTAccess) { TEST_F(UTSyntaxTree, ASTAccess) {

View File

@ -269,6 +269,7 @@ TEST_F(UTASTInterpreter, TypedBasics) {
} }
TEST_F(UTASTInterpreter, TypedExpressions) { TEST_F(UTASTInterpreter, TypedExpressions) {
ExpectValue(R"({})", Factory::EmptySet());
ExpectValue(R"(bool(X1))", Factory::Singleton(data.at("X1"))); ExpectValue(R"(bool(X1))", Factory::Singleton(data.at("X1")));
ExpectValue(R"(bool(X1 \setminus X1))", Factory::Singleton(Factory::EmptySet())); ExpectValue(R"(bool(X1 \setminus X1))", Factory::Singleton(Factory::EmptySet()));
ExpectValue(R"(debool(bool(X1)))", data.at("X1")); ExpectValue(R"(debool(bool(X1)))", data.at("X1"));
@ -297,6 +298,7 @@ TEST_F(UTASTInterpreter, TypedExpressions) {
ExpectValue(R"(I{(a,b) | a \from X1; b \assign a; b \noteq a})", Factory::EmptySet()); ExpectValue(R"(I{(a,b) | a \from X1; b \assign a; b \noteq a})", Factory::EmptySet());
ExpectValue(R"(I{a | a \from X1})", data.at("X1")); ExpectValue(R"(I{a | a \from X1})", data.at("X1"));
ExpectValue(R"(I{a | (a,b) \from X1*X1; b \eq b})", data.at("X1"));
ExpectValue(R"(R{a \assign X1 | a \setminus a})", Factory::EmptySet()); ExpectValue(R"(R{a \assign X1 | a \setminus a})", Factory::EmptySet());
ExpectValue(R"(R{a \assign {} | a \union X1})", data.at("X1")); ExpectValue(R"(R{a \assign {} | a \union X1})", data.at("X1"));

View File

@ -6,6 +6,9 @@
#include "ASTNormalizer.h" #include "ASTNormalizer.h"
#include "ccl/rslang/Parser.h" #include "ccl/rslang/Parser.h"
#include "ccl/rslang/Literals.h"
using ccl::operator""_c17;
class UTastNormalize : public ::testing::Test { class UTastNormalize : public ::testing::Test {
protected: protected:
@ -36,31 +39,78 @@ void UTastNormalize::ExpectAST(const std::string& input, const std::string& ast)
} }
TEST_F(UTastNormalize, EnumDeclaration) { TEST_F(UTastNormalize, EnumDeclaration) {
ExpectAST(R"(\A a,b \in X1 a \eq b)", "[\xE2\x88\x80[a][X1][\xE2\x88\x80[b][X1][=[a][b]]]]"); ExpectAST(
ExpectAST(R"(\E a,b \in X1 a \eq b)", "[\xE2\x88\x83[a][X1][\xE2\x88\x83[b][X1][=[a][b]]]]"); R"(\A a,b \in X1 a \eq b)",
ExpectAST(R"(\E a,b,c \in X1 a \eq b)", "[\xE2\x88\x83[a][X1][\xE2\x88\x83[b][X1][\xE2\x88\x83[c][X1][=[a][b]]]]]"); u8"[\u2200[a][X1][\u2200[b][X1][=[a][b]]]]"_c17
);
ExpectAST(
R"(\E a,b \in X1 a \eq b)",
u8"[\u2203[a][X1][\u2203[b][X1][=[a][b]]]]"_c17
);
ExpectAST(
R"(\E a,b,c \in X1 a \eq b)",
u8"[\u2203[a][X1][\u2203[b][X1][\u2203[c][X1][=[a][b]]]]]"_c17
);
} }
TEST_F(UTastNormalize, Quantor) { TEST_F(UTastNormalize, Quantor) {
ExpectAST(R"(\A (a,b) \in S1 a \eq b)", "[\xE2\x88\x80[@ab][S1][=[pr1[@ab]][pr2[@ab]]]]"); ExpectAST(
ExpectAST(R"(\E (a,b) \in S1 a \eq b)", "[\xE2\x88\x83[@ab][S1][=[pr1[@ab]][pr2[@ab]]]]"); R"(\A (a,b) \in S1 a \eq b)",
ExpectAST(R"(\E (a,b,c) \in S1 (a \eq b \and b \eq c))", u8"[\u2200[@ab][S1][=[pr1[@ab]][pr2[@ab]]]]"_c17
"[\xE2\x88\x83[@abc][S1][&[=[pr1[@abc]][pr2[@abc]]][=[pr2[@abc]][pr3[@abc]]]]]"); );
ExpectAST(R"(\E (a,(b,c)) \in S1 (a \eq b \and b \eq c))", ExpectAST(
"[\xE2\x88\x83[@abc][S1][&[=[pr1[@abc]][pr1[pr2[@abc]]]][=[pr1[pr2[@abc]]][pr2[pr2[@abc]]]]]]"); R"(\E (a,b) \in S1 a \eq b)",
u8"[\u2203[@ab][S1][=[pr1[@ab]][pr2[@ab]]]]"_c17
);
ExpectAST(
R"(\E (a,b,c) \in S1 (a \eq b \and b \eq c))",
u8"[\u2203[@abc][S1][&[=[pr1[@abc]][pr2[@abc]]][=[pr2[@abc]][pr3[@abc]]]]]"_c17
);
ExpectAST(
R"(\E (a,(b,c)) \in S1 (a \eq b \and b \eq c))",
u8"[\u2203[@abc][S1][&[=[pr1[@abc]][pr1[pr2[@abc]]]][=[pr1[pr2[@abc]]][pr2[pr2[@abc]]]]]]"_c17
);
} }
TEST_F(UTastNormalize,TermTupleDeclaration) { TEST_F(UTastNormalize,TermTupleDeclaration) {
ExpectAST(R"(D{(a,b) \in S1 | a \eq b})", "[DECLARATIVE[@ab][S1][=[pr1[@ab]][pr2[@ab]]]]"); ExpectAST(
ExpectAST(R"(D{(a,b,c) \in S1 | a \eq b \and b \eq c})", R"(D{(a,b) \in S1 | a \eq b})",
"[DECLARATIVE[@abc][S1][&[=[pr1[@abc]][pr2[@abc]]][=[pr2[@abc]][pr3[@abc]]]]]"); "[DECLARATIVE[@ab][S1][=[pr1[@ab]][pr2[@ab]]]]"
ExpectAST(R"(D{(a,(b,c)) \in S1 | a \eq b \and b \eq c})", );
"[DECLARATIVE[@abc][S1][&[=[pr1[@abc]][pr1[pr2[@abc]]]][=[pr1[pr2[@abc]]][pr2[pr2[@abc]]]]]]"); ExpectAST(
R"(D{(a,b,c) \in S1 | a \eq b \and b \eq c})",
"[DECLARATIVE[@abc][S1][&[=[pr1[@abc]][pr2[@abc]]][=[pr2[@abc]][pr3[@abc]]]]]"
);
ExpectAST(
R"(D{(a,(b,c)) \in S1 | a \eq b \and b \eq c})",
"[DECLARATIVE[@abc][S1][&[=[pr1[@abc]][pr1[pr2[@abc]]]][=[pr1[pr2[@abc]]][pr2[pr2[@abc]]]]]]"
);
}
TEST_F(UTastNormalize, Imperative) {
ExpectAST(
R"(I{(b,a) | (a,b) \from S1})",
u8"[IMPERATIVE[TUPLE[pr2[@ab]][pr1[@ab]]][:\u2208[@ab][S1]]]"_c17
);
ExpectAST(
R"(I{b | (a,b) \from S1; a \eq a})",
u8"[IMPERATIVE[pr2[@ab]][:\u2208[@ab][S1]][=[pr1[@ab]][pr1[@ab]]]]"_c17
);
ExpectAST(
R"(I{(c,b) | a \from {S1}; (b,c) \assign a})",
u8"[IMPERATIVE[TUPLE[pr2[@bc]][pr1[@bc]]][:\u2208[a][SET[S1]]][:=[@bc][a]]]"_c17
);
} }
TEST_F(UTastNormalize, RecrusionTupleDeclaration) { TEST_F(UTastNormalize, RecrusionTupleDeclaration) {
ExpectAST(R"(R{(a,b) \assign S1 | (b,a)})", "[REC_SHORT[@ab][S1][TUPLE[pr2[@ab]][pr1[@ab]]]]"); ExpectAST(
ExpectAST(R"(R{(a,b) \assign S1 | 1 \eq 1 | (b,a)})", "[REC_FULL[@ab][S1][=[1][1]][TUPLE[pr2[@ab]][pr1[@ab]]]]"); R"(R{(a,b) \assign S1 | (b,a)})",
"[REC_SHORT[@ab][S1][TUPLE[pr2[@ab]][pr1[@ab]]]]"
);
ExpectAST(
R"(R{(a,b) \assign S1 | 1 \eq 1 | (b,a)})",
"[REC_FULL[@ab][S1][=[1][1]][TUPLE[pr2[@ab]][pr1[@ab]]]]"
);
} }
TEST_F(UTastNormalize, Functions) { TEST_F(UTastNormalize, Functions) {
@ -68,7 +118,16 @@ TEST_F(UTastNormalize, Functions) {
ExpectAST(R"(F1[X1 \setminus X1])", "[SET[\\[X1][X1]]]"); ExpectAST(R"(F1[X1 \setminus X1])", "[SET[\\[X1][X1]]]");
ExpectAST(R"(F1[F1[X1]])", "[SET[SET[X1]]]"); ExpectAST(R"(F1[F1[X1]])", "[SET[SET[X1]]]");
ExpectAST(R"(F2[X1, X2])", "[TUPLE[X1][X2]]"); ExpectAST(R"(F2[X1, X2])", "[TUPLE[X1][X2]]");
ExpectAST(R"(F3[X1])", "[DECLARATIVE[__var1][X1][=[__var1][__var1]]]"); ExpectAST(
ExpectAST(R"(F3[F3[X1]])", "[DECLARATIVE[__var1][DECLARATIVE[__var2][X1][=[__var2][__var2]]][=[__var1][__var1]]]"); R"(F3[X1])",
ExpectAST(R"(\A t \in X1 F3[{t}] \eq t)", "[\xE2\x88\x80[t][X1][=[DECLARATIVE[__var1][SET[t]][=[__var1][__var1]]][t]]]"); "[DECLARATIVE[__var1][X1][=[__var1][__var1]]]"
);
ExpectAST(
R"(F3[F3[X1]])",
"[DECLARATIVE[__var1][DECLARATIVE[__var2][X1][=[__var2][__var2]]][=[__var1][__var1]]]"
);
ExpectAST(
R"(\A t \in X1 F3[{t}] \eq t)",
u8"[\u2200[t][X1][=[DECLARATIVE[__var1][SET[t]][=[__var1][__var1]]][t]]]"_c17
);
} }

View File

@ -71,7 +71,7 @@ TEST_F(UTAsciiLexer, Keywords) {
TestSingle(R"(\and)", TokenID::AND); TestSingle(R"(\and)", TokenID::AND);
TestSingle(R"(\or)", TokenID::OR); TestSingle(R"(\or)", TokenID::OR);
TestSingle(R"(\from)", TokenID::PUNC_ITERATE); TestSingle(R"(\from)", TokenID::ITERATE);
TestSingle(R"(\in)", TokenID::IN); TestSingle(R"(\in)", TokenID::IN);
TestSingle(R"(\notin)", TokenID::NOTIN); TestSingle(R"(\notin)", TokenID::NOTIN);
TestSingle(R"(\subseteq)", TokenID::SUBSET_OR_EQ); TestSingle(R"(\subseteq)", TokenID::SUBSET_OR_EQ);

View File

@ -3,6 +3,9 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "FakeRSEnvironment.hpp" #include "FakeRSEnvironment.hpp"
#include "ccl/rslang/Literals.h"
using ccl::operator""_c17;
class UTLiterals: public ::testing::Test { class UTLiterals: public ::testing::Test {
protected: protected:
@ -13,6 +16,7 @@ protected:
TEST_F(UTLiterals, TypificationLiteral) { TEST_F(UTLiterals, TypificationLiteral) {
EXPECT_EQ(Typification("X1"), "X1"_t); EXPECT_EQ(Typification("X1"), "X1"_t);
EXPECT_EQ(Typification("C1"), "C1"_t); EXPECT_EQ(Typification("C1"), "C1"_t);
EXPECT_EQ(Typification::EmptySet(), "B(R0)"_t);
EXPECT_EQ(Typification::Integer(), "Z"_t); EXPECT_EQ(Typification::Integer(), "Z"_t);
EXPECT_EQ(Typification("X1").Bool(), "B(X1)"_t); EXPECT_EQ(Typification("X1").Bool(), "B(X1)"_t);
EXPECT_EQ(Typification("X1").Bool().Bool(), "BB(X1)"_t); EXPECT_EQ(Typification("X1").Bool().Bool(), "BB(X1)"_t);
@ -21,7 +25,12 @@ TEST_F(UTLiterals, TypificationLiteral) {
} }
TEST_F(UTLiterals, RSlangLiteral) { TEST_F(UTLiterals, RSlangLiteral) {
using ccl::operator""_c17; EXPECT_EQ(
EXPECT_EQ(R"(S1 \in B(X1))"_rs, u8"S1\u2208\u212C(X1)"_c17); R"(S1 \in B(X1))"_rs,
EXPECT_EQ("B(Y*(X1*X2)*BB(X3))"_rs, u8"\u212C(Y\u00D7(X1\u00D7X2)\u00D7\u212C\u212C(X3))"_c17); u8"S1\u2208\u212C(X1)"_c17
);
EXPECT_EQ(
"B(Y*(X1*X2)*BB(X3))"_rs,
u8"\u212C(Y\u00D7(X1\u00D7X2)\u00D7\u212C\u212C(X3))"_c17
);
} }

View File

@ -13,11 +13,12 @@ protected:
}; };
TEST_F(UTLogger, ResolveErrorType) { TEST_F(UTLogger, ResolveErrorType) {
EXPECT_EQ(ccl::rslang::ResolveErrorType(static_cast<uint32_t>(ErrorStatus::WARNING)), ErrorStatus::WARNING); using namespace ccl::rslang;
EXPECT_EQ(ccl::rslang::ResolveErrorType(static_cast<uint32_t>(ErrorStatus::WARNING) + 1), ErrorStatus::WARNING); EXPECT_EQ(ResolveErrorType(static_cast<uint32_t>(ErrorStatus::WARNING)), ErrorStatus::WARNING);
EXPECT_EQ(ccl::rslang::ResolveErrorType(static_cast<uint32_t>(ErrorStatus::CRITICAL)), ErrorStatus::CRITICAL); EXPECT_EQ(ResolveErrorType(static_cast<uint32_t>(ErrorStatus::WARNING) + 1), ErrorStatus::WARNING);
EXPECT_EQ(ccl::rslang::ResolveErrorType(static_cast<uint32_t>(ErrorStatus::CRITICAL) + 1), ErrorStatus::CRITICAL); EXPECT_EQ(ResolveErrorType(static_cast<uint32_t>(ErrorStatus::CRITICAL)), ErrorStatus::CRITICAL);
EXPECT_EQ(ccl::rslang::ResolveErrorType(static_cast<uint32_t>(ErrorStatus::CRITICAL) - 1), ErrorStatus::WARNING); EXPECT_EQ(ResolveErrorType(static_cast<uint32_t>(ErrorStatus::CRITICAL) + 1), ErrorStatus::CRITICAL);
EXPECT_EQ(ResolveErrorType(static_cast<uint32_t>(ErrorStatus::CRITICAL) - 1), ErrorStatus::WARNING);
EXPECT_TRUE(Error(static_cast<uint32_t>(ErrorStatus::WARNING), 0).IsWarning()); EXPECT_TRUE(Error(static_cast<uint32_t>(ErrorStatus::WARNING), 0).IsWarning());
EXPECT_FALSE(Error(static_cast<uint32_t>(ErrorStatus::WARNING), 0).IsCritical()); EXPECT_FALSE(Error(static_cast<uint32_t>(ErrorStatus::WARNING), 0).IsCritical());

View File

@ -91,8 +91,8 @@ TEST_F(UTMathLexer, SingleSymbol) {
TestSingle(u8"\u00D7"_c17, TokenID::DECART, 1); TestSingle(u8"\u00D7"_c17, TokenID::DECART, 1);
TestSingle("\xE2\x84\xAC", TokenID::BOOLEAN, 1); TestSingle("\xE2\x84\xAC", TokenID::BOOLEAN, 1);
TestToken(u8":\u2208"_c17, TokenID::PUNC_ITERATE); TestToken(u8":\u2208"_c17, TokenID::ITERATE);
TestSingle(":=", TokenID::PUNC_ASSIGN); TestSingle(":=", TokenID::ASSIGN);
TestSingle(":==", TokenID::PUNC_DEFINE); TestSingle(":==", TokenID::PUNC_DEFINE);
TestSingle("::=", TokenID::PUNC_STRUCT); TestSingle("::=", TokenID::PUNC_STRUCT);
} }

View File

@ -69,7 +69,11 @@ TEST_F(UTRSExpr, FilterIDs) {
TEST_F(UTRSExpr, Translate) { TEST_F(UTRSExpr, Translate) {
using ccl::operator""_c17; using ccl::operator""_c17;
std::string input{ u8"\u212C X1 X2 ab ba"_c17 }; std::string input{ u8"\u212C X1 X2 ab ba"_c17 };
const auto repCount = ccl::rslang::TranslateRS(input, TFFactory::FilterIdentifiers(), ccl::CreateTranslator(idMap)); const auto repCount = ccl::rslang::TranslateRS(
input,
TFFactory::FilterIdentifiers(),
ccl::CreateTranslator(idMap)
);
EXPECT_EQ(repCount, 2); EXPECT_EQ(repCount, 2);
EXPECT_EQ(input, u8"\u212C X42 X2 ba ba"_c17); EXPECT_EQ(input, u8"\u212C X42 X2 ba ba"_c17);
} }

View File

@ -6,6 +6,7 @@
#include "ccl/rslang/RSGenerator.h" #include "ccl/rslang/RSGenerator.h"
#include "ccl/rslang/Parser.h" #include "ccl/rslang/Parser.h"
#include "ccl/rslang/Literals.h"
using ccl::operator""_c17; using ccl::operator""_c17;
@ -71,9 +72,18 @@ TEST_F(UTRSGenerator, ExtractPrefix) {
} }
TEST_F(UTRSGenerator, FromASTGlobal) { TEST_F(UTRSGenerator, FromASTGlobal) {
ExpectASTGeneration("X1:== ", "X1:=="); ExpectASTGeneration(
ExpectASTGeneration("D1:==X1\\X2", "D1:==X1\\X2"); "X1:== ",
ExpectASTGeneration(u8"F1:==[a\u2208X1]a \\ a"_c17, u8"F1:==[a\u2208X1] a\\a"_c17); "X1:=="
);
ExpectASTGeneration(
"D1:==X1\\X2",
"D1:==X1\\X2"
);
ExpectASTGeneration(
u8"F1:==[a\u2208X1]a \\ a"_c17,
u8"F1:==[a\u2208X1] a\\a"_c17
);
} }
TEST_F(UTRSGenerator, FromASTInteger) { TEST_F(UTRSGenerator, FromASTInteger) {
@ -86,12 +96,30 @@ TEST_F(UTRSGenerator, FromASTInteger) {
ExpectASTGeneration("1 +2*3", "1+2*3"); ExpectASTGeneration("1 +2*3", "1+2*3");
ExpectASTGeneration("(1+2) * 3", "(1+2)*3"); ExpectASTGeneration("(1+2) * 3", "(1+2)*3");
ExpectASTGeneration("1 = 2", "1=2"); ExpectASTGeneration(
ExpectASTGeneration(u8"1 \u2260 2"_c17, u8"1\u22602"_c17); "1 = 2",
ExpectASTGeneration("1 > 2", "1>2"); "1=2"
ExpectASTGeneration("1 < 2", "1<2"); );
ExpectASTGeneration(u8"1 \u2264 2"_c17, u8"1\u22642"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"1 \u2265 2"_c17, u8"1\u22652"_c17); u8"1 \u2260 2"_c17,
u8"1\u22602"_c17
);
ExpectASTGeneration(
"1 > 2",
"1>2"
);
ExpectASTGeneration(
"1 < 2",
"1<2"
);
ExpectASTGeneration(
u8"1 \u2264 2"_c17,
u8"1\u22642"_c17
);
ExpectASTGeneration(
u8"1 \u2265 2"_c17,
u8"1\u22652"_c17
);
ExpectASTGeneration("1+2=3", "1+2=3"); ExpectASTGeneration("1+2=3", "1+2=3");
ExpectASTGeneration("1-2=3", "1-2=3"); ExpectASTGeneration("1-2=3", "1-2=3");
@ -102,42 +130,129 @@ TEST_F(UTRSGenerator, FromASTInteger) {
} }
TEST_F(UTRSGenerator, FromASTLogic) { TEST_F(UTRSGenerator, FromASTLogic) {
ExpectASTGeneration(u8"\u00AC (1=2 & 3=4)"_c17, u8"\u00AC(1=2 & 3=4)"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"\u00AC (1=2 \u2228 3=4)"_c17, u8"\u00AC(1=2 \u2228 3=4)"_c17); u8"\u00AC (1=2 & 3=4)"_c17,
ExpectASTGeneration(u8"\u00AC (1=2 \u21D2 3=4)"_c17, u8"\u00AC(1=2 \u21D2 3=4)"_c17); u8"\u00AC(1=2 & 3=4)"_c17
ExpectASTGeneration(u8"\u00AC (1=2 \u21D4 3=4)"_c17, u8"\u00AC(1=2 \u21D4 3=4)"_c17); );
ExpectASTGeneration(
u8"\u00AC (1=2 \u2228 3=4)"_c17,
u8"\u00AC(1=2 \u2228 3=4)"_c17
);
ExpectASTGeneration(
u8"\u00AC (1=2 \u21D2 3=4)"_c17,
u8"\u00AC(1=2 \u21D2 3=4)"_c17
);
ExpectASTGeneration(
u8"\u00AC (1=2 \u21D4 3=4)"_c17,
u8"\u00AC(1=2 \u21D4 3=4)"_c17
);
ExpectASTGeneration("1=2 & (3=4 & 5=6)", "1=2 & (3=4 & 5=6)"); ExpectASTGeneration(
ExpectASTGeneration(u8"1=2 \u2228 (3=4 \u2228 5=6)"_c17, u8"1=2 \u2228 (3=4 \u2228 5=6)"_c17); "1=2 & (3=4 & 5=6)",
ExpectASTGeneration(u8"1=2 \u21D2 (3=4 \u21D2 5=6)"_c17, u8"1=2 \u21D2 (3=4 \u21D2 5=6)"_c17); "1=2 & (3=4 & 5=6)"
ExpectASTGeneration(u8"1=2 \u21D4 (3=4 \u21D4 5=6)"_c17, u8"1=2 \u21D4 (3=4 \u21D4 5=6)"_c17); );
ExpectASTGeneration(
u8"1=2 \u2228 (3=4 \u2228 5=6)"_c17,
u8"1=2 \u2228 (3=4 \u2228 5=6)"_c17
);
ExpectASTGeneration(
u8"1=2 \u21D2 (3=4 \u21D2 5=6)"_c17,
u8"1=2 \u21D2 (3=4 \u21D2 5=6)"_c17
);
ExpectASTGeneration(
u8"1=2 \u21D4 (3=4 \u21D4 5=6)"_c17,
u8"1=2 \u21D4 (3=4 \u21D4 5=6)"_c17
);
ExpectASTGeneration(u8"1=2 & (3=4 \u2228 5=6)"_c17, u8"1=2 & (3=4 \u2228 5=6)"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"1=2 & (3=4 \u21D2 5=6)"_c17, u8"1=2 & (3=4 \u21D2 5=6)"_c17); u8"1=2 & (3=4 \u2228 5=6)"_c17,
ExpectASTGeneration(u8"1=2 & (3=4 \u21D4 5=6)"_c17, u8"1=2 & (3=4 \u21D4 5=6)"_c17); u8"1=2 & (3=4 \u2228 5=6)"_c17
ExpectASTGeneration(u8"1=2 \u2228 (3=4 \u21D2 5=6)"_c17, u8"1=2 \u2228 (3=4 \u21D2 5=6)"_c17); );
ExpectASTGeneration(u8"1=2 \u2228 (3=4 \u21D4 5=6)"_c17, u8"1=2 \u2228 (3=4 \u21D4 5=6)"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"1=2 \u21D2 (3=4 \u21D4 5=6)"_c17, u8"1=2 \u21D2 (3=4 \u21D4 5=6)"_c17); u8"1=2 & (3=4 \u21D2 5=6)"_c17,
u8"1=2 & (3=4 \u21D2 5=6)"_c17
);
ExpectASTGeneration(
u8"1=2 & (3=4 \u21D4 5=6)"_c17,
u8"1=2 & (3=4 \u21D4 5=6)"_c17
);
ExpectASTGeneration(
u8"1=2 \u2228 (3=4 \u21D2 5=6)"_c17,
u8"1=2 \u2228 (3=4 \u21D2 5=6)"_c17
);
ExpectASTGeneration(
u8"1=2 \u2228 (3=4 \u21D4 5=6)"_c17,
u8"1=2 \u2228 (3=4 \u21D4 5=6)"_c17
);
ExpectASTGeneration(
u8"1=2 \u21D2 (3=4 \u21D4 5=6)"_c17,
u8"1=2 \u21D2 (3=4 \u21D4 5=6)"_c17
);
} }
TEST_F(UTRSGenerator, FromASTQuantifier) { TEST_F(UTRSGenerator, FromASTQuantifier) {
ExpectASTGeneration(u8"\u2200a\u2208X1 (1=2)"_c17, u8"\u2200a\u2208X1 1=2"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"\u2203a\u2208X1 (1=2)"_c17, u8"\u2203a\u2208X1 1=2"_c17); u8"\u2200a\u2208X1 (1=2)"_c17,
ExpectASTGeneration(u8"\u2200a,b\u2208X1 (1=2)"_c17, u8"\u2200a, b\u2208X1 1=2"_c17); u8"\u2200a\u2208X1 1=2"_c17
ExpectASTGeneration(u8"\u2200a\u2208X1 1=2 & 3=4"_c17, u8"\u2200a\u2208X1 1=2 & 3=4"_c17); );
ExpectASTGeneration(u8"\u2200b\u2208X1\u2200a\u2208X1 1=2"_c17, u8"\u2200b\u2208X1 \u2200a\u2208X1 1=2"_c17); ExpectASTGeneration(
u8"\u2203a\u2208X1 (1=2)"_c17,
u8"\u2203a\u2208X1 1=2"_c17
);
ExpectASTGeneration(
u8"\u2200a,b\u2208X1 (1=2)"_c17,
u8"\u2200a, b\u2208X1 1=2"_c17
);
ExpectASTGeneration(
u8"\u2200a\u2208X1 1=2 & 3=4"_c17,
u8"\u2200a\u2208X1 1=2 & 3=4"_c17
);
ExpectASTGeneration(
u8"\u2200b\u2208X1\u2200a\u2208X1 1=2"_c17,
u8"\u2200b\u2208X1 \u2200a\u2208X1 1=2"_c17
);
ExpectASTGeneration(u8"\u00AC\u2200a\u2208X1 1=2"_c17, u8"\u00AC\u2200a\u2208X1 1=2"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"\u2200a\u2208X1 \u00AC1=2"_c17, u8"\u2200a\u2208X1 \u00AC1=2"_c17); u8"\u00AC\u2200a\u2208X1 1=2"_c17,
ExpectASTGeneration(u8"\u2200a\u2208X1 (1=2 & 3=4)"_c17, u8"\u2200a\u2208X1 (1=2 & 3=4)"_c17); u8"\u00AC\u2200a\u2208X1 1=2"_c17
ExpectASTGeneration(u8"\u2203a\u2208X1 (1=2 & 3=4)"_c17, u8"\u2203a\u2208X1 (1=2 & 3=4)"_c17); );
ExpectASTGeneration(u8"\u2200a\u2208X1 (1=2 \u2228 3=4)"_c17, u8"\u2200a\u2208X1 (1=2 \u2228 3=4)"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"\u2200a\u2208X1 (1=2 \u21D2 3=4)"_c17, u8"\u2200a\u2208X1 (1=2 \u21D2 3=4)"_c17); u8"\u2200a\u2208X1 \u00AC1=2"_c17,
ExpectASTGeneration(u8"\u2200a\u2208X1 (1=2 \u21D4 3=4)"_c17, u8"\u2200a\u2208X1 (1=2 \u21D4 3=4)"_c17); u8"\u2200a\u2208X1 \u00AC1=2"_c17
);
ExpectASTGeneration(
u8"\u2200a\u2208X1 (1=2 & 3=4)"_c17,
u8"\u2200a\u2208X1 (1=2 & 3=4)"_c17
);
ExpectASTGeneration(
u8"\u2203a\u2208X1 (1=2 & 3=4)"_c17,
u8"\u2203a\u2208X1 (1=2 & 3=4)"_c17
);
ExpectASTGeneration(
u8"\u2200a\u2208X1 (1=2 \u2228 3=4)"_c17,
u8"\u2200a\u2208X1 (1=2 \u2228 3=4)"_c17
);
ExpectASTGeneration(
u8"\u2200a\u2208X1 (1=2 \u21D2 3=4)"_c17,
u8"\u2200a\u2208X1 (1=2 \u21D2 3=4)"_c17
);
ExpectASTGeneration(
u8"\u2200a\u2208X1 (1=2 \u21D4 3=4)"_c17,
u8"\u2200a\u2208X1 (1=2 \u21D4 3=4)"_c17
);
ExpectASTGeneration(u8"\u2200(a,b)\u2208X1 1=2"_c17, u8"\u2200(a, b)\u2208X1 1=2"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"\u2200(a,b,c)\u2208X1 1=2"_c17, u8"\u2200(a, b, c)\u2208X1 1=2"_c17); u8"\u2200(a,b)\u2208X1 1=2"_c17,
ExpectASTGeneration(u8"\u2200(a,(b,c))\u2208X1 1=2"_c17, u8"\u2200(a, (b, c))\u2208X1 1=2"_c17); u8"\u2200(a, b)\u2208X1 1=2"_c17
);
ExpectASTGeneration(
u8"\u2200(a,b,c)\u2208X1 1=2"_c17,
u8"\u2200(a, b, c)\u2208X1 1=2"_c17
);
ExpectASTGeneration(
u8"\u2200(a,(b,c))\u2208X1 1=2"_c17,
u8"\u2200(a, (b, c))\u2208X1 1=2"_c17
);
} }
TEST_F(UTRSGenerator, FromASTTyped) { TEST_F(UTRSGenerator, FromASTTyped) {
@ -146,56 +261,182 @@ TEST_F(UTRSGenerator, FromASTTyped) {
ExpectASTGeneration("F1[a]", "F1[a]"); ExpectASTGeneration("F1[a]", "F1[a]");
ExpectASTGeneration("F1[S1 , S2 , S3]", "F1[S1, S2, S3]"); ExpectASTGeneration("F1[S1 , S2 , S3]", "F1[S1, S2, S3]");
ExpectASTGeneration(u8"X1 \u2208 X2"_c17, u8"X1\u2208X2"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"X1 \u2209 X2"_c17, u8"X1\u2209X2"_c17); u8"X1 \u2208 X2"_c17,
ExpectASTGeneration(u8"X1 \u2282 X2"_c17, u8"X1\u2282X2"_c17); u8"X1\u2208X2"_c17
ExpectASTGeneration(u8"X1 \u2286 X2"_c17, u8"X1\u2286X2"_c17); );
ExpectASTGeneration(u8"X1 \u2284 X2"_c17, u8"X1\u2284X2"_c17); ExpectASTGeneration(
u8"X1 \u2209 X2"_c17,
u8"X1\u2209X2"_c17
);
ExpectASTGeneration(
u8"X1 \u2282 X2"_c17,
u8"X1\u2282X2"_c17
);
ExpectASTGeneration(
u8"X1 \u2286 X2"_c17,
u8"X1\u2286X2"_c17
);
ExpectASTGeneration(
u8"X1 \u2284 X2"_c17,
u8"X1\u2284X2"_c17
);
ExpectASTGeneration(u8"\u212C\u212C( X1 )"_c17, u8"\u212C\u212C(X1)"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"\u212C(\u212C( X1 ))"_c17, u8"\u212C\u212C(X1)"_c17); u8"\u212C\u212C( X1 )"_c17,
ExpectASTGeneration("Pr1( S1 )", "Pr1(S1)"); u8"\u212C\u212C(X1)"_c17
ExpectASTGeneration("Pr42( S1 )", "Pr42(S1)"); );
ExpectASTGeneration("pr1( a )", "pr1(a)"); ExpectASTGeneration(
ExpectASTGeneration("Fi1,2[ b, c]( a )", "Fi1,2[b, c](a)"); u8"\u212C(\u212C( X1 ))"_c17,
ExpectASTGeneration("pr42( a )", "pr42(a)"); u8"\u212C\u212C(X1)"_c17
ExpectASTGeneration("bool( a )", "bool(a)"); );
ExpectASTGeneration("debool( a )", "debool(a)"); ExpectASTGeneration(
ExpectASTGeneration("red( a )", "red(a)"); "Pr1( S1 )",
"Pr1(S1)"
);
ExpectASTGeneration(
"Pr42( S1 )",
"Pr42(S1)"
);
ExpectASTGeneration(
"pr1( a )",
"pr1(a)"
);
ExpectASTGeneration(
"Fi1,2[ b, c]( a )",
"Fi1,2[b, c](a)"
);
ExpectASTGeneration(
"pr42( a )",
"pr42(a)"
);
ExpectASTGeneration(
"bool( a )",
"bool(a)"
);
ExpectASTGeneration(
"debool( a )",
"debool(a)"
);
ExpectASTGeneration(
"red( a )",
"red(a)"
);
ExpectASTGeneration("(a,b)", "(a, b)"); ExpectASTGeneration(
ExpectASTGeneration("(a,b,c)", "(a, b, c)"); "(a,b)",
ExpectASTGeneration("{a}", "{a}"); "(a, b)"
ExpectASTGeneration("{a, b}", "{a, b}"); );
ExpectASTGeneration("{a,b,c}", "{a, b, c}"); ExpectASTGeneration(
ExpectASTGeneration("{(a,b),c}", "{(a, b), c}"); "(a,b,c)",
"(a, b, c)"
);
ExpectASTGeneration(
"{a}",
"{a}"
);
ExpectASTGeneration(
"{a, b}",
"{a, b}"
);
ExpectASTGeneration(
"{a,b,c}",
"{a, b, c}"
);
ExpectASTGeneration(
"{(a,b),c}",
"{(a, b), c}"
);
ExpectASTGeneration(u8"{a \u2208 X1|1=2}"_c17, u8"D{a\u2208X1 | 1=2}"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"D{(a,b) \u2208 X1|1=2}"_c17, u8"D{(a, b)\u2208X1 | 1=2}"_c17); u8"{a \u2208 X1|1=2}"_c17,
ExpectASTGeneration(u8"D{(a,b,c) \u2208 X1|1=2}"_c17, u8"D{(a, b, c)\u2208X1 | 1=2}"_c17); u8"D{a\u2208X1 | 1=2}"_c17
ExpectASTGeneration(u8"D{(a,(b,c)) \u2208 X1|1=2}"_c17, u8"D{(a, (b, c))\u2208X1 | 1=2}"_c17); );
ExpectASTGeneration(u8"D{((a,b),c) \u2208 X1|1=2}"_c17, u8"D{((a, b), c)\u2208X1 | 1=2}"_c17); ExpectASTGeneration(
ExpectASTGeneration("R{a:=X1 | 1=1| a \\ a}", "R{a:=X1 | 1=1 | a\\a}"); u8"D{(a,b) \u2208 X1|1=2}"_c17,
ExpectASTGeneration(u8"I{ (a,b) | b:\u2208X1; a:= b; 1=1}"_c17, u8"I{(a, b) | b:\u2208X1; a:=b; 1=1}"_c17); u8"D{(a, b)\u2208X1 | 1=2}"_c17
);
ExpectASTGeneration(
u8"D{(a,b,c) \u2208 X1|1=2}"_c17,
u8"D{(a, b, c)\u2208X1 | 1=2}"_c17
);
ExpectASTGeneration(
u8"D{(a,(b,c)) \u2208 X1|1=2}"_c17
, u8"D{(a, (b, c))\u2208X1 | 1=2}"_c17
);
ExpectASTGeneration(
u8"D{((a,b),c) \u2208 X1|1=2}"_c17,
u8"D{((a, b), c)\u2208X1 | 1=2}"_c17
);
ExpectASTGeneration(
"R{a:=X1 | 1=1| a \\ a}",
"R{a:=X1 | 1=1 | a\\a}"
);
ExpectASTGeneration(
u8"I{ (a,b) | b:\u2208X1; a:= b; 1=1}"_c17,
u8"I{(a, b) | b:\u2208X1; a:=b; 1=1}"_c17
);
} }
TEST_F(UTRSGenerator, FromASTTypedOperators) { TEST_F(UTRSGenerator, FromASTTypedOperators) {
ExpectASTGeneration("X1\\(X2\\X3)", "X1\\(X2\\X3)"); ExpectASTGeneration(
ExpectASTGeneration("(X1\\X2)\\X3", "X1\\X2\\X3"); "X1\\(X2\\X3)",
ExpectASTGeneration("X1\\X2\\X3", "X1\\X2\\X3"); "X1\\(X2\\X3)"
ExpectASTGeneration(u8"X1\u222AX2\u222AX3"_c17, u8"X1\u222AX2\u222AX3"_c17); );
ExpectASTGeneration(u8"X1\u2229X2\u2229X3"_c17, u8"X1\u2229X2\u2229X3"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"X1\u2206X2\u2206X3"_c17, u8"X1\u2206X2\u2206X3"_c17); "(X1\\X2)\\X3",
"X1\\X2\\X3"
);
ExpectASTGeneration(
"X1\\X2\\X3",
"X1\\X2\\X3"
);
ExpectASTGeneration(
u8"X1\u222AX2\u222AX3"_c17,
u8"X1\u222AX2\u222AX3"_c17
);
ExpectASTGeneration(
u8"X1\u2229X2\u2229X3"_c17,
u8"X1\u2229X2\u2229X3"_c17
);
ExpectASTGeneration(
u8"X1\u2206X2\u2206X3"_c17,
u8"X1\u2206X2\u2206X3"_c17
);
ExpectASTGeneration(u8"X1\\(X2\u222AX3)"_c17, u8"X1\\(X2\u222AX3)"_c17); ExpectASTGeneration(
u8"X1\\(X2\u222AX3)"_c17,
u8"X1\\(X2\u222AX3)"_c17
);
ExpectASTGeneration(u8"X1\u00D7X2\u00D7X3"_c17, u8"X1\u00D7X2\u00D7X3"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"(X1\u00D7X2)\u00D7X3"_c17, u8"(X1\u00D7X2)\u00D7X3"_c17); u8"X1\u00D7X2\u00D7X3"_c17,
ExpectASTGeneration(u8"X1\u00D7(X2\u00D7X3)"_c17, u8"X1\u00D7(X2\u00D7X3)"_c17); u8"X1\u00D7X2\u00D7X3"_c17
ExpectASTGeneration(u8"X1\u00D7Pr1( S1 )"_c17, u8"X1\u00D7Pr1(S1)"_c17); );
ExpectASTGeneration(u8"Pr1( S1 )\u00D7X1"_c17, u8"Pr1(S1)\u00D7X1"_c17); ExpectASTGeneration(
ExpectASTGeneration(u8"{ S1 }\u00D7X1"_c17, u8"{S1}\u00D7X1"_c17); u8"(X1\u00D7X2)\u00D7X3"_c17,
ExpectASTGeneration(u8"X1\u00D7{ S1 }"_c17, u8"X1\u00D7{S1}"_c17); u8"(X1\u00D7X2)\u00D7X3"_c17
);
ExpectASTGeneration(
u8"X1\u00D7(X2\u00D7X3)"_c17,
u8"X1\u00D7(X2\u00D7X3)"_c17
);
ExpectASTGeneration(
u8"X1\u00D7Pr1( S1 )"_c17,
u8"X1\u00D7Pr1(S1)"_c17
);
ExpectASTGeneration(
u8"Pr1( S1 )\u00D7X1"_c17,
u8"Pr1(S1)\u00D7X1"_c17
);
ExpectASTGeneration(
u8"{ S1 }\u00D7X1"_c17,
u8"{S1}\u00D7X1"_c17
);
ExpectASTGeneration(
u8"X1\u00D7{ S1 }"_c17,
u8"X1\u00D7{S1}"_c17
);
} }
TEST_F(UTRSGenerator, CreateCall) { TEST_F(UTRSGenerator, CreateCall) {
@ -234,12 +475,22 @@ TEST_F(UTRSGenerator, FunctionFromExpression) {
EXPECT_EQ(gen.FunctionFromExpr({}, ""), ""); EXPECT_EQ(gen.FunctionFromExpr({}, ""), "");
EXPECT_EQ(gen.FunctionFromExpr({ "S1" }, ""), ""); EXPECT_EQ(gen.FunctionFromExpr({ "S1" }, ""), "");
EXPECT_EQ(gen.FunctionFromExpr({ "S1" }, "X1\\X1"), u8"[arg1\u2208\u212C(X1)] X1\\X1"_c17); EXPECT_EQ(
EXPECT_EQ(gen.FunctionFromExpr({ "S1" }, "S1\\X1"), u8"[arg1\u2208\u212C(X1)] arg1\\X1"_c17); gen.FunctionFromExpr({ "S1" }, "X1\\X1"),
EXPECT_EQ(gen.FunctionFromExpr({ "S1", "X1" }, "S1\\X1"), u8"[arg1\u2208\u212C(X1)] X1\\X1"_c17
u8"[arg1\u2208\u212C(X1), arg2\u2208\u212C(X1)] arg1\\arg2"_c17); );
EXPECT_EQ(gen.FunctionFromExpr({ "S1" }, u8"{arg1 \u2208 S1 | 1=1}"_c17), EXPECT_EQ(
u8"[arg2\u2208\u212C(X1)] {arg1 \u2208 arg2 | 1=1}"_c17); gen.FunctionFromExpr({ "S1" }, "S1\\X1"),
u8"[arg1\u2208\u212C(X1)] arg1\\X1"_c17
);
EXPECT_EQ(
gen.FunctionFromExpr({ "S1", "X1" }, "S1\\X1"),
u8"[arg1\u2208\u212C(X1), arg2\u2208\u212C(X1)] arg1\\arg2"_c17
);
EXPECT_EQ(
gen.FunctionFromExpr({ "S1" }, u8"{arg1 \u2208 S1 | 1=1}"_c17),
u8"[arg2\u2208\u212C(X1)] {arg1 \u2208 arg2 | 1=1}"_c17
);
} }
TEST_F(UTRSGenerator, GenerateStructure) { TEST_F(UTRSGenerator, GenerateStructure) {
@ -259,20 +510,30 @@ TEST_F(UTRSGenerator, GenerateStructure) {
TEST_F(UTRSGenerator, Ascii2RS) { TEST_F(UTRSGenerator, Ascii2RS) {
using ccl::rslang::ConvertTo; using ccl::rslang::ConvertTo;
EXPECT_EQ(ConvertTo(R"(S1 \in B(X1))", Syntax::MATH), u8"S1\u2208\u212C(X1)"_c17); EXPECT_EQ(
EXPECT_EQ(ConvertTo("B(Y*(X1*X2)*BB(X3))", Syntax::MATH), ConvertTo(R"(S1 \in B(X1))", Syntax::MATH),
u8"\u212C(Y\u00D7(X1\u00D7X2)\u00D7\u212C\u212C(X3))"_c17); u8"S1\u2208\u212C(X1)"_c17
);
EXPECT_EQ(
ConvertTo("B(Y*(X1*X2)*BB(X3))", Syntax::MATH),
u8"\u212C(Y\u00D7(X1\u00D7X2)\u00D7\u212C\u212C(X3))"_c17
);
EXPECT_EQ(ConvertTo(" X1 ", Syntax::MATH), "X1"); EXPECT_EQ(ConvertTo(" X1 ", Syntax::MATH), "X1");
EXPECT_EQ(ConvertTo("a,?b", Syntax::MATH), "a,?b"); EXPECT_EQ(ConvertTo("a,?b", Syntax::MATH), "a,?b");
} }
TEST_F(UTRSGenerator, RS2Ascii) { TEST_F(UTRSGenerator, RS2Ascii) {
EXPECT_EQ(ConvertTo(u8"S1\u2208\u212C(X1)"_c17, Syntax::ASCII), R"(S1 \in B(X1))"); EXPECT_EQ(
EXPECT_EQ(ConvertTo(u8"\u212C(Y\u00D7(X1\u00D7X2)\u00D7\u212C\u212C(X3))"_c17, Syntax::ASCII), ConvertTo(u8"S1\u2208\u212C(X1)"_c17, Syntax::ASCII),
R"(B(Y*(X1*X2)*BB(X3)))"); R"(S1 \in B(X1))"
);
EXPECT_EQ(
ConvertTo(u8"\u212C(Y\u00D7(X1\u00D7X2)\u00D7\u212C\u212C(X3))"_c17, Syntax::ASCII),
R"(B(Y*(X1*X2)*BB(X3)))"
);
EXPECT_EQ(ccl::rslang::ConvertTo(" X1 ", Syntax::ASCII), R"(X1)"); EXPECT_EQ(ConvertTo(" X1 ", Syntax::ASCII), R"(X1)");
EXPECT_EQ(ccl::rslang::ConvertTo("\xE2\x88\x85", Syntax::ASCII), R"({})"); EXPECT_EQ(ConvertTo("\xE2\x88\x85", Syntax::ASCII), R"({})");
EXPECT_EQ(ccl::rslang::ConvertTo("a,?b", Syntax::ASCII), R"(a,?b)"); EXPECT_EQ(ConvertTo("a,?b", Syntax::ASCII), R"(a,?b)");
} }

View File

@ -5,6 +5,7 @@
#include "ccl/rslang/RSParser.h" #include "ccl/rslang/RSParser.h"
#include "ccl/rslang/AsciiLexer.h" #include "ccl/rslang/AsciiLexer.h"
#include "ccl/rslang/ErrorLogger.h" #include "ccl/rslang/ErrorLogger.h"
#include "ccl/rslang/Literals.h"
using ccl::operator""_c17; using ccl::operator""_c17;
@ -100,14 +101,22 @@ TEST_F(UTRSParser, GlobalDeclAST) {
ExpectAST(R"(S1 \deftype B(X1))", u8"[::=[S1][\u212C[X1]]]"_c17); ExpectAST(R"(S1 \deftype B(X1))", u8"[::=[S1][\u212C[X1]]]"_c17);
ExpectAST(R"(D1 \defexpr X1 \setminus X2)", u8"[:==[D1][\\[X1][X2]]]"_c17); ExpectAST(R"(D1 \defexpr X1 \setminus X2)", u8"[:==[D1][\\[X1][X2]]]"_c17);
ExpectAST(R"(A1 \defexpr 1 \eq 1)", u8"[:==[A1][=[1][1]]]"_c17); ExpectAST(R"(A1 \defexpr 1 \eq 1)", u8"[:==[A1][=[1][1]]]"_c17);
ExpectAST(R"(F1 \defexpr [a \in X1] X1 \setminus a)", ExpectAST(
u8"[:==[F1][FUNCTION_DEFINITION[ARGS[ARG[a][X1]]][\\[X1][a]]]]"_c17); R"(F1 \defexpr [a \in X1] X1 \setminus a)",
ExpectAST(R"(P1 \defexpr [a \in X1] 1 \eq 1)", u8"[:==[F1][FUNCTION_DEFINITION[ARGS[ARG[a][X1]]][\\[X1][a]]]]"_c17
u8"[:==[P1][FUNCTION_DEFINITION[ARGS[ARG[a][X1]]][=[1][1]]]]"_c17); );
ExpectAST(R"(F1 \defexpr [a \in X1, b \in X1] {b,a})", ExpectAST(
u8"[:==[F1][FUNCTION_DEFINITION[ARGS[ARG[a][X1]][ARG[b][X1]]][SET[b][a]]]]"_c17); R"(P1 \defexpr [a \in X1] 1 \eq 1)",
ExpectAST(R"(F1 \defexpr [a \in R1, b \in B(X1*R1)] {a} \setminus Pr2(b))", u8"[:==[P1][FUNCTION_DEFINITION[ARGS[ARG[a][X1]]][=[1][1]]]]"_c17
u8"[:==[F1][FUNCTION_DEFINITION[ARGS[ARG[a][R1]][ARG[b][\u212C[\u00D7[X1][R1]]]]][\\[SET[a]][Pr2[b]]]]]"_c17); );
ExpectAST(
R"(F1 \defexpr [a \in X1, b \in X1] {b,a})",
u8"[:==[F1][FUNCTION_DEFINITION[ARGS[ARG[a][X1]][ARG[b][X1]]][SET[b][a]]]]"_c17
);
ExpectAST(
R"(F1 \defexpr [a \in R1, b \in B(X1*R1)] {a} \setminus Pr2(b))",
u8"[:==[F1][FUNCTION_DEFINITION[ARGS[ARG[a][R1]][ARG[b][\u212C[\u00D7[X1][R1]]]]][\\[SET[a]][Pr2[b]]]]]"_c17
);
} }
TEST_F(UTRSParser, GlobalDeclErrors) { TEST_F(UTRSParser, GlobalDeclErrors) {
@ -138,6 +147,7 @@ TEST_F(UTRSParser, LogicPredicatesCorrect) {
} }
TEST_F(UTRSParser, LogicPredicatesAST) { TEST_F(UTRSParser, LogicPredicatesAST) {
ExpectAST(R"(a \in X1)", u8"[\u2208[a][X1]]"_c17);
ExpectAST(R"(1 \eq 2)", u8"[=[1][2]]"_c17); ExpectAST(R"(1 \eq 2)", u8"[=[1][2]]"_c17);
ExpectAST(R"(1 \ls X1)", u8"[<[1][X1]]"_c17); ExpectAST(R"(1 \ls X1)", u8"[<[1][X1]]"_c17);
ExpectAST(R"(1 \gr 2)", u8"[>[1][2]]"_c17); ExpectAST(R"(1 \gr 2)", u8"[>[1][2]]"_c17);
@ -150,6 +160,8 @@ TEST_F(UTRSParser, LogicPredicatesErrors) {
ExpectError(R"(1 \eq 1 \eq 1)", ParseEID::syntax, 8); ExpectError(R"(1 \eq 1 \eq 1)", ParseEID::syntax, 8);
ExpectError(R"(1 \gr 1 \eq 1)", ParseEID::syntax, 8); ExpectError(R"(1 \gr 1 \eq 1)", ParseEID::syntax, 8);
ExpectError(R"(P1[])", ParseEID::syntax, 3); ExpectError(R"(P1[])", ParseEID::syntax, 3);
ExpectError(R"(a \assign X1)", ParseEID::invalidImperative, 0);
ExpectError(R"(a \from X1)", ParseEID::invalidImperative, 0);
} }
TEST_F(UTRSParser, LogicOperatorsCorrect) { TEST_F(UTRSParser, LogicOperatorsCorrect) {
@ -170,16 +182,39 @@ TEST_F(UTRSParser, LogicOperatorsCorrect) {
TEST_F(UTRSParser, LogicOperatorsAST) { TEST_F(UTRSParser, LogicOperatorsAST) {
ExpectAST(R"(\neg 1 \eq 2)", u8"[\u00AC[=[1][2]]]"_c17); ExpectAST(R"(\neg 1 \eq 2)", u8"[\u00AC[=[1][2]]]"_c17);
ExpectAST(R"(1 \eq 1 \and 2 \eq 2 \and 3 \eq 3)", "[&[&[=[1][1]][=[2][2]]][=[3][3]]]"); ExpectAST(
ExpectAST(R"(1 \eq 1 \or 2 \eq 2 \or 3 \eq 3)", u8"[\u2228[\u2228[=[1][1]][=[2][2]]][=[3][3]]]"_c17); R"(1 \eq 1 \and 2 \eq 2 \and 3 \eq 3)",
ExpectAST(R"(1 \eq 1 \impl 2 \eq 2 \impl 3 \eq 3)", u8"[\u21D2[\u21D2[=[1][1]][=[2][2]]][=[3][3]]]"_c17); "[&[&[=[1][1]][=[2][2]]][=[3][3]]]"
ExpectAST(R"(1 \eq 1 \equiv 2 \eq 2 \equiv 3 \eq 3)", u8"[\u21D4[\u21D4[=[1][1]][=[2][2]]][=[3][3]]]"_c17); );
ExpectAST(
R"(1 \eq 1 \or 2 \eq 2 \or 3 \eq 3)",
u8"[\u2228[\u2228[=[1][1]][=[2][2]]][=[3][3]]]"_c17
);
ExpectAST(
R"(1 \eq 1 \impl 2 \eq 2 \impl 3 \eq 3)",
u8"[\u21D2[\u21D2[=[1][1]][=[2][2]]][=[3][3]]]"_c17
);
ExpectAST(
R"(1 \eq 1 \equiv 2 \eq 2 \equiv 3 \eq 3)",
u8"[\u21D4[\u21D4[=[1][1]][=[2][2]]][=[3][3]]]"_c17
);
ExpectAST(R"((1 \eq 1 \and 2 \eq 2) \and 3 \eq 3)", "[&[&[=[1][1]][=[2][2]]][=[3][3]]]"); ExpectAST(
ExpectAST(R"(1 \eq 1 \and (2 \eq 2 \and 3 \eq 3))", "[&[=[1][1]][&[=[2][2]][=[3][3]]]]"); R"((1 \eq 1 \and 2 \eq 2) \and 3 \eq 3)",
ExpectAST(R"(1 \eq 1 \or 2 \eq 2 \and 3 \eq 3)", u8"[\u2228[=[1][1]][&[=[2][2]][=[3][3]]]]"_c17); "[&[&[=[1][1]][=[2][2]]][=[3][3]]]"
ExpectAST(R"(1 \eq 1 \and 2 \eq 2 \or 3 \eq 3 \impl 4 \eq 4 \equiv 5 \eq 5)", );
u8"[\u21D4[\u21D2[\u2228[&[=[1][1]][=[2][2]]][=[3][3]]][=[4][4]]][=[5][5]]]"_c17); ExpectAST(
R"(1 \eq 1 \and (2 \eq 2 \and 3 \eq 3))",
"[&[=[1][1]][&[=[2][2]][=[3][3]]]]"
);
ExpectAST(
R"(1 \eq 1 \or 2 \eq 2 \and 3 \eq 3)",
u8"[\u2228[=[1][1]][&[=[2][2]][=[3][3]]]]"_c17
);
ExpectAST(
R"(1 \eq 1 \and 2 \eq 2 \or 3 \eq 3 \impl 4 \eq 4 \equiv 5 \eq 5)",
u8"[\u21D4[\u21D2[\u2228[&[=[1][1]][=[2][2]]][=[3][3]]][=[4][4]]][=[5][5]]]"_c17
);
} }
TEST_F(UTRSParser, LogicOperatorsErrors) { TEST_F(UTRSParser, LogicOperatorsErrors) {
@ -204,20 +239,35 @@ TEST_F(UTRSParser, LogicQuantifiedCorrect) {
ExpectNoWarnings(R"(\A a \in X1 \A b \in X1 1 \eq 1)"); ExpectNoWarnings(R"(\A a \in X1 \A b \in X1 1 \eq 1)");
ExpectNoWarnings(R"(\A a,b,c \in X1 1 \eq 1)"); ExpectNoWarnings(R"(\A a,b,c \in X1 1 \eq 1)");
ExpectNoWarnings(R"(\A a,b,c,d \in X1 1 \eq 1)");
ExpectNoWarnings(R"(\A (a,b,c) \in X1 1 \eq 1)"); ExpectNoWarnings(R"(\A (a,b,c) \in X1 1 \eq 1)");
ExpectNoWarnings(R"(\A (a,(b,d),c) \in X1 1 \eq 1)");
} }
TEST_F(UTRSParser, LogicQuantifiedAST) { TEST_F(UTRSParser, LogicQuantifiedAST) {
ExpectAST(R"(\A a \in X1 1 \eq 2)", u8"[\u2200[a][X1][=[1][2]]]"_c17); ExpectAST(
ExpectAST(R"(\A a,b \in X1 1 \eq 2)", u8"[\u2200[ENUM_DECLARATION[a][b]][X1][=[1][2]]]"_c17); R"(\A a \in X1 1 \eq 2)",
ExpectAST(R"(\A a \in X1 1 \eq 2 \and 3 \eq 4)", u8"[&[\u2200[a][X1][=[1][2]]][=[3][4]]]"_c17); u8"[\u2200[a][X1][=[1][2]]]"_c17
ExpectAST(R"(\A a \in X1 (1 \eq 2 \and 3 \eq 4))", u8"[\u2200[a][X1][&[=[1][2]][=[3][4]]]]"_c17); );
ExpectAST(
R"(\A a,b \in X1 1 \eq 2)",
u8"[\u2200[ENUM_DECLARATION[a][b]][X1][=[1][2]]]"_c17
);
ExpectAST(
R"(\A a \in X1 1 \eq 2 \and 3 \eq 4)",
u8"[&[\u2200[a][X1][=[1][2]]][=[3][4]]]"_c17
);
ExpectAST(
R"(\A a \in X1 (1 \eq 2 \and 3 \eq 4))",
u8"[\u2200[a][X1][&[=[1][2]][=[3][4]]]]"_c17
);
} }
TEST_F(UTRSParser, LogicQuantifiedErrors) { TEST_F(UTRSParser, LogicQuantifiedErrors) {
ExpectError(R"(\A a \in X1, \A b \in X1 1 \eq 1)", ParseEID::invalidQuantifier, 11); ExpectError(R"(\A a \in X1, \A b \in X1 1 \eq 1)", ParseEID::invalidQuantifier, 11);
ExpectError(R"(\A ()", ParseEID::invalidQuantifier, 4); ExpectError(R"(\A ()", ParseEID::invalidQuantifier, 4);
ExpectError(R"(\A (a,X1) \in X1 1 \eq 1)", ParseEID::expectedLocal, 6); ExpectError(R"(\A (a,X1) \in X1 1 \eq 1)", ParseEID::expectedLocal, 6);
ExpectError(R"(\A ((a,X1),b) \in X1 1 \eq 1)", ParseEID::expectedLocal, 7);
ExpectError(R"(\A a \notsubset X1 1 \eq 1)", ParseEID::invalidQuantifier, 5); ExpectError(R"(\A a \notsubset X1 1 \eq 1)", ParseEID::invalidQuantifier, 5);
ExpectError(R"(\A a \notin X1 1 \eq 1)", ParseEID::invalidQuantifier, 5); ExpectError(R"(\A a \notin X1 1 \eq 1)", ParseEID::invalidQuantifier, 5);
ExpectError(R"(\A a \subset X1 1 \eq 2)", ParseEID::invalidQuantifier, 5); ExpectError(R"(\A a \subset X1 1 \eq 2)", ParseEID::invalidQuantifier, 5);
@ -249,7 +299,7 @@ TEST_F(UTRSParser, Identifiers) {
ExpectNoWarnings(R"(hello_world)"); ExpectNoWarnings(R"(hello_world)");
} }
TEST_F(UTRSParser, TermOperatorsCorrect) { TEST_F(UTRSParser, SetexprOperatorsCorrect) {
TestAllBinaryCombos(R"( \plus )"); TestAllBinaryCombos(R"( \plus )");
TestAllBinaryCombos(R"( \minus )"); TestAllBinaryCombos(R"( \minus )");
TestAllBinaryCombos(R"( \multiply )"); TestAllBinaryCombos(R"( \multiply )");
@ -270,7 +320,7 @@ TEST_F(UTRSParser, TermOperatorsCorrect) {
TestAllBinaryCombos(R"( * )"); TestAllBinaryCombos(R"( * )");
} }
TEST_F(UTRSParser, TermOperatorsAST) { TEST_F(UTRSParser, SetexprOperatorsAST) {
ExpectAST(R"(1 \plus 2 \plus 3)", "[+[+[1][2]][3]]"); ExpectAST(R"(1 \plus 2 \plus 3)", "[+[+[1][2]][3]]");
ExpectAST(R"((1 \plus 2) \plus 3)", "[+[+[1][2]][3]]"); ExpectAST(R"((1 \plus 2) \plus 3)", "[+[+[1][2]][3]]");
ExpectAST(R"(1 \plus (2 \plus 3))", "[+[1][+[2][3]]]"); ExpectAST(R"(1 \plus (2 \plus 3))", "[+[1][+[2][3]]]");
@ -284,11 +334,13 @@ TEST_F(UTRSParser, TermOperatorsAST) {
ExpectAST(R"(a \setminus b \setminus c)", "[\\[\\[a][b]][c]]"); ExpectAST(R"(a \setminus b \setminus c)", "[\\[\\[a][b]][c]]");
ExpectAST(R"((a \setminus b) \setminus c)", "[\\[\\[a][b]][c]]"); ExpectAST(R"((a \setminus b) \setminus c)", "[\\[\\[a][b]][c]]");
ExpectAST(R"(a \setminus (b \setminus c))", "[\\[a][\\[b][c]]]"); ExpectAST(R"(a \setminus (b \setminus c))", "[\\[a][\\[b][c]]]");
ExpectAST(R"(((a \union b) \intersect (c \setminus d)) \symmdiff (e * f))", ExpectAST(
u8"[\u2206[\u2229[\u222A[a][b]][\\[c][d]]][\u00D7[e][f]]]"_c17); R"(((a \union b) \intersect (c \setminus d)) \symmdiff (e * f))",
u8"[\u2206[\u2229[\u222A[a][b]][\\[c][d]]][\u00D7[e][f]]]"_c17
);
} }
TEST_F(UTRSParser, TermOperatorsErrors) { TEST_F(UTRSParser, SetexprOperatorsErrors) {
ExpectError(R"(1 \plus \plus )", ParseEID::syntax, 9); ExpectError(R"(1 \plus \plus )", ParseEID::syntax, 9);
ExpectError(R"(1 \minus \minus )", ParseEID::syntax, 10); ExpectError(R"(1 \minus \minus )", ParseEID::syntax, 10);
@ -301,7 +353,7 @@ TEST_F(UTRSParser, TermOperatorsErrors) {
ExpectError(R"(X1 \setminus (1))", ParseEID::syntax, 15); ExpectError(R"(X1 \setminus (1))", ParseEID::syntax, 15);
} }
TEST_F(UTRSParser, TermTextOperationsCorrect) { TEST_F(UTRSParser, SetexprTextOperationsCorrect) {
ExpectNoWarnings(R"(card(X1))"); ExpectNoWarnings(R"(card(X1))");
ExpectNoWarnings(R"(card(1))"); ExpectNoWarnings(R"(card(1))");
ExpectNoWarnings(R"(card(a))"); ExpectNoWarnings(R"(card(a))");
@ -317,18 +369,18 @@ TEST_F(UTRSParser, TermTextOperationsCorrect) {
ExpectNoWarnings(R"(red(a))"); ExpectNoWarnings(R"(red(a))");
} }
TEST_F(UTRSParser, TermTextOperationsAST) { TEST_F(UTRSParser, SetexprTextOperationsAST) {
ExpectAST(R"(card(X1))", u8"[card[X1]]"_c17); ExpectAST(R"(card(X1))", u8"[card[X1]]"_c17);
ExpectAST(R"(Pr2(a))", u8"[Pr2[a]]"_c17); ExpectAST(R"(Pr2(a))", u8"[Pr2[a]]"_c17);
ExpectAST(R"(Fi1,2[b](a))", u8"[Fi1,2[b][a]]"_c17); ExpectAST(R"(Fi1,2[b](a))", u8"[Fi1,2[b][a]]"_c17);
} }
TEST_F(UTRSParser, TermTextOperationsErrors) { TEST_F(UTRSParser, SetexprTextOperationsErrors) {
ExpectError(R"(Pr1,b(a))", ParseEID::syntax, 3); ExpectError(R"(Pr1,b(a))", ParseEID::syntax, 3);
ExpectError(R"(Fi1,b[c](a))", ParseEID::syntax, 3); ExpectError(R"(Fi1,b[c](a))", ParseEID::syntax, 3);
} }
TEST_F(UTRSParser, TermConstructorsCorrect) { TEST_F(UTRSParser, SetexprConstructorsCorrect) {
ExpectNoWarnings(R"(B(a))"); ExpectNoWarnings(R"(B(a))");
ExpectNoWarnings(R"(B(a*b*(c*d)))"); ExpectNoWarnings(R"(B(a*b*(c*d)))");
ExpectNoWarnings(R"(BB(a))"); ExpectNoWarnings(R"(BB(a))");
@ -352,9 +404,10 @@ TEST_F(UTRSParser, TermConstructorsCorrect) {
ExpectNoWarnings(R"(I{(b, a) | a \from X1; b \assign a})"); ExpectNoWarnings(R"(I{(b, a) | a \from X1; b \assign a})");
ExpectNoWarnings(R"(I{ red(b) | a \from X1; b \assign a})"); ExpectNoWarnings(R"(I{ red(b) | a \from X1; b \assign a})");
ExpectNoWarnings(R"(I{(a, b) | a \from X1; b \assign a; (a,b) \in S1})"); ExpectNoWarnings(R"(I{(a, b) | a \from X1; b \assign a; (a,b) \in S1})");
ExpectNoWarnings(R"(I{(a, d) | (a,c) \from X1*X1; (b,d) \assign (a,c); (a,b) \in S1})");
} }
TEST_F(UTRSParser, TermConstructorsAST) { TEST_F(UTRSParser, SetexprConstructorsAST) {
ExpectAST(R"(B(a))", u8"[\u212C[a]]"_c17); ExpectAST(R"(B(a))", u8"[\u212C[a]]"_c17);
ExpectAST(R"((a,b,c))", u8"[TUPLE[a][b][c]]"_c17); ExpectAST(R"((a,b,c))", u8"[TUPLE[a][b][c]]"_c17);
@ -362,25 +415,43 @@ TEST_F(UTRSParser, TermConstructorsAST) {
ExpectAST(R"({{a, b}, {c, d}})", u8"[SET[SET[a][b]][SET[c][d]]]"_c17); ExpectAST(R"({{a, b}, {c, d}})", u8"[SET[SET[a][b]][SET[c][d]]]"_c17);
ExpectAST(R"({a})", u8"[SET[a]]"_c17); ExpectAST(R"({a})", u8"[SET[a]]"_c17);
ExpectAST(R"(D{a \in X1 | 1 \eq 2})", ExpectAST(
u8"[DECLARATIVE[a][X1][=[1][2]]]"_c17); R"(D{a \in X1 | 1 \eq 2})",
ExpectAST(R"(D{(a,b) \in X1 | 1 \eq 2})", u8"[DECLARATIVE[a][X1][=[1][2]]]"_c17
u8"[DECLARATIVE[TUPLE_DECLARATION[a][b]][X1][=[1][2]]]"_c17); );
ExpectAST(
R"(D{(a,b) \in X1 | 1 \eq 2})",
u8"[DECLARATIVE[TUPLE_DECLARATION[a][b]][X1][=[1][2]]]"_c17
);
ExpectAST(R"(R{a \assign S1 | card(a) \ls 10 | a \setminus a})", ExpectAST(
u8"[REC_FULL[a][S1][<[card[a]][10]][\\[a][a]]]"_c17); R"(R{a \assign S1 | card(a) \ls 10 | a \setminus a})",
ExpectAST(R"(R{a \assign S1 | a \setminus a})", u8"[REC_FULL[a][S1][<[card[a]][10]][\\[a][a]]]"_c17
u8"[REC_SHORT[a][S1][\\[a][a]]]"_c17); );
ExpectAST(R"(R{(a,b) \assign S1 | (a \setminus a, b)})", ExpectAST(
u8"[REC_SHORT[TUPLE_DECLARATION[a][b]][S1][TUPLE[\\[a][a]][b]]]"_c17); R"(R{a \assign S1 | a \setminus a})",
u8"[REC_SHORT[a][S1][\\[a][a]]]"_c17
);
ExpectAST(
R"(R{(a,b) \assign S1 | (a \setminus a, b)})",
u8"[REC_SHORT[TUPLE_DECLARATION[a][b]][S1][TUPLE[\\[a][a]][b]]]"_c17
);
ExpectAST(R"(I{(a, b) | a \from X1; b \assign a})", ExpectAST(
u8"[IMPERATIVE[TUPLE[a][b]][IDECLARE[a][X1]][IASSIGN[b][a]]]"_c17); R"(I{(a, b) | a \from X1; b \assign a})",
ExpectAST(R"(I{(a, b) | a \from X1; b \assign a; (a,b) \in S1})", u8"[IMPERATIVE[TUPLE[a][b]][:\u2208[a][X1]][:=[b][a]]]"_c17
u8"[IMPERATIVE[TUPLE[a][b]][IDECLARE[a][X1]][IASSIGN[b][a]][ICHECK[\u2208[TUPLE[a][b]][S1]]]]"_c17); );
ExpectAST(
R"(I{(a, b) | a \from X1; b \assign a; (a,b) \in S1})",
u8"[IMPERATIVE[TUPLE[a][b]][:\u2208[a][X1]][:=[b][a]][\u2208[TUPLE[a][b]][S1]]]"_c17
);
ExpectAST(
R"(I{d | (a,b) \from X1; (c,(d,e)) \assign a; (c,e) \in S1})",
u8"[IMPERATIVE[d][:\u2208[TUPLE_DECLARATION[a][b]][X1]][:=[TUPLE_DECLARATION[c][TUPLE_DECLARATION[d][e]]][a]][\u2208[TUPLE[c][e]][S1]]]"_c17
);
} }
TEST_F(UTRSParser, TermConstructorsErrors) { TEST_F(UTRSParser, SetexprConstructorsErrors) {
ExpectError(R"({(a;b) \in X1 | 1 \eq 1})", ParseEID::syntax, 3); ExpectError(R"({(a;b) \in X1 | 1 \eq 1})", ParseEID::syntax, 3);
ExpectError(R"(D{a \in X1 | 1 \eq 1 a)", ParseEID::missingCurlyBrace, 21); ExpectError(R"(D{a \in X1 | 1 \eq 1 a)", ParseEID::missingCurlyBrace, 21);
@ -408,8 +479,14 @@ TEST_F(UTRSParser, FunctionDefinitionCorrect) {
} }
TEST_F(UTRSParser, FunctionDefinitionAST) { TEST_F(UTRSParser, FunctionDefinitionAST) {
ExpectAST(R"([a \in X1, b \in X1] a \eq b)", u8"[FUNCTION_DEFINITION[ARGS[ARG[a][X1]][ARG[b][X1]]][=[a][b]]]"_c17); ExpectAST(
ExpectAST(R"([a \in X1, b \in X1] a \setminus b)", u8"[FUNCTION_DEFINITION[ARGS[ARG[a][X1]][ARG[b][X1]]][\\[a][b]]]"_c17); R"([a \in X1, b \in X1] a \eq b)",
u8"[FUNCTION_DEFINITION[ARGS[ARG[a][X1]][ARG[b][X1]]][=[a][b]]]"_c17
);
ExpectAST(
R"([a \in X1, b \in X1] a \setminus b)",
u8"[FUNCTION_DEFINITION[ARGS[ARG[a][X1]][ARG[b][X1]]][\\[a][b]]]"_c17
);
} }
TEST_F(UTRSParser, FunctionDefinitionErrors) { TEST_F(UTRSParser, FunctionDefinitionErrors) {

View File

@ -129,16 +129,43 @@ TEST_F(UTRSToken, TokenToString) {
TEST_F(UTRSToken, TokenToStringUnicode) { TEST_F(UTRSToken, TokenToStringUnicode) {
using ccl::operator""_c17; using ccl::operator""_c17;
EXPECT_EQ("p1", Token(TokenID::ID_LOCAL, StrRange{}, TokenData{ u8"\u03C01"_c17 }).ToString(Syntax::ASCII)); EXPECT_EQ(
EXPECT_EQ("aw", Token(TokenID::ID_LOCAL, StrRange{}, TokenData{ u8"\u03B1\u03C9"_c17 }).ToString(Syntax::ASCII)); Token(TokenID::ID_LOCAL, StrRange{}, TokenData{ u8"\u03C01"_c17 }).ToString(Syntax::ASCII),
EXPECT_EQ("qu?u?p", Token(TokenID::ID_LOCAL, StrRange{}, TokenData{ u8"\u03F0"_c17 }).ToString(Syntax::ASCII)); "p1"
);
EXPECT_EQ(
Token(TokenID::ID_LOCAL, StrRange{}, TokenData{ u8"\u03B1\u03C9"_c17 }).ToString(Syntax::ASCII),
"aw"
);
EXPECT_EQ(
Token(TokenID::ID_LOCAL, StrRange{}, TokenData{ u8"\u03F0"_c17 }).ToString(Syntax::ASCII),
"qu?u?p"
);
} }
TEST_F(UTRSToken, CompareOperations) { TEST_F(UTRSToken, CompareOperations) {
EXPECT_EQ(Token::CompareOperations(TokenID::INTERRUPT, TokenID::INTERRUPT), Comparison::INCOMPARABLE); EXPECT_EQ(
EXPECT_EQ(Token::CompareOperations(TokenID::ID_LOCAL, TokenID::ID_LOCAL), Comparison::INCOMPARABLE); Token::CompareOperations(TokenID::INTERRUPT, TokenID::INTERRUPT),
EXPECT_EQ(Token::CompareOperations(TokenID::ID_LOCAL, TokenID::PLUS), Comparison::INCOMPARABLE); Comparison::INCOMPARABLE
EXPECT_EQ(Token::CompareOperations(TokenID::PLUS, TokenID::MINUS), Comparison::EQUAL); );
EXPECT_EQ(Token::CompareOperations(TokenID::MULTIPLY, TokenID::MINUS), Comparison::GREATER); EXPECT_EQ(
EXPECT_EQ(Token::CompareOperations(TokenID::MINUS, TokenID::MULTIPLY), Comparison::LESS); Token::CompareOperations(TokenID::ID_LOCAL, TokenID::ID_LOCAL),
Comparison::INCOMPARABLE
);
EXPECT_EQ(
Token::CompareOperations(TokenID::ID_LOCAL, TokenID::PLUS),
Comparison::INCOMPARABLE
);
EXPECT_EQ(
Token::CompareOperations(TokenID::PLUS, TokenID::MINUS),
Comparison::EQUAL
);
EXPECT_EQ(
Token::CompareOperations(TokenID::MULTIPLY, TokenID::MINUS),
Comparison::GREATER
);
EXPECT_EQ(
Token::CompareOperations(TokenID::MINUS, TokenID::MULTIPLY),
Comparison::LESS
);
} }

View File

@ -254,6 +254,7 @@ TEST_F(UTTypeAuditor, ConstructorsCorrect) {
ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a})", "B(X1*X1)"_t); ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a})", "B(X1*X1)"_t);
ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a; 1 \eq 1})", "B(X1*X1)"_t); ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a; 1 \eq 1})", "B(X1*X1)"_t);
ExpectTypification(R"(I{(a, c) | (a,c) \from X1*X1; (b,d) \assign (a,a); d \eq b})", "B(X1*X1)"_t);
} }
TEST_F(UTTypeAuditor, ConstructorsErrors) { TEST_F(UTTypeAuditor, ConstructorsErrors) {
@ -276,6 +277,8 @@ TEST_F(UTTypeAuditor, ConstructorsErrors) {
ExpectError(R"(I{(a, b) | a \from X1; b \assign {a}; a \noteq b})", SemanticEID::typesNotCompatible, 47); ExpectError(R"(I{(a, b) | a \from X1; b \assign {a}; a \noteq b})", SemanticEID::typesNotCompatible, 47);
ExpectError(R"(I{(a, b) | a \from X1; g \in a \setminus X2; b \assign {a}})", SemanticEID::invalidTypeOperation, 29); ExpectError(R"(I{(a, b) | a \from X1; g \in a \setminus X2; b \assign {a}})", SemanticEID::invalidTypeOperation, 29);
ExpectError(R"(I{(a, c) | a \from X1; (a,c) \assign (a,a)})", SemanticEID::localShadowing, 24);
ExpectError(R"(I{(a, c) | a \from X1; (a,c) \from X1*X1})", SemanticEID::localShadowing, 24);
} }
TEST_F(UTTypeAuditor, TypedPredicatesCorrect) { TEST_F(UTTypeAuditor, TypedPredicatesCorrect) {