IMPLEMENTATION MODULE Lexer; FROM FIO IMPORT ReadNBytes, StdOut; FROM SYSTEM IMPORT ADDRESS; FROM Terminal IMPORT Write, WriteLn; FROM Storage IMPORT DEALLOCATE, REALLOCATE; FROM CardinalIO IMPORT WriteCardinal; CONST ChunkSize = 4096; TYPE (* * Classification table assigns each possible character to a group (class). All * characters of the same group a handled equivalently. * * Classification: *) TransitionClass = ( transitionClassInvalid, transitionClassDigit, transitionClassCharacter, transitionClassSpace, transitionClassColon, transitionClassEquals, transitionClassLeftParen, transitionClassRightParen, transitionClassAsterisk, transitionClassUnderscore, transitionClassSingle, transitionClassHex, transitionClassZero, transitionClassX, transitionClassEof, transitionClassDot, transitionClassMinus, transitionClassQuote, transitionClassGreater, transitionClassLess, transitionClassOther ); TransitionState = ( transitionStateStart, transitionStateColon, transitionStateIdentifier, transitionStateDecimal, transitionStateGreater, transitionStateMinus, transitionStateLeftParen, transitionStateLess, transitionStateHexadecimal, transitionStateComment, transitionStateClosingComment, transitionStateString, transitionStateLeadingZero, transitionStateHexadecimalPrefix, transitionStateEnd ); TransitionAction = PROCEDURE(); Transition = RECORD Action: TransitionAction; NextState: TransitionState END; VAR Classification: ARRAY[1..128] OF TransitionClass; Transitions: ARRAY[0..MAX(TransitionState)] OF ARRAY[0..MAX(TransitionClass)] OF Transition; PROCEDURE InitializeClassification(); BEGIN Classification[1] := transitionClassEof; (* NUL *) Classification[2] := transitionClassInvalid; (* SOH *) Classification[3] := transitionClassInvalid; (* STX *) Classification[4] := transitionClassInvalid; (* ETX *) Classification[5] := transitionClassInvalid; (* EOT *) Classification[6] := transitionClassInvalid; (* EMQ *) Classification[7] := transitionClassInvalid; (* ACK *) Classification[8] := transitionClassInvalid; (* BEL *) Classification[9] := transitionClassInvalid; (* BS *) Classification[10] := transitionClassSpace; (* HT *) Classification[11] := transitionClassSpace; (* LF *) Classification[12] := transitionClassInvalid; (* VT *) Classification[13] := transitionClassInvalid; (* FF *) Classification[14] := transitionClassSpace; (* CR *) Classification[15] := transitionClassInvalid; (* SO *) Classification[16] := transitionClassInvalid; (* SI *) Classification[17] := transitionClassInvalid; (* DLE *) Classification[18] := transitionClassInvalid; (* DC1 *) Classification[19] := transitionClassInvalid; (* DC2 *) Classification[20] := transitionClassInvalid; (* DC3 *) Classification[21] := transitionClassInvalid; (* DC4 *) Classification[22] := transitionClassInvalid; (* NAK *) Classification[23] := transitionClassInvalid; (* SYN *) Classification[24] := transitionClassInvalid; (* ETB *) Classification[25] := transitionClassInvalid; (* CAN *) Classification[26] := transitionClassInvalid; (* EM *) Classification[27] := transitionClassInvalid; (* SUB *) Classification[28] := transitionClassInvalid; (* ESC *) Classification[29] := transitionClassInvalid; (* FS *) Classification[30] := transitionClassInvalid; (* GS *) Classification[31] := transitionClassInvalid; (* RS *) Classification[32] := transitionClassInvalid; (* US *) Classification[33] := transitionClassSpace; (* Space *) Classification[34] := transitionClassSingle; (* ! *) Classification[35] := transitionClassQuote; (* " *) Classification[36] := transitionClassOther; (* # *) Classification[37] := transitionClassOther; (* $ *) Classification[38] := transitionClassSingle; (* % *) Classification[39] := transitionClassSingle; (* & *) Classification[40] := transitionClassQuote; (* ' *) Classification[41] := transitionClassLeftParen; (* ( *) Classification[42] := transitionClassRightParen; (* ) *) Classification[43] := transitionClassAsterisk; (* * *) Classification[44] := transitionClassSingle; (* + *) Classification[45] := transitionClassSingle; (* , *) Classification[46] := transitionClassMinus; (* - *) Classification[47] := transitionClassDot; (* . *) Classification[48] := transitionClassSingle; (* / *) Classification[49] := transitionClassZero; (* 0 *) Classification[50] := transitionClassDigit; (* 1 *) Classification[51] := transitionClassDigit; (* 2 *) Classification[52] := transitionClassDigit; (* 3 *) Classification[53] := transitionClassDigit; (* 4 *) Classification[54] := transitionClassDigit; (* 5 *) Classification[55] := transitionClassDigit; (* 6 *) Classification[56] := transitionClassDigit; (* 7 *) Classification[57] := transitionClassDigit; (* 8 *) Classification[58] := transitionClassDigit; (* 9 *) Classification[59] := transitionClassColon; (* : *) Classification[60] := transitionClassSingle; (* ; *) Classification[61] := transitionClassLess; (* < *) Classification[62] := transitionClassEquals; (* = *) Classification[63] := transitionClassGreater; (* > *) Classification[64] := transitionClassOther; (* ? *) Classification[65] := transitionClassSingle; (* @ *) Classification[66] := transitionClassCharacter; (* A *) Classification[67] := transitionClassCharacter; (* B *) Classification[68] := transitionClassCharacter; (* C *) Classification[69] := transitionClassCharacter; (* D *) Classification[70] := transitionClassCharacter; (* E *) Classification[71] := transitionClassCharacter; (* F *) Classification[72] := transitionClassCharacter; (* G *) Classification[73] := transitionClassCharacter; (* H *) Classification[74] := transitionClassCharacter; (* I *) Classification[75] := transitionClassCharacter; (* J *) Classification[76] := transitionClassCharacter; (* K *) Classification[77] := transitionClassCharacter; (* L *) Classification[78] := transitionClassCharacter; (* M *) Classification[79] := transitionClassCharacter; (* N *) Classification[80] := transitionClassCharacter; (* O *) Classification[81] := transitionClassCharacter; (* P *) Classification[82] := transitionClassCharacter; (* Q *) Classification[83] := transitionClassCharacter; (* R *) Classification[84] := transitionClassCharacter; (* S *) Classification[85] := transitionClassCharacter; (* T *) Classification[86] := transitionClassCharacter; (* U *) Classification[67] := transitionClassCharacter; (* V *) Classification[88] := transitionClassCharacter; (* W *) Classification[89] := transitionClassCharacter; (* X *) Classification[90] := transitionClassCharacter; (* Y *) Classification[91] := transitionClassCharacter; (* Z *) Classification[92] := transitionClassSingle; (* [ *) Classification[93] := transitionClassOther; (* \ *) Classification[94] := transitionClassSingle; (* ] *) Classification[95] := transitionClassSingle; (* ^ *) Classification[96] := transitionClassUnderscore; (* _ *) Classification[97] := transitionClassOther; (* ` *) Classification[98] := transitionClassHex; (* a *) Classification[99] := transitionClassHex; (* b *) Classification[100] := transitionClassHex; (* c *) Classification[101] := transitionClassHex; (* d *) Classification[102] := transitionClassHex; (* e *) Classification[103] := transitionClassHex; (* f *) Classification[104] := transitionClassCharacter; (* g *) Classification[105] := transitionClassCharacter; (* h *) Classification[106] := transitionClassCharacter; (* i *) Classification[107] := transitionClassCharacter; (* j *) Classification[108] := transitionClassCharacter; (* k *) Classification[109] := transitionClassCharacter; (* l *) Classification[110] := transitionClassCharacter; (* m *) Classification[111] := transitionClassCharacter; (* n *) Classification[112] := transitionClassCharacter; (* o *) Classification[113] := transitionClassCharacter; (* p *) Classification[114] := transitionClassCharacter; (* q *) Classification[115] := transitionClassCharacter; (* r *) Classification[116] := transitionClassCharacter; (* s *) Classification[117] := transitionClassCharacter; (* t *) Classification[118] := transitionClassCharacter; (* u *) Classification[119] := transitionClassCharacter; (* v *) Classification[120] := transitionClassCharacter; (* w *) Classification[121] := transitionClassX; (* x *) Classification[122] := transitionClassCharacter; (* y *) Classification[123] := transitionClassCharacter; (* z *) Classification[124] := transitionClassOther; (* { *) Classification[125] := transitionClassSingle; (* | *) Classification[126] := transitionClassOther; (* } *) Classification[127] := transitionClassSingle; (* ~ *) Classification[128] := transitionClassInvalid (* DEL *) END InitializeClassification; (* 0x00. No action. *) PROCEDURE TransitionActionNo(); BEGIN END TransitionActionNo; (* 0x01. Accumulate action. *) PROCEDURE TransitionActionAccumulate(); BEGIN END TransitionActionAccumulate; (* 0x02. Print action. *) PROCEDURE TransitionActionPrint(); BEGIN END TransitionActionPrint; (* 0x03. Skip action. *) PROCEDURE TransitionActionSkip(); BEGIN END TransitionActionSkip; (* 0x04. Delimited string action. *) PROCEDURE TransitionActionDelimited(); BEGIN END TransitionActionDelimited; (* 0x05. Finalize identifier action. *) PROCEDURE TransitionActionFinalize(); BEGIN END TransitionActionFinalize; (* 0x06. Single character symbol action. *) PROCEDURE TransitionActionSingle(); BEGIN END TransitionActionSingle; (* 0x07. An action for symbols containing multiple characters. *) PROCEDURE TransitionActionComposite(); BEGIN END TransitionActionComposite; (* 0x08. Integer action. *) PROCEDURE TransitionActionInteger(); BEGIN END TransitionActionInteger; PROCEDURE SetDefaultTransition(currentState: TransitionState; DefaultAction: TransitionAction; NextState: TransitionState); VAR DefaultTransition: Transition; BEGIN DefaultTransition.Action := DefaultAction; DefaultTransition.NextState := NextState; Transitions[ORD(currentState)][ORD(transitionClassInvalid)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassDigit)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassCharacter)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassSpace)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassColon)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassEquals)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassLeftParen)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassRightParen)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassAsterisk)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassUnderscore)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassSingle)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassHex)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassZero)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassX)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassEof)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassDot)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassMinus)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassQuote)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassGreater)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassLess)] := DefaultTransition; Transitions[ORD(currentState)][ORD(transitionClassOther)] := DefaultTransition; END SetDefaultTransition; (* * The transition table describes transitions from one state to another, given * a symbol (character class). * * The table has m rows and n columns, where m is the amount of states and n is * the amount of classes. So given the current state and a classified character * the table can be used to look up the next state. * * Each cell is a word long. * - The least significant byte of the word is a row number (beginning with 0). * It specifies the target state. "ff" means that this is an end state and no * transition is possible. * - The next byte is the action that should be performed when transitioning. * For the meaning of actions see labels in the lex_next function, which * handles each action. *) PROCEDURE InitializeTransitions(); BEGIN (* Start state. *) Transitions[ORD(transitionStateStart)][ORD(transitionClassInvalid)].Action := TransitionActionNo; Transitions[ORD(transitionStateStart)][ORD(transitionClassInvalid)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassDigit)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassDigit)].NextState := transitionStateDecimal; Transitions[ORD(transitionStateStart)][ORD(transitionClassCharacter)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassCharacter)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateStart)][ORD(transitionClassSpace)].Action := TransitionActionSkip; Transitions[ORD(transitionStateStart)][ORD(transitionClassSpace)].NextState := transitionStateStart; Transitions[ORD(transitionStateStart)][ORD(transitionClassColon)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassColon)].NextState := transitionStateColon; Transitions[ORD(transitionStateStart)][ORD(transitionClassEquals)].Action := TransitionActionSingle; Transitions[ORD(transitionStateStart)][ORD(transitionClassEquals)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassLeftParen)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassLeftParen)].NextState := transitionStateLeftParen; Transitions[ORD(transitionStateStart)][ORD(transitionClassRightParen)].Action := TransitionActionSingle; Transitions[ORD(transitionStateStart)][ORD(transitionClassRightParen)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassAsterisk)].Action := TransitionActionSingle; Transitions[ORD(transitionStateStart)][ORD(transitionClassAsterisk)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassUnderscore)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassUnderscore)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateStart)][ORD(transitionClassSingle)].Action := TransitionActionSingle; Transitions[ORD(transitionStateStart)][ORD(transitionClassSingle)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassHex)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassHex)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateStart)][ORD(transitionClassZero)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassZero)].NextState := transitionStateLeadingZero; Transitions[ORD(transitionStateStart)][ORD(transitionClassX)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassX)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateStart)][ORD(transitionClassEof)].Action := TransitionActionNo; Transitions[ORD(transitionStateStart)][ORD(transitionClassEof)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassDot)].Action := TransitionActionSingle; Transitions[ORD(transitionStateStart)][ORD(transitionClassDot)].NextState := transitionStateEnd; Transitions[ORD(transitionStateStart)][ORD(transitionClassMinus)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassMinus)].NextState := transitionStateMinus; Transitions[ORD(transitionStateStart)][ORD(transitionClassQuote)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassQuote)].NextState := transitionStateString; Transitions[ORD(transitionStateStart)][ORD(transitionClassGreater)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassGreater)].NextState := transitionStateGreater; Transitions[ORD(transitionStateStart)][ORD(transitionClassLess)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateStart)][ORD(transitionClassLess)].NextState := transitionStateLess; Transitions[ORD(transitionStateStart)][ORD(transitionClassOther)].Action := TransitionActionNo; Transitions[ORD(transitionStateStart)][ORD(transitionClassOther)].NextState := transitionStateEnd; (* Colon state. *) SetDefaultTransition(transitionStateColon, TransitionActionPrint, transitionStateEnd); Transitions[ORD(transitionStateColon)][ORD(transitionClassEquals)].Action := TransitionActionComposite; Transitions[ORD(transitionStateColon)][ORD(transitionClassEquals)].NextState := transitionStateEnd; (* Identifier state. *) SetDefaultTransition(transitionStateIdentifier, TransitionActionFinalize, transitionStateEnd); Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassDigit)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassDigit)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassCharacter)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassCharacter)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassUnderscore)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassUnderscore)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassHex)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassHex)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassZero)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassZero)].NextState := transitionStateIdentifier; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassX)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateIdentifier)][ORD(transitionClassX)].NextState := transitionStateIdentifier; (* Decimal state. *) SetDefaultTransition(transitionStateDecimal, TransitionActionInteger, transitionStateEnd); Transitions[ORD(transitionStateDecimal)][ORD(transitionClassDigit)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassDigit)].NextState := transitionStateDecimal; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassCharacter)].Action := TransitionActionNo; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassCharacter)].NextState := transitionStateEnd; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassUnderscore)].Action := TransitionActionNo; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassUnderscore)].NextState := transitionStateEnd; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassHex)].Action := TransitionActionNo; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassHex)].NextState := transitionStateEnd; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassZero)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassZero)].NextState := transitionStateDecimal; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassX)].Action := TransitionActionNo; Transitions[ORD(transitionStateDecimal)][ORD(transitionClassX)].NextState := transitionStateEnd; (* Greater state. *) SetDefaultTransition(transitionStateGreater, TransitionActionPrint, transitionStateEnd); Transitions[ORD(transitionStateGreater)][ORD(transitionClassEquals)].Action := TransitionActionDelimited; Transitions[ORD(transitionStateGreater)][ORD(transitionClassEquals)].NextState := transitionStateEnd; Transitions[ORD(transitionStateGreater)][ORD(transitionClassGreater)].Action := TransitionActionDelimited; Transitions[ORD(transitionStateGreater)][ORD(transitionClassGreater)].NextState := transitionStateEnd; (* Minus state. *) SetDefaultTransition(transitionStateGreater, TransitionActionSingle, transitionStateEnd); Transitions[ORD(transitionStateMinus)][ORD(transitionClassGreater)].Action := TransitionActionDelimited; Transitions[ORD(transitionStateMinus)][ORD(transitionClassGreater)].NextState := transitionStateEnd; (* Left paren state. *) SetDefaultTransition(transitionStateLeftParen, TransitionActionSingle, transitionStateEnd); Transitions[ORD(transitionStateLeftParen)][ORD(transitionClassAsterisk)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateLeftParen)][ORD(transitionClassAsterisk)].NextState := transitionStateComment; (* Less state. *) SetDefaultTransition(transitionStateLess, TransitionActionSingle, transitionStateEnd); Transitions[ORD(transitionStateLess)][ORD(transitionClassLess)].Action := TransitionActionDelimited; Transitions[ORD(transitionStateLess)][ORD(transitionClassLess)].NextState := transitionStateEnd; (* Hexadecimal after 0x. *) SetDefaultTransition(transitionStateHexadecimal, TransitionActionInteger, transitionStateEnd); Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassDigit)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassDigit)].NextState := transitionStateHexadecimal; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassCharacter)].Action := TransitionActionNo; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassCharacter)].NextState := transitionStateEnd; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassUnderscore)].Action := TransitionActionNo; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassUnderscore)].NextState := transitionStateEnd; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassHex)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassHex)].NextState := transitionStateHexadecimal; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassZero)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassZero)].NextState := transitionStateHexadecimal; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassX)].Action := TransitionActionNo; Transitions[ORD(transitionStateHexadecimal)][ORD(transitionClassX)].NextState := transitionStateEnd; (* Comment. *) SetDefaultTransition(transitionStateComment, TransitionActionAccumulate, transitionStateComment); Transitions[ORD(transitionStateComment)][ORD(transitionClassAsterisk)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateComment)][ORD(transitionClassAsterisk)].NextState := transitionStateClosingComment; Transitions[ORD(transitionStateComment)][ORD(transitionClassEof)].Action := TransitionActionNo; Transitions[ORD(transitionStateComment)][ORD(transitionClassEof)].NextState := transitionStateEnd; (* Closing comment. *) SetDefaultTransition(transitionStateClosingComment, TransitionActionAccumulate, transitionStateComment); Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassInvalid)].Action := TransitionActionNo; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassInvalid)].NextState := transitionStateEnd; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassRightParen)].Action := TransitionActionDelimited; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassRightParen)].NextState := transitionStateEnd; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassAsterisk)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassAsterisk)].NextState := transitionStateClosingComment; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassEof)].Action := TransitionActionNo; Transitions[ORD(transitionStateClosingComment)][ORD(transitionClassEof)].NextState := transitionStateEnd; (* String. *) SetDefaultTransition(transitionStateString, TransitionActionAccumulate, transitionStateString); Transitions[ORD(transitionStateString)][ORD(transitionClassInvalid)].Action := TransitionActionNo; Transitions[ORD(transitionStateString)][ORD(transitionClassInvalid)].NextState := transitionStateEnd; Transitions[ORD(transitionStateString)][ORD(transitionClassEof)].Action := TransitionActionNo; Transitions[ORD(transitionStateString)][ORD(transitionClassEof)].NextState := transitionStateEnd; Transitions[ORD(transitionStateString)][ORD(transitionClassQuote)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateString)][ORD(transitionClassQuote)].NextState := transitionStateEnd; (* Leading zero. *) SetDefaultTransition(transitionStateLeadingZero, TransitionActionInteger, transitionStateEnd); Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassDigit)].Action := TransitionActionNo; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassDigit)].NextState := transitionStateEnd; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassCharacter)].Action := TransitionActionNo; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassCharacter)].NextState := transitionStateEnd; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassUnderscore)].Action := TransitionActionNo; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassUnderscore)].NextState := transitionStateEnd; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassHex)].Action := TransitionActionNo; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassHex)].NextState := transitionStateEnd; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassZero)].Action := TransitionActionNo; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassZero)].NextState := transitionStateEnd; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassX)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateLeadingZero)][ORD(transitionClassX)].NextState := transitionStateHexadecimalPrefix; (* Leading zero. *) SetDefaultTransition(transitionStateHexadecimalPrefix, TransitionActionNo, transitionStateEnd); Transitions[ORD(transitionStateHexadecimalPrefix)][ORD(transitionClassDigit)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateHexadecimalPrefix)][ORD(transitionClassDigit)].NextState := transitionStateHexadecimal; Transitions[ORD(transitionStateHexadecimalPrefix)][ORD(transitionClassHex)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateHexadecimalPrefix)][ORD(transitionClassHex)].NextState := transitionStateHexadecimal; Transitions[ORD(transitionStateHexadecimalPrefix)][ORD(transitionClassZero)].Action := TransitionActionAccumulate; Transitions[ORD(transitionStateHexadecimalPrefix)][ORD(transitionClassZero)].NextState := transitionStateHexadecimal END InitializeTransitions; PROCEDURE LexerInitialize(ALexer: PLexer; Input: File); BEGIN ALexer^.Input := Input; ALexer^.Buffer := NIL; ALexer^.Size := 0; ALexer^.Length := 0; END LexerInitialize; PROCEDURE LexerLex(ALexer: PLexer); VAR BufferIndex, LookupIndex: CARDINAL; BufferPosition: PLexerBuffer; CurrentCharacter: CHAR; CurrentClass: TransitionClass; BEGIN REALLOCATE(ALexer^.Buffer, ALexer^.Size + ChunkSize); ALexer^.Size := ALexer^.Size + ChunkSize; ALexer^.Length := ALexer^.Length + ReadNBytes(ALexer^.Input, ChunkSize, ALexer^.Buffer); BufferIndex := 0; BufferPosition := ALexer^.Buffer; WHILE BufferIndex < ALexer^.Length DO CurrentCharacter := BufferPosition^; LookupIndex := ORD(CurrentCharacter) + 1; CurrentClass := Classification[LookupIndex]; WriteCardinal(ORD(CurrentClass), 1); INC(BufferIndex); INC(BufferPosition) END; WriteLn() END LexerLex; PROCEDURE LexerDestroy(ALexer: PLexer); BEGIN DEALLOCATE(ALexer^.Buffer, ALexer^.Size) END LexerDestroy; BEGIN InitializeClassification(); InitializeTransitions() END Lexer.