-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathExpressionParser.h
149 lines (138 loc) · 4.76 KB
/
ExpressionParser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef EXPRESSIONPARSER_H
#define EXPRESSIONPARSER_H
/*
* Copyright 2019 Rochus Keller <mailto:me@rochus-keller.ch>
*
* This file is part of the JuaJIT BC Viewer application.
*
* The following is the license that applies to this copy of the
* application. For a license to use the application under conditions
* other than those described here, please email to me@rochus-keller.ch.
*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public
* License (GPL) versions 2.0 or 3.0 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in
* the packaging of this file. Please review the following information
* to ensure GNU General Public Licensing requirements will be met:
* http://www.fsf.org/licensing/licenses/info/GPLv2.html and
* http://www.gnu.org/copyleft/gpl.html.
*/
// adopted from NMR Application Framework, see https://github.com/rochus-keller/NAF
#include <QVariant>
#include <QTextStream>
class QIODevice;
typedef struct lua_State lua_State;
namespace Lua
{
class Engine2;
class SourceBuffer
{
public:
SourceBuffer( const QByteArray& source = QByteArray() );
bool peek( char* buf, int size);
bool read( char* buf, int size);
void eat(int count = -1);
void rewind();
bool atEnd() const { return d_eaten == d_source.size(); }
private:
QByteArray d_source;
int d_eaten;
int d_peekPtr;
};
class ExpressionLexer
{
public:
struct Token
{
enum Type {
Invalid, Nil, Bool, Number, String, Name,
LBrack, RBrack, // []
LBrace, RBrace, // ()
Dot, Op
};
Type d_type;
QVariant d_val;
Token( Type t = Invalid, const QVariant& v = QVariant()):d_type(t),d_val(v){}
bool isValid() const { return d_type != Invalid; }
};
enum Operator
{
NoOp,
// Gleiche Reihenfolge wie in lcode.h
Plus, Minus, Star, Slash, Percent, /* '+' '-' '*' '/' '%' */
Hat, Concat, /* power and concat (right associative) */
Neq, Eq, /* equality and inequality */
Lt, Leq, Gt, Geq, /* order */
And, Or, /* order */
/*Unary Minus, */ Not, Pound // Unary
};
bool process( const QByteArray& );
const QString& getError() const { return d_error; }
void dump( QTextStream& ) const;
Token next();
Token peek(int i = 0 );
protected:
struct LexEx : public std::exception {};
Operator fetchOp();
bool fetchName( QByteArray& );
bool fetchString( QByteArray& str );
bool fetchNumber( double& d );
void eatSpace();
bool error( const char* msg );
Token fetchNext();
private:
QList<Token> d_tokens;
int d_cur;
SourceBuffer d_source;
QString d_error;
};
class ExpressionParser
{
public:
enum AstNodeType {
Invalid,
Constant, // nil | false | true | Number | String
BinOp, // exp binop exp
UnOp, // unop exp
DotOp, // prefixexp '.' Name
BraceOp, // '(' exp ')'
IndexOp, // prefixexp '[' exp ']'
Name // Name
};
struct AstNode
{
AstNode(AstNodeType t = Invalid,const QVariant& v = QVariant(), AstNode* left = 0, AstNode* right = 0):
d_type(t),d_val(v),d_left(left),d_right(right){}
~AstNode();
AstNodeType d_type;
QVariant d_val;
AstNode* d_left;
AstNode* d_right;
void dump( QTextStream&, int level = 0 ) const;
};
ExpressionParser();
~ExpressionParser();
bool parse( const QByteArray & );
bool parseAndPrint( const QByteArray &, Engine2*, bool doDump = false );
const AstNode* getTop() const { return d_top; }
const QString& getError() const { return d_error; }
int execute(Engine2*);
bool executeAndPrint(Engine2*);
void dump(QTextStream&) const;
protected:
struct ParsEx : public std::exception {};
void prefixexp(AstNode*);
void primaryexp(AstNode*);
void simpleexp( AstNode* );
void expr(AstNode*);
ExpressionLexer::Operator subexpr( AstNode*, quint32 limit, int level);
void error( const char* msg );
int depthFirstExec(Engine2 *e, AstNode*);
private:
AstNode* d_top;
ExpressionLexer d_lex;
QString d_error;
};
}
#endif // EXPRESSIONPARSER_H