Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src / Parser.cpp
diff options
context:
space:
mode:
Commit560a585091f1948efb47d58c82dede281ebef54d (patch)
Author
 martin dobrev <martindobrev0@gmail.com>
2018-09-07 19:00:01 +0300
Committer
 martin dobrev <martindobrev0@gmail.com>
2018-09-07 19:00:01 +0300
Filese62ac68d4fe03881be70b7ce6f400fb0a63060a9 /JSImpl/src/Parser.cpp
IPL-560a585091f1948efb47d58c82dede281ebef54d.tar
IPL-560a585091f1948efb47d58c82dede281ebef54d.tar.gz
IPL-560a585091f1948efb47d58c82dede281ebef54d.zip
Parent23067c0e3a92d452c1f8f3519c64d970a27732e3 (diff)
Introduce Parser and Expression hierarchy.
1 files changed, 182 insertions, 0 deletions
-rw-r--r--JSImpl/src/Parser.cpp182
diff --git a/JSImpl/src/Parser.cpp b/JSImpl/src/Parser.cpp
new file mode 100644
index 0000000..1eceb7f
--- /dev/null
+++ b/JSImpl/src/Parser.cpp
@@ -0,0 +1,182 @@
+#include "Parser.h"
+
+class Parser
+{
+public:
+ Parser(IPLVector<Token>& tokens, const std::function<void()>& onError = {});
+ ExpressionPtr Parse();
+private:
+ bool MatchOneOf(IPLVector<TokenType> types);
+ bool Match(TokenType type);
+ ExpressionPtr Unary();
+ ExpressionPtr LeftSideExpression();
+ ExpressionPtr SimpleExpression();
+
+ Token& Prev() { return m_Tokens[m_Current - 1]; }
+ std::function<void()> OnError;
+ unsigned m_Current;
+ IPLVector<Token> m_Tokens;
+};
+
+Parser::Parser(IPLVector<Token>& tokens, const std::function<void()>& onError)
+ : m_Tokens(tokens)
+ , OnError(onError)
+ , m_Current(0)
+{
+}
+
+bool Parser::MatchOneOf(IPLVector<TokenType> types)
+{
+ for (auto t : types)
+ {
+ if (t == m_Tokens[m_Current].Type)
+ {
+ ++m_Current;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Parser::Match(TokenType type)
+{
+ if (type == m_Tokens[m_Current].Type)
+ {
+ ++m_Current;
+ return true;
+ }
+ return false;
+}
+
+ExpressionPtr Parser::SimpleExpression()
+{
+ //SimpleExpression
+ // this
+ // | null
+ // | true
+ // | false
+ // | Number
+ // | String
+ // | Identifier
+ // | RegularExpression
+ // | ParenthesizedExpression
+ // | ArrayLiteral
+ if (Match({TokenType::Number}))
+ {
+ return IPLMakeSharePtr<LiteralExpression>(Prev().Number);
+ }
+ else if (Match({ TokenType::String }))
+ {
+ return IPLMakeSharePtr<LiteralExpression>(Prev().Lexeme);
+ }
+ else
+ {
+ // TODO implement
+ return ExpressionPtr();
+ }
+}
+
+ExpressionPtr Parser::LeftSideExpression()
+{
+ //LeftSideExpression ->
+ // CallExpression
+ // | ShortNewExpression
+
+ // CallExpression ->
+ // PrimaryExpression
+ // | FullNewExpression
+ // | CallExpression MemberOperator
+ // | CallExpression Arguments
+
+ // FullNewExpression -> new FullNewSubexpression Arguments
+
+ // ShortNewExpression -> new ShortNewSubexpression
+
+ // FullNewSubexpression ->
+ // PrimaryExpressionnormal
+ // | FullNewExpression
+ // | FullNewSubexpression MemberOperator
+
+ // ShortNewSubexpression ->
+ // FullNewSubexpression
+ // | ShortNewExpression
+
+ // MemberOperator ->
+ // [Expressionnormal, allowIn]
+ //| .Identifier
+
+ // Arguments ->
+ // ()
+ // | (ArgumentList)
+
+ // ArgumentList ->
+ // AssignmentExpressionnormal, allowIn
+ // | ArgumentList, AssignmentExpressionnormal, allowIn
+ return SimpleExpression();
+}
+
+ExpressionPtr Parser::Unary()
+{
+
+ //UnaryExpression
+ // PostfixExpression
+ // | delete LeftSideExpressionnormal
+ // | ++LeftSideExpressionnormal
+ // | --LeftSideExpressionnormal
+ // | void UnaryExpressionnormal
+ // | typeof UnaryExpressionnormal
+ // | +UnaryExpressionnormal
+ // | -UnaryExpressionnormal
+ // | ~UnaryExpressionnormal
+ // | !UnaryExpressionnormal
+ if (MatchOneOf({
+ TokenType::Delete,
+ TokenType::MinusMinus,
+ TokenType::PlusPlus,
+ }))
+ {
+ auto ls = LeftSideExpression();
+ auto suffix = false;
+ return IPLMakeSharePtr<UnaryExpression>(ls, Prev().Type, suffix);
+ }
+ else if (MatchOneOf({
+ TokenType::Void,
+ TokenType::Typeof,
+ TokenType::Plus,
+ TokenType::Minus,
+ TokenType::BitwiseNot,
+ TokenType::Bang,
+ }))
+ {
+ auto ls = Unary();
+ auto suffix = false;
+ return IPLMakeSharePtr<UnaryExpression>(ls, Prev().Type, suffix);
+ }
+ else
+ {
+ //PostfixExpression
+ // LeftSideExpression
+ // | LeftSideExpression++
+ // | LeftSideExpression--
+ auto leftSide = LeftSideExpression();
+ if (MatchOneOf({ TokenType::PlusPlus, TokenType::MinusMinus }))
+ {
+ auto suffix = true;
+ return IPLMakeSharePtr<UnaryExpression>(leftSide, Prev().Type, suffix);
+ }
+ return leftSide;
+ }
+}
+
+ExpressionPtr Parser::Parse()
+{
+ // TODO implement full grammar
+ return Unary();
+}
+
+
+ExpressionPtr Parse(IPLVector<Token>& tokens, const std::function<void()>& onError)
+{
+ Parser p(tokens, onError);
+ return p.Parse();
+} \ No newline at end of file