protected override bool ScanFraction() { StreamPointer savPosition = streamInPtr; // Position of '.' do { NextCh(); } while (Char.IsDigit(ch)); bool result = (streamInPtr.Position > savPosition.Position + 1); // a fraction if (result) { if (ch == 'i') { symbol.TerminalId = ImagLiteral; NextCh(); } else { symbol.TerminalId = RealLiteral; } } else { InitCh(savPosition); } return(result); }
private void InitCh(StreamPointer c) { streamInPtr = c; GetStreamInChar(streamInPtr.Position, out ch); if (streamInPtr.Position <= 0) prevCh = ' '; else GetStreamInChar(streamInPtr.Position - 1, out prevCh); endText = (streamInPtr.Position > streamInLen - 1); if (endText) ch = '\x0'; }
protected override void ScanIdOrTerminalOrCommentStart() { TerminalDescr tRec; bool firstLow = Char.IsLower(ch); StreamPointer iPtr = streamInPtr; StreamPointer tPtr = iPtr; int aLen = (ch.IsIdStartChar()) ? 1 : 0; // length of longest Identifier sofar int tLen = 0; // length of longest Terminal sofar int fCnt = 0; // count of calls to FindCharAndSubtree bool isDot = (ch == '.'); // remains valid only if symbol length is 1 terminalTable.FindCharInSubtreeReset(); while (fCnt++ >= 0 && terminalTable.FindCharInSubtree(ch, out tRec)) { if (tRec != null) { symbol.TerminalId = tRec.IVal; symbol.Payload = tRec.Payload; // not used symbol.Class = tRec.Class; tLen = fCnt; tPtr = streamInPtr; // next char to be processed if (symbol.TerminalId == CommentStart || symbol.TerminalId == CommentSingle) { return; } if (terminalTable.AtLeaf) { break; // terminal cannot be extended } } NextCh(); if (aLen == fCnt && (Char.IsLetterOrDigit(ch) || ch == '_')) { aLen++; iPtr = streamInPtr; } } // fCnt++ by last (i.e. failing) Call /* * At this point: (in the Prolog case, read 'Identifier and Atom made up * from specials' for 'Identifier'): * - tLen has length of BaseTrie terminal (if any, 0 otherwise); * - aLen has length of Identifier (if any, 0 otherwise); * - fCnt is the number of characters inspected (for Id AND terminal) * - The character pointer is on the last character inspected (for both) * Iff aLen = fCnt then the entire sequence read sofar is an Identifier. * Now try extending the Identifier, only meaningful if iLen = fCnt. * Do not do this for an Atom made up from specials if a Terminal was recognized !! */ if (aLen == fCnt) { while (true) { NextCh(); if (Char.IsLetterOrDigit(ch) || ch == '_') { aLen++; iPtr = streamInPtr; } else { break; } } } if (aLen > tLen) // tLen = 0 iff Terminal == Undefined { symbol.TerminalId = Identifier; symbol.Class = SymbolClass.Id; InitCh(iPtr); } else if (symbol.TerminalId == Undefined) { InitCh(iPtr); } else // we have a terminal != Identifier { if (aLen == tLen) { symbol.Class = SymbolClass.Id; } InitCh(tPtr); } NextCh(); }
protected override void ScanIdOrTerminalOrCommentStart() { TerminalDescr tRec; bool special = ch.IsSpecialAtomChar(); bool firstLow = Char.IsLower(ch); StreamPointer iPtr = streamInPtr; StreamPointer tPtr = iPtr; int aLen = (ch.IsIdStartChar() || special) ? 1 : 0; // length of longest Atom sofar int tLen = 0; // length of longest Terminal sofar int fCnt = 0; // count of calls to FindCharAndSubtree bool isDot = (ch == '.'); // remains valid only if symbol length is 1 terminalTable.FindCharInSubtreeReset(); while (fCnt++ >= 0 && terminalTable.FindCharInSubtree(ch, out tRec)) { if (tRec != null) { symbol.TerminalId = tRec.IVal; symbol.Payload = tRec.Payload; symbol.Class = tRec.Class; tLen = fCnt; tPtr = streamInPtr; // next char to be processed if (symbol.TerminalId == CommentStart || symbol.TerminalId == CommentSingle) { return; } if (terminalTable.AtLeaf) { break; // terminal cannot be extended } } NextCh(); if (aLen == fCnt && (special && ch.IsSpecialAtomChar() || !special && ch.IsIdAtomContinueChar(extraUnquotedAtomChar) ) ) { aLen++; iPtr = streamInPtr; } } // fCnt++ by last (i.e. failing) Call // At this point: (in the Prolog case, read 'Identifier and Atom made up // from specials' for 'Identifier'): // - tLen has length of BaseTrie terminal (if any, 0 otherwise); // - aLen has length of Identifier (if any, 0 otherwise); // - fCnt is the number of characters inspected (for Id AND terminal) // - The character pointer is on the last character inspected (for both) // Iff aLen = fCnt then the entire sequence read sofar is an Identifier. // Now try extending the Identifier, only meaningful if iLen = fCnt. // Do not do this for an Atom made up from specials if a Terminal was recognized !! if (aLen == fCnt) { while (true) { NextCh(); if (special ? ch.IsSpecialAtomChar() : ch.IsIdAtomContinueChar(extraUnquotedAtomChar)) { aLen++; iPtr = streamInPtr; } else { break; } } } if (aLen > tLen) // tLen = 0 iff Terminal == Undefined { if (firstLow || special) { symbol.TerminalId = Atom; } else { symbol.TerminalId = Identifier; } symbol.Class = SymbolClass.Id; InitCh(iPtr); } else if (symbol.TerminalId == Undefined) { InitCh(iPtr); } else // we have a terminal != Identifier { if (aLen == tLen) { symbol.Class = SymbolClass.Id; } InitCh(tPtr); } NextCh(); // a bit hacky: find erroneous conditional define symbols // such as e.g. !ifxxx (space omitted between !if and xxx) if (symbol.Class == SymbolClass.Meta) { int pos = streamInPtr.Position; while (ch.IsIdAtomContinueChar(extraUnquotedAtomChar)) { NextCh(); } if (pos != streamInPtr.Position) { symbol.TerminalId = Undefined; } } // Dot-patch: a '.' is a Dot only if it is followed by layout, // otherwise it is an atom (or an operator if defined as such) if (isDot && aLen == 1 && (ch == '\0' || ch == '%' || Char.IsWhiteSpace(ch))) { symbol.TerminalId = Dot; } }