// TODO: maintain a list of token types provided by parser so that scanner can remain unbiased // TODO: maintain a list of special token types public Token GetToken() { SkipWhitespace(); if (currType == CharType.Alpha) { WordToken token = WordToken.GetToken(this); // TODO: check for reserved words return(token); } else if (currType == CharType.Numeric) { return(NumberToken.GetToken(this)); } else if (currType == CharType.Quote) { return(StringToken.GetToken(this)); } else if (currType == CharType.EOF) { return(new EndOfFileToken()); } else if (currType == CharType.Special) { SpecialToken token = SpecialToken.GetToken(this); // TODO: check for special token types return(token); } return(null); }
public static NumberToken GetToken(Scanner scanner) { NumberToken t = new NumberToken(); t.stringBuilder = new StringBuilder(); t.sc = scanner.col; t.sr = scanner.row; t.AccumulateValue(scanner, ref t._value); t.wholePlaces = t.digitCount; if (scanner.curr == '.') { t.stringBuilder.Append(scanner.curr); scanner.Next(); t.real = true; t.AccumulateValue(scanner, ref t._value); t.decimalPlaces = t.digitCount - t.wholePlaces; } if (scanner.curr == 'e' || scanner.curr == 'E') { t.real = true; t.stringBuilder.Append(scanner.curr); scanner.Next(); if (scanner.curr == '+' || scanner.curr == '-') { t.exponentSign = scanner.curr; t.stringBuilder.Append(scanner.curr); scanner.Next(); } t.digitCount = 0; t.AccumulateValue(scanner, ref t.eValue); if (t.exponentSign == '-') { t.eValue = -t.eValue; } } t.ec = scanner.col; t.er = scanner.row; var exponent = t.eValue - t.decimalPlaces; if (exponent != 0) { t.Value *= Math.Pow(10, exponent); } t.String = t.stringBuilder.ToString(); return(t); }
public static NumberToken GetToken(Scanner scanner) { NumberToken t = new NumberToken(); t.stringBuilder = new StringBuilder(); t.sc = scanner.col; t.sr = scanner.row; t.AccumulateValue(scanner, ref t._value); t.wholePlaces = t.digitCount; // no dealing with real values, just integers // if (scanner.curr == '.') // { // t.stringBuilder.Append(scanner.curr); // scanner.Next(); // t.real = true; // t.AccumulateValue(scanner, ref t._value); // t.decimalPlaces = t.digitCount - t.wholePlaces; // } // if (scanner.curr == 'e' || scanner.curr == 'E') // { // t.real = true; // t.stringBuilder.Append(scanner.curr); // scanner.Next(); // if (scanner.curr == '+' || scanner.curr == '-') // { // t.exponentSign = scanner.curr; // t.stringBuilder.Append(scanner.curr); // scanner.Next(); // } // t.digitCount = 0; // t.AccumulateValue(scanner, ref t.eValue); // if (t.exponentSign == '-') // { // t.eValue = -t.eValue; // } // } t.ec = scanner.col; t.er = scanner.row; // var exponent = t.eValue - t.decimalPlaces; // if (exponent != 0) // { // t.Value *= Math.Pow(10, exponent); // } t.String = t.stringBuilder.ToString(); return(t); }
public override void Parse(string filename) { FileStream fs = File.OpenRead(filename); StreamReader sr = new StreamReader(fs); scanner = new Scanner(sr); // Getting the first token will skip whitespace, so I will have either a comment, a RR or a control block GetToken(); do { if (token.Type == tokenControl) { // get the next token which should be a string containing // ORIGIN, INCLUDE or TTL GetToken(); if (token.Type == tokenOrigin) { origin = ParseOrigin(); owner = origin; } else if (token.Type == tokenTTL) { GetToken(); if (token.Type == TokenType.Numeric) { NumberToken nt = token as NumberToken; ttl = (int)nt.Value; } GetToken(); } else if (token.Type == tokenInclude) { GetToken(); // TODO: finish this // will it be a filename, need to process dots and slashes?? // there could be a domain name - how to know? // there could be a comment - how to know? } } else { ParseResourceRecord(); } }while (!(token.Type == TokenType.EndOfFile)); }
// TODO: maintain a list of token types provided by parser so that scanner can remain unbiased // TODO: maintain a list of special token types public Token GetToken(bool skipWhitespace = true) { if (skipWhitespace) { SkipWhitespace(); } if (currType == CharType.Whitespace) { return(new Token() { Type = TokenType.Whitespace }); } else if (currType == CharType.Alpha) { WordToken token = WordToken.GetToken(this); // TODO: check for reserved words return(token); } else if (currType == CharType.Numeric) { // TODO: need a scanner options class that lets me specify things like // skipping whitespace, treating numbers etc. // because here an IP address will be treated as a decimal number // 192.0[.2.1] return(NumberToken.GetToken(this)); } else if (currType == CharType.Quote) { return(StringToken.GetToken(this)); } else if (currType == CharType.EOF) { return(new EndOfFileToken()); } else if (currType == CharType.Special) { SpecialToken token = SpecialToken.GetToken(this); // TODO: check for special token types return(token); } return(null); }
protected override void ParseFactor() { if (token.Type == TokenType.Identifier) { WordToken wt = token as WordToken; var node = SearchAll(wt.Word); if (node == null) { throw new InvalidOperationException("Unknown identifier"); } else { runtimeStack.Push(node.Value); } GetToken(); } else if (token.Type == tokenPi) { runtimeStack.Push(Math.PI); GetToken(); } else if (token.Type == TokenType.Numeric) { NumberToken nt = token as NumberToken; runtimeStack.Push(nt.Value); GetToken(); } else if (token.Type == tokenOpenParentheses) { GetToken(); ParseExpression(); if (token.Type == tokenCloseParentheses) { GetToken(); } else { throw new InvalidOperationException("No closing parentheses"); } } }
public Token Get() { int tokenCode = -1; do { tokenCode = code[index++]; if (tokenCode == TokenType.LineMarker) { // TODO: replicate the global currentLineNumber from book int lineNumber = code[index++]; } }while (tokenCode == TokenType.LineMarker); if (tokenCode == TokenType.Numeric) { var token = new NumberToken(); var node = GetSymbolTableNode(); token.Value = node.Value; return(token); } if (tokenCode == TokenType.String) { var token = new StringToken(); var node = GetSymbolTableNode(); token.Value = node.Symbol; return(token); } if (tokenCode == TokenType.Identifier) { var token = new WordToken(); var node = GetSymbolTableNode(); token.Word = node.Symbol; return(token); } var defaultToken = new WordToken(); defaultToken.Word = ""; return(defaultToken); }
protected void ParseResourceRecord() { bool haveType = false; MasterFileEntry entry = new MasterFileEntry(); while (haveType == false && token.Type != TokenType.EndOfFile) { if (token.Type == TokenType.Numeric) { // most likely a <rr> beginning with TTL // [<TTL>] [<class>] <type> <RDATA> NumberToken nt = token as NumberToken; entry.TTL = (int)nt.Value; GetToken(); } else if (token.IsInList(tokensQueryClass)) { // most likely a <rr> beginning with class // [<class>] [<TTL>] <type> <RDATA> WordToken wt = token as WordToken; entry.Class = wt.Word; GetToken(); } else if (token.IsInList(tokensQueryType)) { haveType = true; WordToken wt = token as WordToken; entry.Type = wt.Word; // prepare to parse the data if (token.Type == tokenCanonicalName) { // name string - probably fqdn GetToken(); entry.Data = ParseDomainName(); } else if (token.Type == tokenHostInfo) { // CPU string GetToken(); // OS string GetToken(); GetToken(); } else if (token.Type == tokenMailExchange) { GetToken(); NumberToken nt = token as NumberToken; entry.Priority = (int)nt.Value; GetToken(); entry.Data = ParseDomainName(); } else if (token.Type == tokenNameServer) { GetToken(); entry.Data = ParseDomainName(); } else if (token.Type == tokenPointer) { GetToken(); entry.Data = ParseDomainName(); } else if (token.Type == tokenAuthority) { // name server GetToken(); // TODO: if token is open parentheses then loop until close parentheses (and stop scanner from swallowing parentheses) entry.NameServer = ParseDomainName(); // mailbox of responsible person entry.Responsible = ParseDomainName(); // serial number NumberToken nt = token as NumberToken; entry.SerialNumber = (int)nt.Value; // refresh interval GetToken(); nt = token as NumberToken; entry.RefreshInterval = (int)nt.Value; // retry interval GetToken(); nt = token as NumberToken; entry.RetryInterval = (int)nt.Value; // expiry timeout GetToken(); nt = token as NumberToken; entry.ExpiryTimeout = (int)nt.Value; // minimum ttl GetToken(); nt = token as NumberToken; entry.MinimumTTL = (int)nt.Value; GetToken(); } else if (token.Type == tokenText) { GetToken(); // TODO: this is wrong and probably needs additional parsing entry.Data = ((WordToken)token).Word; GetToken(); } else if (token.Type == tokenHostAddress) { GetToken(); entry.Data = ParseIPv4Address(); } else if (token.Type == tokenHostIPv6Address) { GetToken(); entry.Data = ParseIPv6Address(); } else if (token.Type == tokenWellKnownService) { // address GetToken(); string address = ParseIPv4Address(); string protocol = ((WordToken)token).Word; // TODO: open parentheses, loop until close } } else { // most likely a <rr> beginning with <owner> // <domain-name> [<class>] [<TTL>] <type> <RDATA> entry.Owner = ParseDomainName(); if (entry.Owner != "@") { // set default owner in case we reach another record that doesn't have an owner // see section 5.1 owner = entry.Owner; } } } if (entry.Owner == null) { entry.Owner = owner; } if (entry.Owner == "@") { entry.Owner = origin; } else if (entry.Owner.EndsWith(".") == false) { entry.Owner += "." + origin; } // add to the running list of entries found Entries.Add(entry); Console.WriteLine($"Parsed resource record: {entry.Owner}\t{entry.Type}\t{entry.Class}\t{entry.Data}"); }