1//===-- GoParser.h -----------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_GoParser_h
11#define liblldb_GoParser_h
12
13#include "lldb/lldb-private.h"
14#include "Plugins/ExpressionParser/Go/GoAST.h"
15#include "Plugins/ExpressionParser/Go/GoLexer.h"
16
17namespace lldb_private
18{
19class GoParser
20{
21  public:
22    explicit GoParser(const char *src);
23
24    GoASTStmt *Statement();
25
26    GoASTStmt *GoStmt();
27    GoASTStmt *ReturnStmt();
28    GoASTStmt *BranchStmt();
29    GoASTStmt *EmptyStmt();
30    GoASTStmt *ExpressionStmt(GoASTExpr *e);
31    GoASTStmt *IncDecStmt(GoASTExpr *e);
32    GoASTStmt *Assignment(GoASTExpr *e);
33    GoASTBlockStmt *Block();
34
35    GoASTExpr *MoreExpressionList();  // ["," Expression]
36    GoASTIdent *MoreIdentifierList(); // ["," Identifier]
37
38    GoASTExpr *Expression();
39    GoASTExpr *UnaryExpr();
40    GoASTExpr *OrExpr();
41    GoASTExpr *AndExpr();
42    GoASTExpr *RelExpr();
43    GoASTExpr *AddExpr();
44    GoASTExpr *MulExpr();
45    GoASTExpr *PrimaryExpr();
46    GoASTExpr *Operand();
47    GoASTExpr *Conversion();
48
49    GoASTExpr *Selector(GoASTExpr *e);
50    GoASTExpr *IndexOrSlice(GoASTExpr *e);
51    GoASTExpr *TypeAssertion(GoASTExpr *e);
52    GoASTExpr *Arguments(GoASTExpr *e);
53
54    GoASTExpr *Type();
55    GoASTExpr *Type2();
56    GoASTExpr *ArrayOrSliceType(bool allowEllipsis);
57    GoASTExpr *StructType();
58    GoASTExpr *FunctionType();
59    GoASTExpr *InterfaceType();
60    GoASTExpr *MapType();
61    GoASTExpr *ChanType();
62    GoASTExpr *ChanType2();
63
64    GoASTExpr *Name();
65    GoASTExpr *QualifiedIdent(GoASTIdent *p);
66    GoASTIdent *Identifier();
67
68    GoASTField *FieldDecl();
69    GoASTExpr *AnonymousFieldType();
70    GoASTExpr *FieldNamesAndType(GoASTField *f);
71
72    GoASTFieldList *Params();
73    GoASTField *ParamDecl();
74    GoASTExpr *ParamType();
75    GoASTFuncType *Signature();
76    GoASTExpr *CompositeLit();
77    GoASTExpr *FunctionLit();
78    GoASTExpr *Element();
79    GoASTCompositeLit *LiteralValue();
80
81    bool
82    Failed() const
83    {
84        return m_failed;
85    }
86    bool
87    AtEOF() const
88    {
89        return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size();
90    }
91
92    void GetError(Error &error);
93
94  private:
95    class Rule;
96    friend class Rule;
97
98    std::nullptr_t
99    syntaxerror()
100    {
101        m_failed = true;
102        return nullptr;
103    }
104    GoLexer::Token &
105    next()
106    {
107        if (m_pos >= m_tokens.size())
108        {
109            if (m_pos != 0 &&
110                (m_tokens.back().m_type == GoLexer::TOK_EOF || m_tokens.back().m_type == GoLexer::TOK_INVALID))
111                return m_tokens.back();
112            m_pos = m_tokens.size();
113            m_tokens.push_back(m_lexer.Lex());
114        }
115        return m_tokens[m_pos++];
116    }
117    GoLexer::TokenType
118    peek()
119    {
120        GoLexer::Token &tok = next();
121        --m_pos;
122        return tok.m_type;
123    }
124    GoLexer::Token *
125    match(GoLexer::TokenType t)
126    {
127        GoLexer::Token &tok = next();
128        if (tok.m_type == t)
129            return &tok;
130        --m_pos;
131        m_last_tok = t;
132        return nullptr;
133    }
134    GoLexer::Token *
135    mustMatch(GoLexer::TokenType t)
136    {
137        GoLexer::Token *tok = match(t);
138        if (tok)
139            return tok;
140        return syntaxerror();
141    }
142    bool Semicolon();
143
144    GoASTStmt *
145    FinishStmt(GoASTStmt *s)
146    {
147        if (!Semicolon())
148            m_failed = true;
149        return s;
150    }
151
152    llvm::StringRef CopyString(llvm::StringRef s);
153
154    GoLexer m_lexer;
155    std::vector<GoLexer::Token> m_tokens;
156    size_t m_pos;
157    llvm::StringRef m_error;
158    llvm::StringRef m_last;
159    GoLexer::TokenType m_last_tok;
160    llvm::StringMap<uint8_t> m_strings;
161    bool m_failed;
162};
163}
164
165#endif
166