📄 parser.cs
字号:
}
else
{
#if false
// If no explicit assignment, then we must create one
// first field -> '=0'
if (idPrev == null)
{
expInit = new IntExp(0, id.Location);
}
// all other fields -> '= <prevfield> + '1' '
else
{
expInit = new BinaryExp(
new SimpleObjExp(idPrev),
new IntExp(1, id.Location),
BinaryExp.BinaryOp.cAdd);
}
#endif
}
//EnumField e = new EnumField(id);
FieldDecl e = new FieldDecl(id, tSig, mods, expInit);
a.Add(e);
// If no comma, then this had better be our last one
t = m_lexer.PeekNextToken();
if (t.TokenType != Token.Type.cComma)
{
break;
}
ReadExpectedToken(Token.Type.cComma);
idPrev = id;
t = m_lexer.PeekNextToken();
} // while parsing fields
ReadExpectedToken(Token.Type.cRCurly);
// Convert array list to EnumField[]
FieldDecl [] f = new FieldDecl[a.Count];
for(int i = 0; i < f.Length; i++)
f[i] = (FieldDecl) a[i];
EnumDecl node = new EnumDecl(idName, f, modsEnums);
node.SetLocation(this.EndRange(f2));
return node;
}
//-----------------------------------------------------------------------------
// Parse an interface
//
// ** rules **
// InterfaceDecl-> 'interface' id:name '{' body '}'
// InterfaceDecl-> 'interface' id:name ':' base_list '{' body '}'
//-----------------------------------------------------------------------------
protected ClassDecl ParseInterface(Modifiers modsInterface)
{
Token t;
ReadExpectedToken(Token.Type.cInterface);
Identifier idName = ReadExpectedIdentifier();
TypeSig[] arBase = null;
//if (!modsInterface.IsPublic)
//modsInterface.FlagSetter |= Modifiers.EFlags.Private;
if (modsInterface.VisibilityNotSet)
modsInterface.SetPrivate();
ArrayList alMethods = new ArrayList();
ArrayList alProperties = new ArrayList();
// Read list of base interfaces that we derive from
t = m_lexer.PeekNextToken();
if (t.TokenType == Token.Type.cColon)
{
ConsumeNextToken(); // ':'
arBase = ParseIdNameList();
}
ReadExpectedToken(Token.Type.cLCurly);
// Read members
t = m_lexer.PeekNextToken();
while(t.TokenType != Token.Type.cRCurly)
{
// member:
// method -> rettype id:name '(' param_list ')' ';'
// property -> rettype id:name '{' set ';' get ';' '}'
TypeSig rettype = ParseTypeSig();
Identifier idMember = ReadExpectedIdentifier();
t = m_lexer.PeekNextToken();
// All interface members have these attributes
/*
AST.Modifiers mods = new AST.Modifiers(
AST.Modifiers.EFlags.Abstract |
AST.Modifiers.EFlags.Virtual |
AST.Modifiers.EFlags.Public
);
*/
Modifiers mods = new Modifiers();
mods.SetAbstract();
mods.SetVirtual();
mods.SetPublic();
// Method
if (t.TokenType == Token.Type.cLParen)
{
MemberDecl m = this.PartialParseMethodDecl(mods, rettype, idMember, Genre.cInterface);
alMethods.Add(m);
}
// Property
else if (t.TokenType == Token.Type.cLCurly)
{
PropertyDecl p = PartialParsePropertyDecl(mods, rettype, idMember);
alProperties.Add(p);
}
// Indexer
else if (t.TokenType == Token.Type.cLSquare)
{
PropertyDecl p = PartialParseIndexerDecl(mods, rettype, idMember);
alProperties.Add(p);
}
// Error
else {
//this.ThrowError_UnexpectedToken(t);
ThrowError(E_UnexpectedToken(t));
}
t = m_lexer.PeekNextToken();
}
ReadExpectedToken(Token.Type.cRCurly); // '}'
MethodDecl [] arMethods = this.MethodDeclFromArray(alMethods);
PropertyDecl [] arProperties = this.PropertyDeclFromArray(alProperties);
ClassDecl d = new ClassDecl(idName, arBase, arMethods, arProperties, modsInterface);
return d;
}
//-----------------------------------------------------------------------------
// Parse a class, reutrn a ClassDecl node
//
// ** Rules **
// ClassDecl -> 'class' id:name '{' membeddecl_list '}'
// ClassDecl -> 'class' id:name ':' id:Super '{' membeddecl_list '}'
//-----------------------------------------------------------------------------
protected ClassDecl ParseClass(Modifiers modsClass)
{
return ParseClassOrStruct(modsClass, true);
}
protected ClassDecl ParseStruct(Modifiers modsClass)
{
return ParseClassOrStruct(modsClass, false);
}
protected ClassDecl ParseClassOrStruct(Modifiers modsClass, bool fIsClass)
{
Token t;
if (fIsClass)
ReadExpectedToken(Token.Type.cClass);
else
ReadExpectedToken(Token.Type.cStruct);
// Get Name of the type
Identifier stClassName = ReadExpectedIdentifier();
t = m_lexer.PeekNextToken();
// Get base list
TypeSig[] arBase = null;
if (t.TokenType == Token.Type.cColon)
{
ConsumeNextToken();
arBase = ParseIdNameList();
}
ReadExpectedToken(Token.Type.cLCurly);
ArrayList alMethods = new ArrayList();
ArrayList alFields = new ArrayList();
ArrayList alProperties = new ArrayList();
ArrayList alNestedTypes = new ArrayList();
ArrayList alEvents = new ArrayList();
// Parse list of memberdecls
// We peek at the first token. If it's a '}', then we're done parsing members,
// Else Figure out what type of member this is and parse it.
t = m_lexer.PeekNextToken();
while (t.TokenType != Token.Type.cRCurly)
{
// mods -> <set of member modifiers, like public, protected, static, etc>
// type -> <some type>
// ctordecl -> attrs id '(' paramlist ')' '{' statementlist '}'
// methoddecl -> attrs type id '(' paramlist ')' '{' statementlist '}'
// -> attrs type 'operator' op '(' paramlist ')' body
// fielddecl -> attrs type id ';'
// propdecl -> attrs type id '{' ... '}'
// typedecl -> attrs 'enum' ...
// eventdecl -> attrs 'delegate' type id ';'
// All members start with 'attrs type id'. (except ctor) So do those.
Modifiers mods = ParseModifiers();
// Make private a default
if (mods.VisibilityNotSet)
mods.SetPrivate();
// @todo - we need a clean way to decide if this is a ctor or a methoddecl
Identifier tTempId = null;
t = m_lexer.PeekNextToken();
// Check events
if (t.TokenType == Token.Type.cEvent)
{
EventDecl e = PartialParseEventDecl(mods);
alEvents.Add(e);
continue;
}
// Check if this is a nested type
if (t.TokenType == Token.Type.cEnum)
{
EnumDecl e = ParseEnum(mods);
alNestedTypes.Add(e);
t = m_lexer.PeekNextToken();
continue;
}
if (t.TokenType == Token.Type.cDelegate)
{
DelegateDecl d = ParseDelegate(mods);
alNestedTypes.Add(d);
t = m_lexer.PeekNextToken();
continue;
}
if (t.TokenType == Token.Type.cClass)
{
ClassDecl d = ParseClass(mods);
alNestedTypes.Add(d);
t = m_lexer.PeekNextToken();
continue;
}
if (t.TokenType == Token.Type.cStruct)
{
ClassDecl d = ParseStruct(mods);
alNestedTypes.Add(d);
t = m_lexer.PeekNextToken();
continue;
}
// Not a nested type, so it's some other member (maybe a ctor)...
if (t.TokenType == Token.Type.cId)
{
tTempId = t.Id;
}
TypeSig type = ParseTypeSig();
Identifier stMemberName;
// Ctor - has a '(' instead of another identifier for the member name
t = m_lexer.PeekNextToken();
if (t.TokenType == Token.Type.cLParen)
{
type = null; // ctor has a no return type
stMemberName = tTempId;
// If the ctor name doesn't match the class name, we have some error
if (stMemberName.Text != stClassName.Text)
{
ThrowError(new ParserErrorException(
Code.cMissingRetType,
stMemberName.Location,
"Missing a return type on a method"
));
}
} else {
// Check for overloaded operator
if (t.TokenType == Token.Type.cOperator)
{
MethodDecl m = this.PartialParseOverloadedOp(mods, type);
alMethods.Add(m);
t = m_lexer.PeekNextToken();
continue;
}
// Not a ctor, so we can go ahead and read the identifier
stMemberName = ReadExpectedIdentifier();
}
t = m_lexer.PeekNextToken();
// MethodDecl. Has a '(' next
if (t.TokenType == Token.Type.cLParen)
{
MethodDecl m = PartialParseMethodDecl(mods, type, stMemberName, fIsClass ? Genre.cClass : Genre.cStruct);
alMethods.Add(m);
}
// FieldDecl. Has a ';' (or possibly an '=') next
else if ((t.TokenType == Token.Type.cSemi) || (t.TokenType == Token.Type.cAssign))
{
Exp expInit = null;
if (t.TokenType == Token.Type.cAssign)
{
ConsumeNextToken();
expInit = ParseExp();
}
ReadExpectedToken(Token.Type.cSemi);
FieldDecl f = new FieldDecl(stMemberName, type, mods, expInit);
alFields.Add(f);
}
// Property
else if (t.TokenType == Token.Type.cLCurly)
{
PropertyDecl p = PartialParsePropertyDecl(mods, type, stMemberName);
alProperties.Add(p);
}
// Indexer
else if (t.TokenType == Token.Type.cLSquare)
{
PropertyDecl p = PartialParseIndexerDecl(mods, type, stMemberName);
alProperties.Add(p);
}
// Syntax error
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -