forked from rochus-keller/Micron
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMicParser2.h
207 lines (193 loc) · 7.03 KB
/
MicParser2.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#ifndef __MIC_PARSER2__
#define __MIC_PARSER2__
/*
** Copyright (C) 2024 Rochus Keller (me@rochus-keller.ch)
**
** This file is part of the Micron language project.
**
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
*/
#include <Micron/MicToken.h>
#include <Micron/MicAst.h>
#include <QList>
#include <QHash>
#include <QSet>
namespace Mic {
class MilEmitter;
class Evaluator;
class Scanner2 {
public:
virtual Token next() = 0;
virtual Token peek(int offset) = 0;
virtual QString source() const = 0;
virtual QByteArrayList path() const { return QByteArrayList(); } // prefix without module name
};
class Importer {
public:
virtual Declaration* loadModule( const Import& imp ) = 0;
virtual QByteArray moduleSuffix( const MetaActualList& imp ) = 0;
virtual QByteArray modulePath( const QByteArrayList& imp ) = 0;
};
class Parser2 {
public:
Parser2(AstModel* m, Scanner2* s, MilEmitter* out, Importer* = 0);
~Parser2();
void RunParser(const MetaActualList& = MetaActualList());
Declaration* takeModule(); // get module declaration and take ownership (otherwise deleted by parser)
struct Error {
QString msg;
int row, col;
QString path;
Error( const QString& m, int r, int c, const QString& p):msg(m),row(r),col(c),path(p){}
};
QList<Error> errors;
bool assigCompat(Type* lhs, Type* rhs) const;
protected:
Expression* number();
typedef QPair<QByteArray,QByteArray> Quali;
Quali qualident();
struct IdentDef {
Token name;
enum Visi { Private, ReadOnly, Public } visi;
bool isValid() const { return name.d_type == Tok_ident; }
};
IdentDef identdef();
void ConstDeclaration();
Expression* ConstExpression();
void TypeDeclaration();
Type* type(bool deanonymize = true);
Type* NamedType(Quali* = 0, bool allowUnresovedLocal = false);
Type* ArrayType();
void length(quint32& len);
Type* RecordType();
bool inline_();
void VariantPart();
void FixedPart();
void FieldList();
typedef QList<IdentDef> IdentDefList;
IdentDefList IdentList();
Type* PointerType();
Type* enumeration();
DeclList constEnum();
void VariableDeclaration();
Expression* designator(bool lvalue);
Expression* expression(bool lvalue = false);
quint8 relation();
Expression* SimpleExpression(bool lvalue = false);
quint8 AddOperator();
Expression* term(bool lvalue = false);
quint8 MulOperator();
Expression* literal();
Expression* constructor();
enum { FirstComponent, Named, Anonymous };
void component(Type* constrType, Value& v, quint8& state, DeclList&);
Expression* factor(bool lvalue = false);
Expression* variableOrFunctionCall(bool lvalue = false);
Expression* set();
Expression* element();
void statement();
void assignmentOrProcedureCall();
void StatementSequence();
void gotoLabel();
void GotoStatement();
void IfStatement();
void CaseStatement();
typedef QSet<qint64> CaseLabels;
void Case(Type* t, CaseLabels& ll);
void CaseLabelList(Type* t, CaseLabels&);
void LabelRange(Type* t,CaseLabels&);
Value label(Type* t);
void WhileStatement();
void RepeatStatement();
void ForStatement();
void LoopStatement();
void ExitStatement();
void procedure();
Type* ProcedureType();
void ProcedureDeclaration();
void block();
void DeclarationSequence();
void ReturnStatement();
Type* FormalParameters();
Type* ReturnType();
void FPSection();
Type* FormalType();
void module();
void ImportList();
void import();
static bool isUnique(const MetaParamList&, const Declaration*);
MetaParamList MetaParams();
Declaration* MetaSection(bool& isType);
protected:
void next();
Token peek(int off);
void invalid(const char* what);
bool expect(int tt, bool pkw, const char* where);
void error( const Token&, const QString& msg);
void error( int row, int col, const QString& msg );
Declaration* findDecl(const Token& id );
bool assigCompat(Type* lhs, Declaration* rhs) const;
bool assigCompat(Type* lhs, const Expression* rhs) const;
bool paramCompat(Declaration* lhs, const Expression* rhs) const;
bool matchFormals(const QList<Declaration*>& a, const QList<Declaration*>& b) const;
bool matchResultType(Type* lhs, Type* rhs) const;
bool sameType(Type* lhs, Type* rhs) const;
bool equalTypes(Type* lhs, Type* rhs) const;
void ForwardDeclaration();
Expression* maybeQualident();
Declaration* resolveQualident(Quali* = 0, bool allowUnresovedLocal = false);
void ProcAlias();
static DeclList toList(Declaration*);
Declaration* addDecl(const Token& id, quint8 visi, quint8 mode, bool* doublette = 0);
Declaration* addDecl(const IdentDef& id, quint8 mode, bool* doublette = 0);
void resolveDeferreds();
Expression* toExpr(Declaration* d, const RowCol&);
void emitType(Type*, const Quali& = Quali());
Declaration* addHelper(Type*);
Declaration* addTemp(Type*);
typedef QList<QPair<Token,Value> > Args;
void openArrayError(const Token&, Type*);
void invalidTypeError(const Token&, Type*);
void prepareParam(const DeclList& formals, const ExpList& actuals);
void resolveAndCheckType(Declaration* d);
Type* resolveAndCheckType(Type*, bool selfRefBroken);
void checkArithOp(Expression*);
void checkUnaryOp(Expression*);
void checkRelOp(Expression*);
private:
AstModel* mdl;
MilEmitter* out;
Evaluator* ev;
Importer* imp;
Token cur;
Token la;
Scanner2* scanner;
Declaration* thisMod, *thisDecl;
QList<QPair<Type*,Token> > deferred;
QList<Type*> componentTypeStack;
QList<RowCol> loopStack;
typedef QList<RowCol> Depth;
Depth blockDepth;
struct Label {
Depth depth;
Token tok;
bool used;
Label(const Depth& d, const Token& t):depth(d),tok(t),used(false) {}
};
typedef QHash<const char*,Label> Labels;
Labels labels;
typedef QList<QPair<Depth,Token> > Gotos;
Gotos gotos;
QSet<Type*> deferDeleteNamedType;
MetaActualList metaActuals;
};
}
#endif // include