diff --git a/instance_of_parseExprFromStr/.keep b/instance_of_parseExprFromStr/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/instance_of_parseExprFromStr/include/.keep b/instance_of_parseExprFromStr/include/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/instance_of_parseExprFromStr/include/basic.hpp b/instance_of_parseExprFromStr/include/basic.hpp new file mode 100644 index 0000000000000000000000000000000000000000..617b363136179aa67600799056d54b11053f9314 --- /dev/null +++ b/instance_of_parseExprFromStr/include/basic.hpp @@ -0,0 +1,198 @@ +#ifndef _BASIC +#define _BASIC +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//===----------------------------------------------------------------------===// +// Abstract Syntax Tree (aka Parse Tree) +//===----------------------------------------------------------------------===// + +// namespace +// { + +/// ExprAST - Base class for all expression nodes. +class ExprAST +{ +public: + virtual ~ExprAST() = default; + + virtual void printExpr() { fprintf(stderr, "the base class for expression\n"); } + + virtual std::string type() { return "Base"; } + + virtual std::unique_ptr Clone() { return std::make_unique(); } +}; + +/// NumberExprAST - Expression class for numeric literals like "1.0". +class NumberExprAST : public ExprAST +{ + double Val; + +public: + NumberExprAST(double Val) : Val(Val) {} + + void printExpr() { fprintf(stderr, "num = %f\n", Val); } + + std::string type() { return "Number"; } + + double getNumber() { return Val; } + + std::unique_ptr Clone() { return std::make_unique(Val); } +}; + +/// VariableExprAST - Expression class for referencing a variable, like "a". +class VariableExprAST : public ExprAST +{ + std::string Name; + +public: + VariableExprAST(const std::string &Name) : Name(Name) {} + + void printExpr() { fprintf(stderr, "variable = %s\n", Name.c_str()); } + + std::string type() { return "Variable"; } + + std::string getVariable() { return Name; } + + std::unique_ptr Clone() { return std::make_unique(Name); } +}; + +/// BinaryExprAST - Expression class for a binary operator. +class BinaryExprAST : public ExprAST +{ + char Op; + std::unique_ptr LHS, RHS; + +public: + BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} + + void printExpr() + { + fprintf(stderr, "op = %c\n", Op); + LHS->printExpr(); + RHS->printExpr(); + } + + std::string type() { return "Binary"; } + + char getOp() { return Op; } + void setOp(char opNew) { Op = opNew; } + std::unique_ptr &getLHS() { return LHS; } + std::unique_ptr &getRHS() { return RHS; } + + void setLHS(std::unique_ptr &newLHS) { LHS = newLHS->Clone(); } + void setRHS(std::unique_ptr &newRHS) { RHS = newRHS->Clone(); } + + std::unique_ptr Clone() + { + auto LHSNew = LHS->Clone(); + auto RHSNew = RHS->Clone(); + return std::make_unique(Op, std::move(LHSNew), std::move(RHSNew)); + } +}; + +/// CallExprAST - Expression class for function calls. +class CallExprAST : public ExprAST +{ + std::string Callee; + std::vector> Args; + +public: + CallExprAST(const std::string &Callee, std::vector> Args) : Callee(Callee), Args(std::move(Args)) {} + + void printExpr() + { + fprintf(stderr, "call function name = %s\n", Callee.c_str()); + fprintf(stderr, "call function args =\n"); + for (long unsigned int i = 0; i < Args.size(); ++i) + { + (Args[i])->printExpr(); + } + } + + std::string type() { return "Call"; } + + std::string getCallee() { return Callee; } + std::vector> &getArgs() { return Args; } + + std::unique_ptr Clone() + { + std::vector> ArgsNew; + for (long unsigned int i = 0; i < Args.size(); ++i) + { + auto arg = (Args.at(i))->Clone(); + ArgsNew.push_back(std::move(arg)); + } + + return std::make_unique(Callee, std::move(ArgsNew)); + } +}; + +/// PrototypeAST - This class represents the "prototype" for a function, +/// which captures its name, and its argument names (thus implicitly the number +/// of arguments the function takes). +class PrototypeAST +{ + std::string Name; + std::vector Args; + +public: + PrototypeAST(const std::string &Name, std::vector Args) : Name(Name), Args(std::move(Args)) {} + + const std::string &getName() const { return Name; } + const std::vector &getArgs() const { return Args; } +}; + +/// FunctionAST - This class represents a function definition itself. +class FunctionAST +{ + std::unique_ptr Proto; + std::unique_ptr Body; + +public: + FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} + + const std::string &getFuncName() const { return Proto->getName(); } + const std::vector &getFuncArgs() const { return Proto->getArgs(); } + std::unique_ptr &getFuncBody() { return Body; } +}; + +//===----------------------------------------------------------------------===// +// basic operation +//===----------------------------------------------------------------------===// + +bool isEqual(const std::unique_ptr &expr1, const std::unique_ptr &expr2); + +bool isFraction(const std::unique_ptr &expr); + +std::unique_ptr getNumerator(const std::unique_ptr &expr); + +std::unique_ptr getDenominator(const std::unique_ptr &expr); + +std::unique_ptr createBinaryExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2, const char op); + +std::unique_ptr addExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2); + +std::unique_ptr mulExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2); + +std::unique_ptr divExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2); + +//===----------------------------------------------------------------------===// +// print information +//===----------------------------------------------------------------------===// + +std::string PrintExpression(std::unique_ptr &expr); + +void PrintFunction(std::unique_ptr &fun); + +// } // end anonymous namespace + +#endif \ No newline at end of file diff --git a/instance_of_parseExprFromStr/include/laxerASTLY.hpp b/instance_of_parseExprFromStr/include/laxerASTLY.hpp new file mode 100644 index 0000000000000000000000000000000000000000..77943da3c591b4c9d9f68fbc81aa8b2a57f9ae00 --- /dev/null +++ b/instance_of_parseExprFromStr/include/laxerASTLY.hpp @@ -0,0 +1,51 @@ +#ifndef _LAXERASTLY +#define _LAXERASTLY + +#include "basic.hpp" +#include "string.h" + + + +enum Token1 +{ + tok_eof_forstr = -1, + + // commands + tok_def_forstr = -2, + tok_extern_forstr = -3, + + // primary + tok_identifier_forstr = -4, + tok_number_forstr = -5 +}; +extern std::string filestring; +extern int flag; +extern int CurTokForStr; +extern std::string IdentifierStr1; // Filled in if tok_identifier +extern double NumVal1; // Filled in if tok_number + +/// gettok - Return the next token from standard input. +int gettokForStr(); + +/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current +/// token the parser is looking at. getNextToken reads another token from the +/// lexer and updates CurTok with its results. +extern int CurTokForStr; +int getNextTokenForStr(); + +/// BinopPrecedenceForStr - This holds the precedence for each binary operator that is +/// defined. +extern std::map BinopPrecedenceForStr; + +// Install standard binary operators. +void installOperatorsForStr(); + +/// GetTokPrecedenceForStr - Get the precedence of the pending binary operator token. +int GetTokPrecedenceForStr(); + +/// LogError* - These are little helper functions for error handling. +std::unique_ptr LogErrorForStr(const char *Str); + +std::unique_ptr LogErrorPForStr(const char *Str); + +#endif \ No newline at end of file diff --git a/instance_of_parseExprFromStr/include/parserASTLY.hpp b/instance_of_parseExprFromStr/include/parserASTLY.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b3b0f877b2e1ae0234c9de242626706ef8d0cfd0 --- /dev/null +++ b/instance_of_parseExprFromStr/include/parserASTLY.hpp @@ -0,0 +1,46 @@ +#ifndef _PARSERASTLY +#define _PARSERASTLY + +#include "basic.hpp" + +#include +#include +#include + +//===----------------------------------------------------------------------===// +// Parser +//===----------------------------------------------------------------------===// + +std::unique_ptr ParseExpressionForStr(); + +/// numberexpr ::= number +std::unique_ptr ParseNumberExprForStr(); + +/// parenexpr ::= '(' expression ')' +std::unique_ptr ParseParenExprForStr(); + +/// identifierexpr +/// ::= identifier +/// ::= identifier '(' expression* ')' +std::unique_ptr ParseIdentifierExprForStr(); + +/// primary +/// ::= identifierexpr +/// ::= numberexpr +/// ::= parenexpr +std::unique_ptr ParsePrimaryForStr(); + +/// binoprhs +/// ::= ('+' primary)* +std::unique_ptr ParseBinOpRHSForStr(int ExprPrec, std::unique_ptr LHS); + +/// expression +/// ::= primary binoprhs +/// +std::unique_ptr ParseExpressionForStr(); + +std::string readFileIntoString(char * filename); + +std::unique_ptr ParseExpressionFromString(); + +#endif \ No newline at end of file diff --git a/instance_of_parseExprFromStr/src/.keep b/instance_of_parseExprFromStr/src/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/instance_of_parseExprFromStr/src/basic.cpp b/instance_of_parseExprFromStr/src/basic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..798721fd1db818e014a094d37eafa6a73b8ccadf --- /dev/null +++ b/instance_of_parseExprFromStr/src/basic.cpp @@ -0,0 +1,300 @@ +#include "basic.hpp" + +//===----------------------------------------------------------------------===// +// basic operation +//===----------------------------------------------------------------------===// + +bool isEqual(const std::unique_ptr &expr1, const std::unique_ptr &expr2) +{ + if(expr1 == nullptr || expr2 == nullptr) + { + fprintf(stderr, "empty\n"); + return false; + } + + const std::string expr1Type = expr1->type(); + const std::string expr2Type = expr2->type(); + + if(expr1Type == expr2Type) + { + if(expr1->type() == "Number") + { + NumberExprAST *numberExpr1 = dynamic_cast(expr1.get()); + double number1 = (numberExpr1->getNumber()); + NumberExprAST *numberExpr2 = dynamic_cast(expr2.get()); + double number2 = (numberExpr2->getNumber()); + + return (number1 == number2); + } + else if(expr1->type() == "Variable") + { + VariableExprAST *variableExpr1 = dynamic_cast(expr1.get()); + std::string variable1 = (variableExpr1->getVariable()); + VariableExprAST *variableExpr2 = dynamic_cast(expr2.get()); + std::string variable2 = (variableExpr2->getVariable()); + + return (variable1 == variable2); + } + else if(expr1->type() == "Call") + { + CallExprAST *callExpr1 = dynamic_cast(expr1.get()); + std::string callee1 = (callExpr1->getCallee()); + CallExprAST *callExpr2 = dynamic_cast(expr2.get()); + std::string callee2 = (callExpr2->getCallee()); + + if(callee1 == callee2) + { + std::vector> &args1 = callExpr1->getArgs(); + std::vector> &args2 = callExpr2->getArgs(); + + if(args1.size() == args2.size()) + { + for(long unsigned int i = 0; i < args1.size(); ++i) + { + if(!isEqual(args1.at(i), args2.at(i))) + { + return false; + } + } + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + else if(expr1Type == "Binary") + { + BinaryExprAST *binOp1 = dynamic_cast(expr1.get()); + char op1 = binOp1->getOp(); + std::string opStr1(1, op1); + BinaryExprAST *binOp2 = dynamic_cast(expr2.get()); + char op2 = binOp2->getOp(); + std::string opStr2(1, op2); + if(opStr1 == opStr2) + { + std::unique_ptr &lhs1 = binOp1->getLHS(); + std::unique_ptr &rhs1 = binOp1->getRHS(); + std::unique_ptr &lhs2 = binOp2->getLHS(); + std::unique_ptr &rhs2 = binOp2->getRHS(); + + return (isEqual(lhs1, lhs2) && isEqual(rhs1, rhs2)); + } + else + { + return false; + } + } + else + { + return false; // TODO: handle the other cases + } + } + else + { + return false; + } +} + +bool isFraction(const std::unique_ptr &expr) +{ + if (expr == nullptr) + { + fprintf(stderr, "\tERROR: isFraction: the input expr is nullptr!\n"); + return false; + } + if (expr->type() == "Binary") + { + BinaryExprAST *binOpPtr = dynamic_cast(expr.get()); + char op = binOpPtr->getOp(); + if (op == '/') + { + return true; + } + } + return false; +} + +std::unique_ptr getNumerator(const std::unique_ptr &expr) +{ + if (expr == nullptr) + { + fprintf(stderr, "\tERROR: getNumerator: the input expr is nullptr!\n"); + return nullptr; + } + if (expr->type() == "Binary") + { + BinaryExprAST *binOpPtr = dynamic_cast(expr.get()); + char op = binOpPtr->getOp(); + if (op == '/') + { + return std::move(binOpPtr->getLHS()); + } + } + fprintf(stderr, "\tWARNING: getNumerator: the input expr is not match for fraction\n"); + return expr->Clone(); +} + +std::unique_ptr getDenominator(const std::unique_ptr &expr) +{ + if (expr == nullptr) + { + fprintf(stderr, "\tERROR: getDenominator: the input expr is nullptr!\n"); + return nullptr; + } + if (expr->type() == "Binary") + { + BinaryExprAST *binOpPtr = dynamic_cast(expr.get()); + char op = binOpPtr->getOp(); + if (op == '/') + { + return std::move(binOpPtr->getRHS()); + } + } + fprintf(stderr, "\tWARNING: getDenominator: the input expr is not match for fraction\n"); + return expr->Clone(); +} + +std::unique_ptr createBinaryExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2, const char op) +{ + if (expr1 == nullptr || expr2 == nullptr) + { + fprintf(stderr, "\tERROR: createBinaryExpr: the input contain nullptr!"); + return nullptr; + } + + auto lhs = expr1->Clone(); + auto rhs = expr2->Clone(); + return std::make_unique(op, std::move(lhs), std::move(rhs)); +} + +std::unique_ptr addExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2) { return createBinaryExpr(expr1, expr2, '+'); } + +std::unique_ptr mulExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2) { return createBinaryExpr(expr1, expr2, '*'); } + +std::unique_ptr divExpr(const std::unique_ptr &expr1, const std::unique_ptr &expr2) { return createBinaryExpr(expr1, expr2, '/'); } + +//===----------------------------------------------------------------------===// +// print information +//===----------------------------------------------------------------------===// + +std::string PrintExpression(std::unique_ptr &expr) +{ + if(expr == nullptr) + { + fprintf(stderr, "this is a nullptr.\n"); + } +// const std::string exprType = expr->type(); +#ifdef DEBUG + fprintf(stderr, "expr type: %s;\t", exprType.c_str()); +#endif + std::string exprStr = ""; + if(expr->type() == "Number") + { + NumberExprAST *numberExpr = dynamic_cast(expr.get()); + // std::unique_ptr numberExpr; + // if (tmp != nullptr) + // { + // expr.release(); + // numberExpr.reset(tmp); + // } + double number = (numberExpr->getNumber()); +#ifdef DEBUG + fprintf(stderr, "number: %f\n", number); +#endif + + return std::to_string(number); + } + else if(expr->type() == "Variable") + { + VariableExprAST *variableExpr = dynamic_cast(expr.get()); + std::string variable = (variableExpr->getVariable()); +#ifdef DEBUG + fprintf(stderr, "variable: %s\n", variable.c_str()); +#endif + + return variable; + } + else if(expr->type() == "Call") + { + CallExprAST *callExpr = dynamic_cast(expr.get()); + std::string callee = (callExpr->getCallee()); +#ifdef DEBUG + fprintf(stderr, "call: %s\n", callee.c_str()); +#endif + std::vector> &args = callExpr->getArgs(); + + std::vector argsStr; + for(long unsigned int i = 0; i < args.size(); ++i) + { + std::string strTmp = PrintExpression(args.at(i)); // std::unique_ptr& exprTmp = args.at(i); + argsStr.push_back(strTmp); + } + callee += "("; + for(long unsigned int i = 0; i < argsStr.size() - 1; ++i) + { + callee += argsStr.at(i) + ", "; + } + callee += argsStr.back() + ")"; + return callee; + } + else if(expr->type() == "Binary") + { + BinaryExprAST *binOp = dynamic_cast(expr.get()); + // std::unique_ptr binOp = std::make_unique(expr); // a old wrong method + char op = binOp->getOp(); + std::string opStr(1, op); +#ifdef DEBUG + fprintf(stderr, "op: %s\n", opStr.c_str()); +#endif + + std::unique_ptr &lhs = binOp->getLHS(); + std::string lhsStr = PrintExpression(lhs); + std::unique_ptr &rhs = binOp->getRHS(); + std::string rhsStr = PrintExpression(rhs); + + exprStr += "(" + lhsStr + opStr + rhsStr + ")"; + } + else + { + exprStr = "unknown expression"; + } + return exprStr; +} + +void PrintFunction(std::unique_ptr &fun) +{ + if(fun == nullptr) + { + fprintf(stderr, "this is a nullptr.\n"); + } + else + { + std::string funcNameStr = fun->getFuncName(); + std::vector funcArgsStr = fun->getFuncArgs(); + std::unique_ptr &expr = fun->getFuncBody(); + + fprintf(stderr, "funcName: %s\n", funcNameStr.c_str()); + fprintf(stderr, "Args list:\n"); + if(funcArgsStr.size() == 0) + { + fprintf(stderr, "\tempty args"); + } + else + { + for(auto it = funcArgsStr.begin(); it != funcArgsStr.end(); ++it) + { + fprintf(stderr, "%s ", (*it).c_str()); + } + } + fprintf(stderr, "\nFunc Body:\n"); + // expr->printExpr(); + std::string funcBodyStr = PrintExpression(expr); + fprintf(stderr, "\t%s\n", funcBodyStr.c_str()); + } +} diff --git a/instance_of_parseExprFromStr/src/laxerASTLY.cpp b/instance_of_parseExprFromStr/src/laxerASTLY.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9414b2d39f654135202fbb852037721551960cef --- /dev/null +++ b/instance_of_parseExprFromStr/src/laxerASTLY.cpp @@ -0,0 +1,141 @@ +#include "laxerASTLY.hpp" + +#include "string.h" + +std::string filestring; +int flag = 0; //flag为遍历filestring元素时的索引 +std::string IdentifierStr1; // Filled in if tok_identifier +double NumVal1; // Filled in if tok_number +int CurTokForStr; // CurTok is the current token the parser is looking at. +// BinopPrecedence - This holds the precedence for each binary operator that is defined. +std::map BinopPrecedenceForStr; + +//===----------------------------------------------------------------------===// +// Lexer +//===----------------------------------------------------------------------===// + +char getCharFromStr() +{ + if(flag < filestring.size()) + { char c = filestring.at(flag++); + return c; + } + //遍历完filestring,返回';'作为结束符 + return ';'; +} +// gettokForStr - Return the next token from string. +int gettokForStr() +{ + static int LastChar = ' '; + bool minusFlag = false; + + // Skip any whitespace. + while(isspace(LastChar)) + LastChar = getCharFromStr(); + + if(LastChar == ';') //当LastChar == ';'时,进入新一轮解析,此时s会被更换,LastChar也要更换 + LastChar = getCharFromStr(); + + if(isalpha(LastChar)) + { // identifier: [a-zA-Z][a-zA-Z0-9]* + IdentifierStr1 = LastChar; + while(isalnum((LastChar = getCharFromStr()))) + IdentifierStr1 += LastChar; + + if(IdentifierStr1 == "def") + return tok_def_forstr; + if(IdentifierStr1 == "extern") + return tok_extern_forstr; + return tok_identifier_forstr; + } + + if(LastChar == '-') + { // judge if there is a minus sign + LastChar = getCharFromStr(); + if(isspace(LastChar)) + { // if the character after '-' is a space, just return '-' + LastChar = getCharFromStr(); + return '-'; + } + minusFlag = true; + } + + if(isdigit(LastChar) || LastChar == '.') + { // Number: [0-9.]+ + std::string NumStr; + if(minusFlag) + { + NumStr += '-'; + minusFlag = false; + } + do + { + NumStr += LastChar; + LastChar = getCharFromStr(); + } while(isdigit(LastChar) || LastChar == '.'); + + NumVal1 = strtod(NumStr.c_str(), nullptr); + return tok_number_forstr; + } + + if(LastChar == '#') + { + // Comment until end of line. + do + LastChar = getCharFromStr(); + while(LastChar != EOF && LastChar != '\n' && LastChar != '\r'); + + if(LastChar != EOF) + return gettokForStr(); + } + + // Check for end of file. Don't eat the EOF. + if(LastChar == EOF) + return tok_eof_forstr; + + // Otherwise, just return the character as its ascii value. + int ThisChar = LastChar; + LastChar = getCharFromStr(); + return ThisChar; +} + +/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current +/// token the parser is looking at. getNextToken reads another token from the +/// lexer and updates CurTok with its results. +int getNextTokenForStr() { return CurTokForStr = gettokForStr(); } + +// Install standard binary operators. +void installOperatorsForStr() +{ + // 1 is lowest precedence. + BinopPrecedenceForStr['<'] = 10; + BinopPrecedenceForStr['+'] = 20; + BinopPrecedenceForStr['-'] = 20; + BinopPrecedenceForStr['*'] = 40; // highest. + BinopPrecedenceForStr['/'] = 40; // highest. +} + +/// GetTokPrecedenceForStr - Get the precedence of the pending binary operator token. +int GetTokPrecedenceForStr() +{ + if(!isascii(CurTokForStr)) + return -1; + + // Make sure it's a declared binop. + int TokPrec = BinopPrecedenceForStr[CurTokForStr]; + if(TokPrec <= 0) + return -1; + return TokPrec; +} + +/// LogErrorForStr* - These are little helper functions for error handling. +std::unique_ptr LogErrorForStr(const char *Str) +{ + fprintf(stderr, "Error: %s\n", Str); + return nullptr; +} +std::unique_ptr LogErrorPForStr(const char *Str) +{ + LogErrorForStr(Str); + return nullptr; +} \ No newline at end of file diff --git a/instance_of_parseExprFromStr/src/main.cpp b/instance_of_parseExprFromStr/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea2015d0206d2efed3e2bd6a6f8c7dd324752a31 --- /dev/null +++ b/instance_of_parseExprFromStr/src/main.cpp @@ -0,0 +1,30 @@ +#include "basic.hpp" +#include "laxerASTLY.hpp" +#include "parserASTLY.hpp" +#include "string.h" + +#include "stdlib.h " +#include "stdio.h" + + +static void HandleParseExpressionFromString() +{ + std::unique_ptr es = ParseExpressionFromString(); + if(es) + { + fprintf(stderr, "Parsed an string\n"); + std::string str = PrintExpression(es); + fprintf(stderr, "\tstr: %s\n", str.c_str()); + } +} + + +int main() +{ + // Install standard binary operators + installOperatorsForStr(); + + HandleParseExpressionFromString(); + system("pause"); + return 0; +} \ No newline at end of file diff --git a/instance_of_parseExprFromStr/src/parserASTLY.cpp b/instance_of_parseExprFromStr/src/parserASTLY.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdf4ebafa01c5d6f3b387b04b080b1504bb633ab --- /dev/null +++ b/instance_of_parseExprFromStr/src/parserASTLY.cpp @@ -0,0 +1,174 @@ +#include "basic.hpp" +#include "laxerASTLY.hpp" +#include "parserASTLY.hpp" +#include "string.h" + +//===----------------------------------------------------------------------===// +// Parser +//===----------------------------------------------------------------------===// + +std::unique_ptr ParseExpressionForStr(); + +/// numberexpr ::= number +std::unique_ptr ParseNumberExprForStr() +{ + auto Result = std::make_unique(NumVal1); + getNextTokenForStr(); // consume the number + return Result; +} + +/// parenexpr ::= '(' expression ')' +std::unique_ptr ParseParenExprForStr() +{ + getNextTokenForStr(); // eat (. + auto V = ParseExpressionForStr(); + if(!V) + return nullptr; + + if(CurTokForStr != ')') + return LogErrorForStr("expected ')'"); + getNextTokenForStr(); // eat ). + return V; +} + +/// identifierexpr +/// ::= identifier +/// ::= identifier '(' expression* ')' +std::unique_ptr ParseIdentifierExprForStr() +{ + std::string IdName = IdentifierStr1; + + getNextTokenForStr(); // eat identifier. + + if(CurTokForStr != '(') // Simple variable ref. + return std::make_unique(IdName); + + // Call. + getNextTokenForStr(); // eat ( + std::vector> Args; + if(CurTokForStr != ')') + { + while(true) + { + if(auto Arg = ParseExpressionForStr()) + Args.push_back(std::move(Arg)); + else + return nullptr; + + if(CurTokForStr == ')') + break; + + if(CurTokForStr != ',') + return LogErrorForStr("Expected ')' or ',' in argument list"); + getNextTokenForStr(); + } + } + + // Eat the ')'. + getNextTokenForStr(); + + return std::make_unique(IdName, std::move(Args)); +} + +/// primary +/// ::= identifierexpr +/// ::= numberexpr +/// ::= parenexpr +std::unique_ptr ParsePrimaryForStr() +{ + switch(CurTokForStr) + { + default: + return LogErrorForStr("unknown token when expecting an expression"); + case tok_identifier_forstr: + return ParseIdentifierExprForStr(); + case tok_number_forstr: + return ParseNumberExprForStr(); + case '(': + return ParseParenExprForStr(); + } +} + +/// binoprhs +/// ::= ('+' primary)* +std::unique_ptr ParseBinOpRHSForStr(int ExprPrec, std::unique_ptr LHS) +{ + // If this is a binop, find its precedence. + while(true) + { + int TokPrec = GetTokPrecedenceForStr(); + + // If this is a binop that binds at least as tightly as the current binop, + // consume it, otherwise we are done. + if(TokPrec < ExprPrec) + return LHS; + + // Okay, we know this is a binop. + int BinOp = CurTokForStr; + getNextTokenForStr(); // eat binop + + // Parse the primary expression after the binary operator. + auto RHS = ParsePrimaryForStr(); + if(!RHS) + return nullptr; + + // If BinOp binds less tightly with RHS than the operator after RHS, let + // the pending operator take RHS as its LHS. + int NextPrec = GetTokPrecedenceForStr(); + if(TokPrec < NextPrec) + { + RHS = ParseBinOpRHSForStr(TokPrec + 1, std::move(RHS)); + if(!RHS) + return nullptr; + } + + // Merge LHS/RHS. + LHS = std::make_unique(BinOp, std::move(LHS), std::move(RHS)); + } +} + +/// expression +/// ::= primary binoprhs +/// +std::unique_ptr ParseExpressionForStr() +{ + auto LHS = ParsePrimaryForStr(); + if(!LHS) + return nullptr; + + return ParseBinOpRHSForStr(0, std::move(LHS)); +} + +//从文件读入到string里 +std::string readFileIntoString(char * filename) +{ + std::ifstream ifile(filename); + //将文件读入到ostringstream对象buf中 + std::ostringstream buf; + char ch; + while(buf&&ifile.get(ch)) + buf.put(ch); + //返回与流对象buf关联的字符串 + return buf.str(); +} +std::unique_ptr ParseExpressionFromString() +{ + //清空filestring,flag归零 + if(CurTokForStr == ';') + { + filestring.clear(); + filestring.shrink_to_fit(); + flag = 0; + } + + char * fn = (char*)"pythonAfter.txt"; + filestring = readFileIntoString(fn); + + getNextTokenForStr(); //eat first element + + if (auto E = ParseExpressionForStr()){ + std::unique_ptr es = E->Clone(); + return es; + } + return nullptr; +} \ No newline at end of file diff --git a/instance_of_parseExprFromStr/src/pythonAfter.txt b/instance_of_parseExprFromStr/src/pythonAfter.txt new file mode 100644 index 0000000000000000000000000000000000000000..edec44d632c06630c595e94db11161a25113d63c --- /dev/null +++ b/instance_of_parseExprFromStr/src/pythonAfter.txt @@ -0,0 +1 @@ +e/b*(a+e)/e*i \ No newline at end of file