/* * Method assumes preprocessor came * in and dealt with labels and directives. */ public bool Derive(Token[] tokens) { DTree curchild = null, tempchild = null; Token curtoken; string nmemonic = null; string iden; int i = 0; next = null; children = null; if (tokens.Length == 0) { return(true); } curtoken = tokens[0]; if (curtoken.id != TokenKind.IDENTIFIER) { return(SyntaxErr()); } iden = ((IdentifierToken)curtoken).identifier.ToUpper(); if (NmemonicTree.IsNmemonic(iden)) { children = new NmemonicTree(iden); curchild = children; i = 1; nmemonic = iden; } else { return(SyntaxErr()); } while (i < tokens.Length) { curtoken = tokens[i]; switch (curtoken.id) { case TokenKind.IDENTIFIER: iden = ((IdentifierToken)curtoken).identifier.ToUpper(); if (RegTree.IsReg(iden)) { /* * C is a register and also a condition. * To solve this ambiguity, if the nmemonic requires * a condition, it doesn't require a register, so create * a new register tree iff the nmemonic is not conditional. */ if (NmemonicTree.IsConditionalNmemonic(nmemonic) && iden.Equals("C")) { tempchild = new ConditionTree("C"); } else { tempchild = new RegTree(iden); } } else if (NormPairTree.IsNormPair(iden)) { tempchild = new NormPairTree(iden); } else if (SpecPairTree.IsSpecPair(iden)) { tempchild = new SpecPairTree(iden); } else if (ConditionTree.IsCondition(iden)) { tempchild = new ConditionTree(iden); } else if (SpecRegTree.IsSpecReg(iden)) { tempchild = new SpecRegTree(iden); } else if (IRegTree.IsIReg(iden)) { tempchild = new IRegTree(iden); } else if (IPairTree.IsIPair(iden)) { tempchild = new IPairTree(iden); } else { return(SyntaxErr()); } curchild.next = tempchild; curchild = tempchild; i++; break; case TokenKind.NUMBER: tempchild = new ImmTree(((NumberToken)curtoken).number); curchild.next = tempchild; curchild = tempchild; i++; break; case TokenKind.OPERATOR: OperatorKind op = ((OperatorToken)curtoken).op; switch (op) { case OperatorKind.LPAREN: int start = i; Token[] adrtokens; i++; while (i < tokens.Length) { curtoken = tokens[i]; if (curtoken.id == TokenKind.OPERATOR && ((OperatorToken)curtoken).op == OperatorKind.RPAREN) { break; } i++; } if (i >= tokens.Length) { return(SyntaxErr()); } adrtokens = new Token[i - start - 1]; Array.Copy(tokens, start + 1, adrtokens, 0, adrtokens.Length); tempchild = new AdrTree(); bool success = ((AdrTree)tempchild). FormAdrTree(adrtokens, start + 1); if (!success) { return(false); } curchild.next = tempchild; curchild = tempchild; i++; break; case OperatorKind.PLUS: if (i >= tokens.Length - 1) { return(SyntaxErr()); } Token numtokenadd = tokens[i + 1]; if (numtokenadd.id != TokenKind.NUMBER) { return(SyntaxErr()); } tempchild = new ImmTree(((NumberToken)numtokenadd).number); curchild.next = tempchild; curchild = tempchild; i += 2; break; case OperatorKind.MINUS: if (i >= tokens.Length - 1) { return(SyntaxErr()); } Token numtokensub = tokens[i + 1]; if (numtokensub.id != TokenKind.NUMBER) { return(SyntaxErr()); } tempchild = new ImmTree(-((NumberToken)numtokensub).number); curchild.next = tempchild; curchild = tempchild; i += 2; break; default: return(SyntaxErr()); } break; default: break; } if (i < tokens.Length) { curtoken = tokens[i]; if (curtoken.id != TokenKind.OPERATOR || ((OperatorToken)curtoken).op != OperatorKind.COMMA) { return(SyntaxErr()); } i++; if (i >= tokens.Length) { return(SyntaxErr()); } } } return(true); }
public static void DebugTree(DTree t, int indent) { StringBuilder sb = new StringBuilder(indent); DTree child; for (int i = 0; i < indent; i++) { sb.Append(' '); } switch (t.kind) { case DTKind.NMEMONIC: NmemonicTree nm = (NmemonicTree)t; Console.Write(sb); Console.WriteLine("(NMEMONIC) { " + nm.nmemonic + " }"); break; case DTKind.OPERATOR: OperatorTree op = (OperatorTree)t; Console.Write(sb); Console.WriteLine("(OPERATOR) { " + op.op + " }"); break; case DTKind.REG: RegTree reg = (RegTree)t; Console.Write(sb); Console.WriteLine("(REGISTER) { " + reg.reg + " }"); break; case DTKind.NORMPAIR: NormPairTree npair = (NormPairTree)t; Console.Write(sb); Console.WriteLine("(NORMPAIR) { " + npair.normpair + " }"); break; case DTKind.SPECPAIR: SpecPairTree spair = (SpecPairTree)t; Console.Write(sb); Console.WriteLine("(SPECPAIR) { " + spair.specpair + " }"); break; case DTKind.IPAIR: IPairTree ipair = (IPairTree)t; Console.Write(sb); Console.WriteLine("(IPAIR) { " + ipair.ipair + " }"); break; case DTKind.IMM: ImmTree imm = (ImmTree)t; Console.Write(sb); Console.WriteLine("(IMM) { " + imm.immediate + " }"); break; case DTKind.ADR: AdrTree adr = (AdrTree)t; child = adr.children; Console.Write(sb); Console.WriteLine("(ADR) {"); while (child != null) { DebugTree(child, indent + 4); child = child.next; } Console.Write(sb); Console.WriteLine("}"); break; case DTKind.INSTRUCTION: InstructionTree inst = (InstructionTree)t; child = inst.children; Console.Write(sb); Console.WriteLine("(INSTRUCTION) {"); while (child != null) { DebugTree(child, indent + 4); child = child.next; } Console.Write(sb); Console.WriteLine("}"); break; case DTKind.CONDITION: ConditionTree cond = (ConditionTree)t; Console.Write(sb); Console.WriteLine("(CONDITION) { " + cond.cond + " }"); break; case DTKind.SPECREG: SpecRegTree specreg = (SpecRegTree)t; Console.Write(sb); Console.WriteLine("(SPECREG) { " + specreg.reg + " }"); break; default: break; } }