Object subclass: #TranslatorGenerator instanceVariableNames: 'grammar transformedGrammar isLL1 isSLR1 isLALR1 isLR1 parser statusTextBuffer tokenSpecification grammarSpecification inputText grammarMode parserMode parserResult tokenSpecController scannerClass treeBuilderClass oldScannerSpec oldScannerLits oldScanner specsFileName conflictStrategy ' classVariableNames: 'StatusTextBufferMenu TextMenu TokenSpecMetaChars ' poolDictionaries: '' category: 'T-gen-Interface'! TranslatorGenerator comment: '================================================= Copyright (c) 1992 by Justin O. Graver. All rights reserved (with exceptions). For complete information evaluate "Object tgenCopyright." ================================================= I''m an application for generating scanners and parsers for arbitrary context-free languages. My view contains four panes and several status buttons, as described below: View Panes: top-left - token class specifications are entered and ''accepted'' here. bottom-left - grammar specifications are entered and ''accepted'' here. Status buttons control what kind of parser is generated, either LL or LR varieties. top-right - status transcript, status messages and other information is sent here. bottom-right - test strings in the specified language are entered and ''accepted'' here. Status buttons control the resulting parser actions. To view the result of a test input parse choose the middle button menu item ''result'' in the transcript pane. I attempt to generate a parser for a given a context-free grammar. Basically, I try LL(1) first and LR variations second. (See the parser generation protocol for more details.) Instance Variables: grammar - original context-free grammar for which I''m trying to build a parser. transformedGrammar - an LL(1) transformed version of my grammar, if needed, requested, and possible. isLL1, isSLR1, isLALR1, isLR1 - grammar status flags. parser - a parser for my grammar, if one could be built. statusTextBuffer - status transcript pane text buffer. tokenSpecification grammarSpecification inputText grammarMode - represents state of grammar pane status button. parserMode - represents state of test input pane status button. parserResult - result of test input parse. tokenSpecController - ''accepting'' a grammar specification actually processes both grammar and token class specifications. Direct access to the token spec Controller is needed for reporting errors in the token class specification. scannerClass - class used to build scanners. Some languages may require more sophisticated scanners with multiple-token lookahead (see FSABasedScannerWithOneTokenLookahead and FSABasedScannerWithTwoTokenLookahead). treeBuilderClass - class used to build AST builders for parsers. Users may define specilizations of this class. oldScannerSpec - previous scanner spec. oldScannerLits - literals from previous grammar spec. oldScanner - previously generated scanner. specsFileName - last used base file name for saving or loading specs. Class Variables: StatusTextBufferMenu - menu cache TextMenu - menu cache TokenSpecMetaChars - These characters are special to the token specification parser and must be escaped.'! !TranslatorGenerator methodsFor: 'status text'! clear "Reset the transcriptView for the next accept." self statusTextBuffer clear! cr "Perform a carriage return." self statusTextBuffer cr! show: aString "Append aString to the status transcript text." self statusTextBuffer show: aString! showCR: aString "Append aString to the status transcript text and perform a carriage return." self statusTextBuffer show: aString; cr! tab "Perform a tab over." self statusTextBuffer tab! ! !TranslatorGenerator methodsFor: 'state accessing'! grammar ^grammar! grammar: argument grammar := argument! grammarMode ^grammarMode! grammarMode: argument grammarMode := argument! grammarSpecification ^grammarSpecification! grammarSpecification: argument grammarSpecification := argument! inputText ^inputText! inputText: argument inputText := argument! isLALR1 ^isLALR1! isLALR1: argument isLALR1 := argument! isLL1 ^isLL1! isLL1: argument isLL1 := argument! isLR1 ^isLR1! isLR1: argument isLR1 := argument! isSLR1 ^isSLR1! isSLR1: argument isSLR1 := argument! oldScanner ^oldScanner! oldScanner: argument oldScanner := argument! oldScannerLits ^oldScannerLits! oldScannerLits: argument oldScannerLits := argument! oldScannerSpec ^oldScannerSpec! oldScannerSpec: argument oldScannerSpec := argument! parser ^parser! parser: argument parser := argument! parserMode ^parserMode! parserMode: argument parserMode := argument! parserResult ^parserResult! parserResult: argument parserResult := argument! scannerClass ^scannerClass! scannerClass: argument scannerClass := argument! specsFileName ^specsFileName! specsFileName: argument specsFileName := argument! statusTextBuffer ^statusTextBuffer! statusTextBuffer: argument statusTextBuffer := argument! tokenSpecController ^tokenSpecController! tokenSpecController: argument tokenSpecController := argument! tokenSpecification ^tokenSpecification! tokenSpecification: argument tokenSpecification := argument! transformedGrammar ^transformedGrammar! transformedGrammar: argument transformedGrammar := argument! treeBuilderClass ^treeBuilderClass! treeBuilderClass: argument treeBuilderClass := argument! ! !TranslatorGenerator methodsFor: 'LL parser generation'! ll1Parser "Attempt to construct an LL(1) parser for my grammar. Answer true if I can and false otherwise." | table prod | table := self llParserTableClass new. self grammar selectSets associationsDo: [:assoc | prod := assoc key. assoc value do: [:term | table atNonterminal: prod leftHandSide andTerminal: term addProduction: prod]]. table isDeterministic ifTrue: [self isLL1: true. self parser: (self ll1ParserClass parseTable: table spaceOptimize startSymbol: self grammar startSymbol). ^true] ifFalse: [self parser: (self ll1ParserClass parseTable: table startSymbol: self grammar startSymbol). ^false]! ll1ParserWithTransformations "Assuming my original grammar is not LL(1), attempt to derive an equivalent LL(1) grammar and parser for my original grammar through various grammar manipulations. Answer true if I can and false otherwise." | oldGrammar | oldGrammar := self grammar. self grammar: oldGrammar copy. self grammar makeLL1Transformations. self ll1Parser ifTrue: [self isLL1: true. self transformedGrammar: self grammar. self grammar: oldGrammar. ^true] ifFalse: [self grammar: oldGrammar. ^false]! ! !TranslatorGenerator methodsFor: 'private'! astModeMarker ^#AST! computeProductionMap "Delegate to my grammar." ^self grammar computeProductionMap! defaultModeMarker ^#default! defaultScannerClass "This is the default scanner class, a more specialized scanner class may be designated using a middle button menu item in the transcript pane." ^FSABasedScanner! defaultTreeBuilderClass "This is the default tree builder class, a more specialized tree builder class may be designated using a middle button menu item in the transcript pane." ^AbstractSyntaxTreeBuilder! fsaStateClass ^FSAState! grammarClass ^Grammar! initialLR0ItemSet ^ItemSet with: (self lr0ItemClass initialItemForGrammar: self grammar)! initialLR1ItemSet ^ItemSet with: (self lr1ItemClass initialItemForGrammar: self grammar)! ll1ParserClass ^LL1Parser! llModeMarker ^#LL! llParserTableClass ^LLParserTable! lr0ItemClass ^LR0Item! lr1ItemClass ^LR1Item! lr1LookaheadSetFor: item "Delegate to my grammar." ^self grammar lr1LookaheadSetFor: item! lrModeMarker ^#LR! lrParserClass ^LR1Parser! lrParserFinalStateClass ^FSAFinalState! lrParserStateClass ^LRParserState! shamAstModeMarker ^#shamAST! traceModeMarker ^#Trace! ! !TranslatorGenerator methodsFor: 'LR parser generation'! computeLR0ClosureOf: itemSet "For all items in itemSet of the form 'B -> . A ' recursively add new items of the form 'A -> . '." ^self computeLR0ClosureOf: itemSet withProdMap: self computeProductionMap! computeLR0ClosureOf: itemSet withProdMap: prodMap "For all items in itemSet of the form 'B -> . A ' recursively add new items of the form 'A -> . '." | nonterms sym newItemSet | nonterms := Set new. itemSet do: [:item | (sym := item nextSymbol) isNonterminal ifTrue: [nonterms add: sym]]. newItemSet := ItemSet new. newItemSet addAll: itemSet. nonterms do: [:nont | newItemSet addAll: ((prodMap at: nont) collect: [:prod | prod asInitialLR0Item])]. ^itemSet size = newItemSet size ifTrue: [newItemSet] ifFalse: [self computeLR0ClosureOf: newItemSet withProdMap: prodMap]! computeLR1ClosureOf: itemSet "For all items in itemSet of the form 'B -> . A : lookahead' recursively add new items of the form 'A -> . : First( lookahead)'." ^self computeLR1ClosureOf: itemSet withProdMap: self computeProductionMap! computeLR1ClosureOf: itemSet withProdMap: prodMap "For all items in itemSet of the form 'B -> . A : lookahead' recursively add new items of the form 'A -> . : First( lookahead)'." | nontermItems newItemSet | nontermItems := Set new. itemSet do: [:item | item nextSymbol isNonterminal ifTrue: [nontermItems add: item]]. newItemSet := ItemSet new. newItemSet addAll: itemSet. nontermItems do: [:item | (self lr1LookaheadSetFor: item) do: [:la | (prodMap at: item nextSymbol) do: [:prod | newItemSet add: (prod asInitialLR1ItemWithLookahead: la)]]]. ^itemSet size = newItemSet size ifTrue: [newItemSet] ifFalse: [self computeLR1ClosureOf: newItemSet withProdMap: prodMap]! extantStateFor: itemSet in: stateItemMap "If stateItemMap includes itemSet as one of its values answer the corresponding state, otherwise answer nil. (This is the same as Dictionary>>keyAtValue:ifAbsent: [^nil] except that it uses = rather than ==.)" stateItemMap associationsDo: [:assoc | assoc value = itemSet ifTrue: [^assoc key]]. ^nil! findTransitionItemSet: itemSet "Arbitrarily choose a transition symbol (immediately after a dot) and answer the set of items that have transitions on that symbol. All 'atEnd' items have already been removed." | transitSym | transitSym := itemSet first postDotSymbols first. ^itemSet select: [:item | self is: item postDotSymbols first theSameAs: transitSym]! is: symOne theSameAs: symTwo "Compare the symbols for equality. This method is required because T-gen uses Strings to represent terminals and Symbols for non-terminals, and a String and Symbol with the same characters are considered equal. Thus, 'prod' = #prod is true in Smalltalk but not in T-gen." ^symOne isTerminal = symTwo isTerminal ifTrue: [symOne = symTwo] ifFalse: [false]! lr1Parser "Attempt to build an LR(1) parser for my grammar. Answer true if successful and false otherwise. Based on Algorithm 6.2 from 'Principles of Compiler Design', by Aho and Ullman, 1977." | stateItemMap startState unprocessedStates currState closure transitItems transitSym newItemSet nextState finalState conflictStates | stateItemMap := Dictionary new. conflictStates := Set new. startState := self lrParserStateClass new. unprocessedStates := Set with: startState. stateItemMap at: startState put: self initialLR1ItemSet. [unprocessedStates isEmpty] whileFalse: [currState := unprocessedStates removeFirst. closure := self computeLR1ClosureOf: (stateItemMap at: currState). "Process all reduce items." (closure select: [:item | item atEnd]) do: [:item | item isFinalStateItem ifTrue: [finalState := currState] ifFalse: [currState reduceMap at: item lookahead add: item asGrammarProduction. currState reduceMap at: item lookahead ifNotUnique: ["reduce/reduce conflict" conflictStates add: currState]]. closure remove: item]. [closure isEmpty] whileFalse: [transitItems := self findTransitionItemSet: closure. transitSym := transitItems first postDotSymbols first. newItemSet := ItemSet new. transitItems do: [:item | newItemSet add: item copy shift]. (nextState := self extantStateFor: newItemSet in: stateItemMap) isNil ifTrue: [nextState := self lrParserStateClass new. unprocessedStates add: nextState. stateItemMap at: nextState put: newItemSet]. currState goto: nextState on: transitSym. (currState reduceMap includesKey: transitSym) ifTrue: ["shift/reduce conflict" conflictStates add: currState]. closure removeAll: transitItems]]. conflictStates isEmpty ifTrue: [self isLR1: true. self parser: (self lrParserClass parseTable: startState finalState: finalState) spaceOptimize. ^true] ifFalse: [self parser: (self lrParserClass parseTable: startState finalState: finalState). ^false]! slr1Parser "Attempt to build an SLR(1) parser for my grammar. Answer true if successful and false otherwise. Based on Algorithm 6.1 from 'Principles of Compiler Design', by Aho and Ullman, 1977." | stateItemMap startState unprocessedStates currState closure transitItems transitSym newItemSet nextState finalState conflictStates slr1Parser | stateItemMap := Dictionary new. conflictStates := Set new. startState := self lrParserStateClass new. unprocessedStates := Set new. stateItemMap at: startState put: self initialLR0ItemSet. unprocessedStates add: startState. [unprocessedStates isEmpty] whileFalse: [currState := unprocessedStates removeFirst. closure := self computeLR0ClosureOf: (stateItemMap at: currState). "Process all reduce items." (closure select: [:item | item atEnd]) do: [:item | item isFinalStateItem ifTrue: [finalState := currState] ifFalse: ["SLR(1) lookahead symbols" (self grammar followSetOf: item leftHandSide) do: [:term | currState reduceMap at: term add: item asGrammarProduction. currState reduceMap at: term ifNotUnique: ["reduce/reduce conflict" conflictStates addAll: (conflictStrategy resolveReduceReduceFor: term atState: currState)]]]. closure remove: item]. [closure isEmpty] whileFalse: [transitItems := self findTransitionItemSet: closure. transitSym := transitItems first postDotSymbols first. newItemSet := ItemSet new. transitItems do: [:item | newItemSet add: item copy shift]. (nextState := self extantStateFor: newItemSet in: stateItemMap) isNil ifTrue: [nextState := self lrParserStateClass new. unprocessedStates add: nextState. stateItemMap at: nextState put: newItemSet]. currState goto: nextState on: transitSym. (currState reduceMap includesKey: transitSym) ifTrue: ["shift/reduce conflict" conflictStates addAll: (conflictStrategy resolveShiftReduceFor: transitSym atState: currState)]. closure removeAll: transitItems]]. slr1Parser := self lrParserClass parseTable: startState finalState: finalState. conflictStates isEmpty ifTrue: [self isSLR1: true. self parser: slr1Parser spaceOptimize. ^true] ifFalse: ["try LALR(1) analysis" (slr1Parser lalr1AnalyzeConflicts: conflictStates originalGrammar: self grammar) ifTrue: [self isLALR1: true. self parser: slr1Parser spaceOptimize. ^true] ifFalse: [self parser: slr1Parser. ^false]]! ! !TranslatorGenerator methodsFor: 'scanner generation'! buildFSAFrom: rules and: literalDict "Answer a minimal deterministic FSA that will recognize rules and literals." | startState fsa stream ch state nextStateSet nextState | "First, build the basic DFSA for the token classes (rules)." startState := self fsaStateClass new. rules do: [:rule | rule regExpr asFSAWithType: rule tokenClass andAction: rule directive startingAt: startState]. fsa := startState asNearMinimalDFSAWithUniqueTokenClasses. "Then, see if any of the literal tokens (keywords) can be placed in an existing final state." literalDict copy associationsDo: [:assoc | stream := ReadStream on: assoc key. ch := stream next. state := fsa. "Remember, we have not yet space optimized so we are dealing with SetDictionaries." [nextStateSet := state transitionFor: ch ifNone: [nil]. nextState := nextStateSet isNil ifTrue: [nil] ifFalse: [nextStateSet first]. nextState isNil or: [stream atEnd]] whileFalse: [state := nextState. ch := stream next]. nextState isFSAFinalState ifTrue: [nextState addLiteralToken: assoc key. literalDict removeKey: assoc key]]. "Attach remaining literal tokens to start state, re-DFSA-ify, and space optimize." literalDict associationsDo: [:assoc | assoc value asFSAWithLiteral: assoc key startingAt: fsa]. ^fsa asNearMinimalDFSAWithUniqueTokenClasses spaceOptimize! buildLiteralDictionaryIfFail: aBlock "Answer a Dictionary from (de-escaped) literal tokens to their corresponding regular expressions." | litDict | litDict := Dictionary new. self grammar literalTerminals do: [:lit | litDict at: lit put: (self convertToRegExpr: lit ifFail: aBlock)]. ^litDict! buildScannerFromRules: rules withLiteralDict: literalDict "Answer a scanner that scans according to the rules, also recognizing literalTokens." | fsa | fsa := self buildFSAFrom: rules and: literalDict. ^self scannerClass new fsa: fsa! convertToRegExpr: aString ifFail: aBlock "Answer a regular expression object by interpreting aString as a token class specification. Token specification meta-characters must be escaped in aString." | rules tokenSpecNode | tokenSpecNode := self tokenSpecParser parseForAST: (self escapedTokenSpecDeclFor: aString) ifFail: aBlock. rules := tokenSpecNode asSpecRuleList. ^rules first regExpr! escapedTokenSpecDeclFor: aString "Answer a string of the form ' : aString ;' where all metacharacters in aString have been escaped (proceeded by a backslash)." | aStream metaChars | aStream := WriteStream on: (String new: 20). aStream nextPutAll: ' : '. metaChars := self tokenSpecMetaChars. aString do: [:ch | (metaChars includes: ch) ifTrue: [aStream nextPut: $\]. aStream nextPut: ch]. aStream nextPut: $;. ^aStream contents! oldBuildFSAFrom: rules and: literalDict "Answer a minimal deterministic FSA that will recognize rules and literals." | startState | startState := self fsaStateClass new. rules do: [:rule | rule regExpr asFSAWithType: rule tokenClass andAction: rule directive startingAt: startState]. literalDict associationsDo: [:assoc | assoc value asFSAWithLiteral: assoc key startingAt: startState]. ^startState asNearMinimalDFSAWithUniqueTokenClasses spaceOptimize! sameScannerSpec: newSpec usingLits: newLits "Has the Specification for the scanner changed since it was last generated?" (self oldScannerSpec = nil or: [self oldScannerLits = nil]) ifTrue: [^false]. ^self oldScannerLits size = (newLits keys union: self oldScannerLits) size and: [self oldScannerSpec = newSpec asString]! ! !TranslatorGenerator methodsFor: 'parser generation'! generateLLParser "Try to build an LL parser for this language." self ll1Parser ifTrue: [^true]. (Dialog confirm: 'Grammar is not LL(1) but a transformation may be. Do you wish to try transforming the grammar?') ifTrue: [self ll1ParserWithTransformations ifTrue: [^true]]. ^false! generateLRParser "Try to build an LR parser for this language." self slr1Parser ifTrue: [^true]. (Dialog confirm: 'Grammar is not LALR(1). Do you wish to try LR(1) analysis (this may take a while)?') ifTrue: [self lr1Parser ifTrue: [^true]]. ^false! generateParser "Try to build a parser for this language." ^self generateLLParser ifTrue: [true] ifFalse: [self generateLRParser]! grammarClassification "Answer a string describing my classification." self isLL1 ifTrue: [self transformedGrammar isNil ifTrue: [^'Grammar is LL(1).'] ifFalse: [^'Grammar is LL(1), but required transformations.']]. self isSLR1 ifTrue: [^'Grammar is SLR(1).']. self isLALR1 ifTrue: [^'Grammar is LALR(1).']. self isLR1 ifTrue: [^'Grammar is LR(1).'] ifFalse: [^'Parser generation failed; nondeterministic parser is available for inspection.']! ! !TranslatorGenerator methodsFor: 'initialization'! init "set status defaults" statusTextBuffer := TextCollector new. self resetParserAndFlags. self tokenSpecification: Text new. self setGrammarModeToDefault. self setParserModeToDefault. self scannerClass: self defaultScannerClass. self treeBuilderClass: self defaultTreeBuilderClass. self oldScannerSpec: nil. self oldScannerLits: nil. conflictStrategy := StandardConflictStrategy new.! resetParserAndFlags "Reset my state for parser generation." self isLL1: false. self isSLR1: false. self isLALR1: false. self isLR1: false. self parser: nil. self grammar: nil. self transformedGrammar: nil! ! !TranslatorGenerator methodsFor: 'public access'! buildParserIfFail: aBlock | tokenSpecNode grammarNode rules scanner newParser litDict | self resetParserAndFlags. tokenSpecNode := self tokenSpecParser parseForAST: self tokenSpecification ifFail: aBlock. grammarNode := self grammarSpecParser parseForAST: self grammarSpecification ifFail: aBlock. rules := tokenSpecNode asSpecRuleList. self cr; show: 'Checking grammar... '. self grammarClass notReducedSignal handle: [:ex | self showCR: ex errorString. ^aBlock value] do: [self grammar: grammarNode asContextFreeGrammar]. self showCR: 'done.'. litDict := self buildLiteralDictionaryIfFail: aBlock. self show: 'Building scanner... starting at: '. self showCR: Time now printString; tab. (self sameScannerSpec: self tokenSpecification usingLits: litDict) ifTrue: [self showCR: 'Scanner has not changed - no build required.'. scanner := self oldScanner] ifFalse: [self showCR: 'Scanner new or has changed - build required.'. Cursor execute showWhile: [scanner := self buildScannerFromRules: rules withLiteralDict: litDict]]. self tab; showCR: '...done.'. self oldScannerSpec: self tokenSpecification asString. "Must force a copy" self oldScannerLits: litDict keys. self oldScanner: scanner. self show: 'Building parser...starting at: '. self showCR: Time now printString. Cursor execute showWhile: [self isGrammarModeDefault ifTrue: [self generateParser] ifFalse: [self isGrammarModeLL ifTrue: [self generateLLParser] ifFalse: [self isGrammarModeLR ifTrue: [self generateLRParser] ifFalse: [self error: 'What mode am I in then?!!?!!']]]]. self tab; show: '...done at:'. self showCR: Time now printString. self showCR: self grammarClassification. newParser := self parser. newParser scanner: scanner. newParser treeBuilder: self treeBuilderClass new. ^newParser! loadSpecFrom: fileName | file | file := Filename named: fileName , '.tok'. file isReadable ifTrue: [(Dialog confirm: 'This load will overwrite the existing specs. Are you sure you want to do this?') ifFalse: [^self]. tokenSpecification := file contentsOfEntireFile. self changed: #tokenSpecification] ifFalse: [self showCR: 'Could not find file ''' , fileName , '.tok' , ''' - skipping load.'. ^self]. file := Filename named: fileName , '.grm'. file isReadable ifTrue: [grammarSpecification := file contentsOfEntireFile. self changed: #grammarSpecification]. file := Filename named: fileName , '.eg'. file isReadable ifTrue: [inputText := file contentsOfEntireFile. self changed: #inputText]! saveSpecTo: fileName tokenSpecification notNil ifTrue: [((Filename named: fileName , '.tok') writeStream) nextPutAll: tokenSpecification; close]. grammarSpecification notNil ifTrue: [((Filename named: fileName , '.grm') writeStream) nextPutAll: grammarSpecification; close]. ^inputText notNil ifTrue: [((Filename named: fileName , '.eg') writeStream) nextPutAll: inputText; close]! ! !TranslatorGenerator methodsFor: 'accessing'! grammarSpecParser ^self class grammarSpecParser! tokenSpecMetaChars ^TokenSpecMetaChars! tokenSpecParser ^self class tokenSpecParser! ! !TranslatorGenerator methodsFor: 'input text'! acceptInputText: aText from: aController self inputText: aText. self parser isNil ifTrue: [self cr; showCR: 'No parser has been generated.'. ^true]. isLL1 | isSLR1 | isLALR1 | isLR1 ifFalse: [(Dialog confirm: 'The current parser was nondeterministic when built. Are you sure you want to continue?') ifFalse: [^true]]. self parser requestor: aController. self isParserModeDefault ifTrue: [self parserResult: (self parser parseForDerivationTree: aText asString ifFail: [^false]). self postInspectResultMessage. ^true]. self isParserModeTrace ifTrue: [self parserResult: (self parser parseAndTrace: aText asString on: self ifFail: [^false]). self postSuccessMessage. ^true]. self isParserModeShamAST ifTrue: [self parserResult: (self parser parseForShamAST: aText asString ifFail: [^false]). self postInspectResultMessage. ^true]. self isParserModeAST ifTrue: [self parserResult: (self parser parseForAST: aText asString ifFail: [^false]). self postInspectResultMessage. ^true]. ^false! postInspectResultMessage self cr; showCR: 'Choose ''result'' from the middle button menu in this pane to inspect the results of the successful parse.'! postSuccessMessage self cr; showCR: 'The parse of the test input was successful.'! ! !TranslatorGenerator methodsFor: 'parser mode'! isParserModeAST ^self parserMode = self astModeMarker! isParserModeDefault ^self parserMode = self defaultModeMarker! isParserModeShamAST ^self parserMode = self shamAstModeMarker! isParserModeTrace ^self parserMode = self traceModeMarker! setParserMode: modeMarker self parserMode: modeMarker. self changed: #value "broadcast change so radio buttons may change"! setParserModeToAST self parserMode: self astModeMarker! setParserModeToDefault self parserMode: self defaultModeMarker! setParserModeToShamAST self parserMode: self shamAstModeMarker! setParserModeToTrace self parserMode: self traceModeMarker! ! !TranslatorGenerator methodsFor: 'grammar mode'! isGrammarModeDefault ^self grammarMode = self defaultModeMarker! isGrammarModeLL ^self grammarMode = self llModeMarker! isGrammarModeLR ^self grammarMode = self lrModeMarker! setGrammarMode: modeMarker self grammarMode: modeMarker. self changed: #value "broadcast change so radio buttons may change"! setGrammarModeToDefault self grammarMode: self defaultModeMarker! setGrammarModeToLL self grammarMode: self llModeMarker! setGrammarModeToLR self grammarMode: self lrModeMarker! ! !TranslatorGenerator methodsFor: 'grammar text'! acceptGrammarSpec: aText from: aController self grammarSpecification: aText. self grammarSpecParser requestor: aController. self tokenSpecParser requestor: self tokenSpecController. (self tokenSpecification isNil or: [self tokenSpecification isEmpty]) ifTrue: [self cr; showCR: 'No token classes have been specified (did you forget to ''accept'' them?).']. self buildParserIfFail: [^false]. ^true! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! TranslatorGenerator class instanceVariableNames: 'grammarSpecParser tokenSpecParser '! !TranslatorGenerator class methodsFor: 'version information'! versionName ^'T-gen, Version 2.1'! ! !TranslatorGenerator class methodsFor: 'examples'! example1 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: (none) grammar spec: S : 'a' S 'b' {Pair} ; S : {Core} ; status: LL(1) and SLR(1) test input: aaabbb "! example10 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: : [a-z] ; : [0-9]+ ; : [\s\t\r]+ {ignoreDelimiter} ; grammar spec: Prog : LetExpr ; Prog : Expr {LetNode} ; LetExpr : 'let' Defs 'in' Expr {LetNode} ; Defs : Def Defs0 {liftRightChild} ; Defs0 : ',' Defs ; Defs0 : {OrderedChildren} ; Def : VarName '=' Number {DefinitionNode} ; Expr : Term Expr0 {liftRightChild}; Expr0 : '+' Expr {PlusNode} ; Expr0 : '-' Expr {MinusNode} ; Expr0 : {nil} ; Term : Factor Term0 {liftRightChild}; Term0 : '*' Term {TimesNode} ; Term0 : '/' Term {DivideNode} ; Term0 : {nil}; Factor : VarName ; Factor : Number ; Factor : '(' Expr ')' ; VarName : {VarNode} ; Number : {NumberNode} ; status: LL(1) and SLR(1) test input: let x = 3, y = 7, z = 2 in x * (y + z / 4) "! example11 "This grammar demonstrates the ability to fix nondeterministic parsers by hand. Evaluate the following expression and then test the grammar. Try to build an LL(1) parser and when asked to perform transformations, answer no. From the middle button menu in the transcript pane inspect the parser. Inspect the parseTable instance variable. The 'E' row and 'else' column has a double entry. Using the inspectors, remove the production 'E : ;' from the set and evaluate 'self spaceOptimize' in the parseTable inspector. The resulting parser will successfully parse the input and can be installed. For more information see the T-gen User's Guide." "TranslatorGeneratorView open" "token spec: : [\s\t\r]+ {ignoreDelimiter} ; grammar spec: G : S ';' ; S : 'if' S E | 'other' ; E : 'else' S | ; status: not LL(1) and not LR(1) test input: if if other else other; "! example2 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: : [a-z]+ ; : [0-9]+ ; : [\s\t\r]+ {ignoreDelimiter} ; grammar spec: Z : 'program' Decls Stmts {Program} ; Decls : 'var' IdList ':' 'integer' {Decls} ; IdList : Name IdList {liftRightChild} ; IdList : Name {IdList} ; Stmts : 'begin' SL 'end' {Stmts} ; SL : S SL {liftRightChild} ; SL : Stmts SL {liftRightChild} ; SL : S {StmtList} ; SL : Stmts {StmtList} ; S : Name ':=' E ';' {Assign} ; E : E '+' T {Plus} ; E : T ; T : P '*' T {Times} ; T : P; P : '(' E ')' ; P : Name ; P : {Number} ; Name : {Id} ; status: SLR(1) and LL(1), with transformations test input: program var a b c : integer begin a := 3; b := a * 4 * 5; begin c := a + b * 19; b := b * c + 1; a := (a + 1) * a; end c := b * (c + 5); end "! example3 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: : [\s\t\r]+ {ignoreDelimiter} ; grammar spec: E : T Ec {liftRightChild} ; Ec : '+' E {Plus} ; Ec : {nil} ; T : P Tc {liftRightChild} ; Tc : '*' T {Times} ; Tc : {nil} ; P : 'a' {A} ; P : 'b' {B} ; P : 'c' {C} ; status: LL(1) and SLR(1) test input: a + b * c + a "! example4 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: : [\s\t\r]+ {ignoreDelimiter} ; grammar spec: E : P ; P : 'a' ; P : '(' A ';' A ')' ; P : '(' V ',' V ')' ; V : 'a' ; A : 'a' ; status: LALR(1) test input: (a ; a) "! example5 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: (none) grammar spec: S : 'a' B 'b' ; S : 'a' D 'a' ; S : 'b' B 'a' ; S : 'b' D 'b' ; B : A ; A : 'a' ; D : 'a' ; status: LR(1) test input: aaa "! example6 "Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: : [\s\t\r]+ {ignoreDelimiter} ; grammar spec: S : E ; E : E '+' E | E '*' E | 'a' ; status: not LL(1) and not LR(1) test input: a + a * a "! example7 "This grammar demonstrates the need of simple scanner backup. Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: (none) grammar spec: S : E S | ; E : 'a' | 'abc' | 'bd' ; status: LL(1) and SLR(1) test input: abd "! example8 "This grammar demonstrates the need of two-token scanner lookahead. Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: (none) grammar spec: S : E S | ; E : 'a' | 'ab' | 'abc' | 'bd' ; status: LL(1) and SLR(1) test input: abd "! example9 "This demonstrates how to build flat non-empty lists. Evaluate the following expression and then test the grammar." "TranslatorGeneratorView open" "token spec: (none) grammar spec: E : E P {liftLeftChild} | P {OrderedChildren} ; P : 'a' {A} | 'b' {B} | 'c' {C} ; status: LL(1) with transformations (translations are still not handled) and SLR(1) test input: abc "! ! !TranslatorGenerator class methodsFor: 'instance creation'! new ^super new init! ! !TranslatorGenerator class methodsFor: 'class initialization'! initialize "TranslatorGenerator initialize" self grammarSpecParser: GrammarSpecParser new. self tokenSpecParser: TokenSpecParser new. self initializeTokenSpecMetaChars.! initializeTokenSpecMetaChars "These characters are special to the TokenSpecParser and must be escaped." | chars | chars := Set new. chars addAll: #($: $; $| $* $+ $? $( $) $[ $] $~ $- $< $> ${ $} $\ ). chars add: Character space; add: Character tab; add: Character cr. TokenSpecMetaChars := chars! ! !TranslatorGenerator class methodsFor: 'state accessing'! grammarSpecParser ^grammarSpecParser! grammarSpecParser: argument grammarSpecParser := argument! tokenSpecParser ^tokenSpecParser! tokenSpecParser: argument tokenSpecParser := argument! ! ApplicationModel subclass: #TranslatorGeneratorView instanceVariableNames: 'grammarMode parserMode generator ' classVariableNames: '' poolDictionaries: '' category: 'T-gen-Interface'! TranslatorGeneratorView comment: '================================================= Copyright (c) 1994 by Justin O. Graver. All rights reserved (with exceptions). For complete information evaluate "Object tgenCopyright." ================================================= I am the VisualWorks-style view (application model) for a TranslatorGenerator. See TranslatorGenerator class comment for a description of my subviews. Instance Variables: grammarMode - for the generator''s grammarMode. parserMode - for the generator''s parserMode. generator - domain model.'! !TranslatorGeneratorView methodsFor: 'aspects'! grammarMode ^grammarMode isNil ifTrue: [grammarMode := (AspectAdaptor subject: self generator) forAspect: #grammarMode] ifFalse: [grammarMode]! grammarSpec | adaptor | adaptor := AspectAdaptor subject: generator. adaptor forAspect: #grammarSpecification. adaptor subjectSendsUpdates: true. ^adaptor! parserMode ^parserMode isNil ifTrue: [parserMode := (AspectAdaptor subject: self generator) forAspect: #parserMode] ifFalse: [parserMode]! test | adaptor | adaptor := AspectAdaptor subject: generator. adaptor forAspect: #inputText. adaptor subjectSendsUpdates: true. ^adaptor! tokenSpec | adaptor | adaptor := AspectAdaptor subject: generator. adaptor forAspect: #tokenSpecification. adaptor subjectSendsUpdates: true. ^adaptor! ! !TranslatorGeneratorView methodsFor: 'custom views'! statusView | tcv | tcv := TextCollectorView new model: self generator statusTextBuffer. tcv controller: TextEditorController new. tcv controller menuHolder: (self class statusMenu) asValue. tcv controller performer: self. tcv controller keyboardProcessor: builder keyboardProcessor. ^tcv! ! !TranslatorGeneratorView methodsFor: 'initialize-release'! initialize self generator: TranslatorGenerator new! ! !TranslatorGeneratorView methodsFor: 'state accessing'! generator ^generator! generator: argument generator := argument! ! !TranslatorGeneratorView methodsFor: 'interface opening'! postBuildWith: aBuilder | controller | super postBuildWith: aBuilder. controller := (aBuilder componentAt: #tokenSpecView) widget controller. generator tokenSpecController: controller. controller autoAccept: false. controller := (aBuilder componentAt: #grammarSpecView) widget controller. controller autoAccept: false. controller := (aBuilder componentAt: #testView) widget controller. controller autoAccept: false! ! !TranslatorGeneratorView methodsFor: 'accepting'! acceptGrammarSpec: aText from: aController generator acceptGrammarSpec: aText from: aController! acceptInputText: aText from: aController generator acceptInputText: aText from: aController! ! !TranslatorGeneratorView methodsFor: 'actions'! defineScannerClass "Prompt the user for the name of a new scanner class. An instance of this class will be installed in each new parser built." | scannerName newScannerClass | scannerName := Dialog request: 'Type the name of the preferred scanner class.' initialAnswer: 'FSABasedScanner'. newScannerClass := Smalltalk at: scannerName asSymbol ifAbsent: [^generator showCR: 'No class named ' , scannerName , '.']. newScannerClass isBehavior ifFalse: [^generator showCR: scannerName , ' is not a class name.']. generator scannerClass: newScannerClass. generator showCR: 'Rebuild scanner and parser.'. generator resetParserAndFlags. "Force generation of new scanner, even is spec has not changed." generator oldScannerSpec: nil! defineTreeBuilderClass "Prompt the user for the name of a new parse tree builder class. An instance of this class will be installed in each new parser built." | builderName builderClass | builderName := Dialog request: 'Type the name of the new parse tree builder class.' initialAnswer: 'AbstractSyntaxTreeBuilder'. builderClass := Smalltalk at: builderName asSymbol ifAbsent: [^generator showCR: 'No class named ' , builderName , '.']. builderClass isBehavior ifFalse: [^generator showCR: builderName , ' is not a class name.']. generator treeBuilderClass: builderClass. generator parser notNil ifTrue: [generator parser treeBuilder: builderClass new. generator showCR: 'New parse tree builder installed in current parser.']! inspectGrammar generator transformedGrammar isNil ifTrue: [generator grammar inspect] ifFalse: [generator transformedGrammar inspect]! inspectParser generator parser isNil ifTrue: [generator showCR: 'No parser to inspect.'] ifFalse: [generator parser inspect]! inspectResult generator parserResult inspect! installScannerAndParserClasses | baseName category | (baseName := Dialog request: 'Type in a base name for the new scanner and parser classes, e.g. if you typed ''Gork'' the classes created would be named GorkScanner and GorkParser' initialAnswer: 'Gork') isEmpty ifFalse: [(category := Dialog request: 'Type in the category name for the new classes.' initialAnswer: 'category name') isEmpty ifFalse: [generator cr; show: 'Installing classes '; show: baseName; show: 'Scanner and '; show: baseName; show: 'Parser... '. generator parser fastParser createScannerParserClassesNamed: baseName category: category tokenSpec: generator tokenSpecification grammarSpec: generator grammarSpecification. generator showCR: 'done.']]! loadSpecs "load a token specification, a grammar specification, and a sample input. Use a single file name with three different extensions: *.tok, *.grm, and *.eg." | fileName | fileName := Dialog request: 'Enter base file name (standard extensions will be added):' initialAnswer: (generator specsFileName isNil ifTrue: ['Tgen'] ifFalse: [generator specsFileName]). fileName isEmpty ifTrue: [^self] ifFalse: ["cache" generator specsFileName: fileName]. generator loadSpecFrom: fileName.! saveSpecs "Save the token specification, the grammar specification, and the sample input. Use a single file name with three different extensions: *.tok, *.grm, and *.eg." | fileName | fileName := Dialog request: 'Enter base file name (standard extensions will be added):' initialAnswer: (generator specsFileName isNil ifTrue: ['Tgen'] ifFalse: [generator specsFileName]). fileName isEmpty ifTrue: [^self] ifFalse: ["cache" generator specsFileName: fileName]. Cursor write showWhile: [generator saveSpecTo: fileName]! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! TranslatorGeneratorView class instanceVariableNames: ''! !TranslatorGeneratorView class methodsFor: 'interface specs'! windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" ^#(#FullSpec #window: #(#WindowSpec #label: 'T-gen' #min: #(#Point 453 323 ) #bounds: #(#Rectangle 348 298 801 621 ) ) #component: #(#SpecCollection #collection: #( #(#MenuButtonSpec #layout: #(#LayoutFrame 1 0 -21 1 0 0.5 -1 1 ) #model: #grammarMode #menu: #grammarModeMenu ) #(#MenuButtonSpec #layout: #(#LayoutFrame 1 0.5 -21 1 -1 1 -1 1 ) #model: #parserMode #menu: #parserModeMenu ) #(#TextEditorSpec #layout: #(#LayoutFrame 0 0.00221729 0 0.00309597 0 0.498891 0 0.297214 ) #name: #tokenSpecView #model: #tokenSpec #menu: #tokenSpecMenu ) #(#TextEditorSpec #layout: #(#LayoutFrame 0 0.00443459 0 0.30031 0 0.498891 0 0.928793 ) #name: #grammarSpecView #model: #grammarSpec #menu: #grammarSpecMenu ) #(#ArbitraryComponentSpec #layout: #(#LayoutFrame 0 0.503326 0 0.00619195 0 0.997783 0 0.291022 ) #name: #statusView #flags: 9 #component: #statusView ) #(#TextEditorSpec #layout: #(#LayoutFrame 0 0.503326 0 0.30031 0 0.995565 0 0.931888 ) #name: #testView #model: #test #menu: #inputMenu ) ) ) )! ! !TranslatorGeneratorView class methodsFor: 'resources'! grammarModeMenu "UIMenuEditor new openOnClass: self andSelector: #grammarModeMenu" ^#(#Menu #( #(#MenuItem #label: 'LL(1)' ) #(#MenuItem #label: 'SLR(1), LALR(1), LR(1)' ) #(#MenuItem #label: 'don''t care' ) ) #(3 ) #(#LL #LR #default ) ) decodeAsLiteralArray! grammarSpecMenu "UIMenuEditor new openOnClass: self andSelector: #tokenSpecMenu" ^#(#Menu #( #(#MenuItem #rawLabel: '&find...' #value: #find ) #(#MenuItem #rawLabel: '&replace...' #value: #replace ) #(#MenuItem #rawLabel: '&undo' #value: #undo ) #(#MenuItem #rawLabel: '©' #value: #copySelection ) #(#MenuItem #rawLabel: 'cu&t' #value: #cut ) #(#MenuItem #rawLabel: '&paste' #value: #paste ) #(#MenuItem #rawLabel: '&accept' #value: #acceptGrammarSpec:from: ) #(#MenuItem #rawLabel: 'cancel' #value: #cancelText ) ) #(2 1 3 2 ) nil ) decodeAsLiteralArray! inputMenu "UIMenuEditor new openOnClass: self andSelector: #tokenSpecMenu" ^#(#Menu #( #(#MenuItem #rawLabel: '&find...' #value: #find ) #(#MenuItem #rawLabel: '&replace...' #value: #replace ) #(#MenuItem #rawLabel: '&undo' #value: #undo ) #(#MenuItem #rawLabel: '©' #value: #copySelection ) #(#MenuItem #rawLabel: 'cu&t' #value: #cut ) #(#MenuItem #rawLabel: '&paste' #value: #paste ) #(#MenuItem #rawLabel: '&accept' #value: #acceptInputText:from:) #(#MenuItem #rawLabel: 'cancel' #value: #cancelText ) ) #(2 1 3 2 ) nil ) decodeAsLiteralArray! parserModeMenu "UIMenuEditor new openOnClass: self andSelector: #parserModeMenu" ^#(#Menu #( #(#MenuItem #label: 'derivation tree' ) #(#MenuItem #label: 'trace' ) #(#MenuItem #label: 'sham AST' ) #(#MenuItem #label: 'AST' ) ) #(4 ) #(#default #Trace #shamAST #AST ) ) decodeAsLiteralArray! statusMenu "MenuEditor new openOnClass: self andSelector: #statusMenu" ^#(#Menu #( #(#MenuItem #rawLabel: 'result' #value: #inspectResult ) #(#MenuItem #rawLabel: 'builder' #value: #defineTreeBuilderClass ) #(#MenuItem #rawLabel: 'grammar' #value: #inspectGrammar ) #(#MenuItem #rawLabel: 'parser' #value: #inspectParser ) #(#MenuItem #rawLabel: 'scanner' #value: #defineScannerClass ) #(#MenuItem #rawLabel: 'install' #value: #installScannerAndParserClasses ) #(#MenuItem #rawLabel: 'save specs' #value: #saveSpecs ) #(#MenuItem #rawLabel: 'load specs' #value: #loadSpecs ) ) #(5 1 2 ) nil ) decodeAsLiteralArray! tokenSpecMenu "UIMenuEditor new openOnClass: self andSelector: #tokenSpecMenu" ^#(#Menu #( #(#MenuItem #rawLabel: '&find...' #value: #find ) #(#MenuItem #rawLabel: '&replace...' #value: #replace ) #(#MenuItem #rawLabel: '&undo' #value: #undo ) #(#MenuItem #rawLabel: '©' #value: #copySelection ) #(#MenuItem #rawLabel: 'cu&t' #value: #cut ) #(#MenuItem #rawLabel: '&paste' #value: #paste ) #(#MenuItem #rawLabel: '&accept' #value: #accept) #(#MenuItem #rawLabel: 'cancel' #value: #cancelText ) ) #(2 1 3 2 ) nil ) decodeAsLiteralArray! ! OptimizedLR1Parser subclass: #TokenSpecParser instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'T-gen-Interface'! TokenSpecParser comment: '================================================= Copyright (c) 1992 by Justin O. Graver. All rights reserved (with exceptions). For complete information evaluate "Object tgenCopyright." ================================================= I am a parser for T-gen token specifications.'! !TokenSpecParser methodsFor: 'private'! scannerClass ^TokenSpecScanner! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! TokenSpecParser class instanceVariableNames: ''! !TokenSpecParser class methodsFor: 'class initialization'! initialize "TokenSpecParser initialize" " spec : rule spec {liftRightChild} ; spec : {TokenSpecNode} ; rule : type ':' regExpr directive ';' {TokenSpecRuleNode} ; type : {TokenClassNode} ; directive : {DirectiveNode} ; directive : {nil} ; regExpr : catExpr '|' regExpr {liftRightChild} ; regExpr : catExpr {AlternationNode} ; catExpr : expr catExpr {liftRightChild} ; catExpr : expr {ConcatenationNode} ; expr : baseExpr '*' {StarClosureNode} ; expr : baseExpr '+' {PlusClosureNode} ; expr : baseExpr '?' {OptionalNode} ; expr : baseExpr ; baseExpr : atom ; baseExpr : '(' regExpr ')' ; baseExpr : '[' atomList ']' {AlternationRangeNode} ; baseExpr : '~' '[' atomList ']' {ComplementedAlternationRangeNode} ; atomList : listElmt atomList {liftRightChild} ; atomList : listElmt {OrderedChildren} ; listElmt : atom ; listElmt : atom '-' atom {CharRangeNode} ; atom : {DecimalCharNode} ; atom : {OctalCharNode} ; atom : {HexadecimalCharNode} ; atom : {EscapedCharNode} ; atom : {CharacterNode} ; " | table prodTable | prodTable := #( #expr #listElmt '[' $ #atomList ')' '' '(' #regExpr ';' #atom #directive ':' '' '~' #type #baseExpr '|' '-' '' '' ']' '' '' '+' '?' '' #catExpr #spec #rule '*' 'liftRightChild' 'HexadecimalCharNode' 'EscapedCharNode' 'StarClosureNode' 'ConcatenationNode' 'TokenSpecNode' 'OptionalNode' 'OrderedChildren' 'ComplementedAlternationRangeNode' 'nil' 'TokenClassNode' 'AlternationRangeNode' 'CharacterNode' 'CharRangeNode' 'PlusClosureNode' 'TokenSpecRuleNode' 'DecimalCharNode' 'DirectiveNode' 'AlternationNode' 'OctalCharNode' ). self tokenTypeTable: (prodTable copyFrom: 1 to: 31). table := #( #( nil nil nil #(29 #()37) nil nil nil nil nil nil nil nil nil nil nil 2 nil nil nil nil 39 nil nil nil nil nil nil nil 41 38 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil 3 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( 29 nil 4 nil nil nil 13 22 17 nil 21 nil nil 7 30 nil 25 nil nil nil nil nil 9 12 nil nil 8 35 nil nil nil ) #( nil 10 nil nil 5 nil 13 nil nil nil 14 nil nil 7 nil nil nil nil nil nil nil nil 9 12 nil nil 8 nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 6 nil nil nil nil nil nil nil nil nil ) #( nil nil #(17 #(3 5 22 )43) nil nil #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) nil #(17 #(3 5 22 )43) nil nil nil #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) nil nil #(17 #(3 5 22 )43) nil #(17 #(3 5 22 )43) nil nil #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) #(17 #(3 5 22 )43) nil nil nil #(17 #(3 5 22 )43) ) #( nil nil #(11 #(14 )44) nil nil #(11 #(14 )44) #(11 #(14 )44) #(11 #(14 )44) nil #(11 #(14 )44) nil nil nil #(11 #(14 )44) #(11 #(14 )44) nil nil #(11 #(14 )44) #(11 #(14 )44) #(11 #(14 )44) nil #(11 #(14 )44) #(11 #(14 )44) #(11 #(14 )44) #(11 #(14 )44) #(11 #(14 )44) #(11 #(14 )44) nil nil nil #(11 #(14 )44) ) #( nil nil #(11 #(27 )33) nil nil #(11 #(27 )33) #(11 #(27 )33) #(11 #(27 )33) nil #(11 #(27 )33) nil nil nil #(11 #(27 )33) #(11 #(27 )33) nil nil #(11 #(27 )33) #(11 #(27 )33) #(11 #(27 )33) nil #(11 #(27 )33) #(11 #(27 )33) #(11 #(27 )33) #(11 #(27 )33) #(11 #(27 )33) #(11 #(27 )33) nil nil nil #(11 #(27 )33) ) #( nil nil #(11 #(23 )48) nil nil #(11 #(23 )48) #(11 #(23 )48) #(11 #(23 )48) nil #(11 #(23 )48) nil nil nil #(11 #(23 )48) #(11 #(23 )48) nil nil #(11 #(23 )48) #(11 #(23 )48) #(11 #(23 )48) nil #(11 #(23 )48) #(11 #(23 )48) #(11 #(23 )48) #(11 #(23 )48) #(11 #(23 )48) #(11 #(23 )48) nil nil nil #(11 #(23 )48) ) #( nil 10 nil nil 11 nil 13 nil nil nil 14 nil nil 7 nil nil nil nil nil nil nil #(5 #(2 )39) 9 12 nil nil 8 nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil #(5 #(2 5 )32) nil nil nil nil nil nil nil nil nil ) #( nil nil #(11 #(24 )51) nil nil #(11 #(24 )51) #(11 #(24 )51) #(11 #(24 )51) nil #(11 #(24 )51) nil nil nil #(11 #(24 )51) #(11 #(24 )51) nil nil #(11 #(24 )51) #(11 #(24 )51) #(11 #(24 )51) nil #(11 #(24 )51) #(11 #(24 )51) #(11 #(24 )51) #(11 #(24 )51) #(11 #(24 )51) #(11 #(24 )51) nil nil nil #(11 #(24 )51) ) #( nil nil #(11 #(7 )34) nil nil #(11 #(7 )34) #(11 #(7 )34) #(11 #(7 )34) nil #(11 #(7 )34) nil nil nil #(11 #(7 )34) #(11 #(7 )34) nil nil #(11 #(7 )34) #(11 #(7 )34) #(11 #(7 )34) nil #(11 #(7 )34) #(11 #(7 )34) #(11 #(7 )34) #(11 #(7 )34) #(11 #(7 )34) #(11 #(7 )34) nil nil nil #(11 #(7 )34) ) #( nil nil nil nil nil nil #(2 #(11 )) nil nil nil nil nil nil #(2 #(11 )) nil nil nil nil 15 nil nil #(2 #(11 )) #(2 #(11 )) #(2 #(11 )) nil nil #(2 #(11 )) nil nil nil nil ) #( nil nil nil nil nil nil 13 nil nil nil 16 nil nil 7 nil nil nil nil nil nil nil nil 9 12 nil nil 8 nil nil nil nil ) #( nil nil nil nil nil nil #(2 #(11 19 11 )45) nil nil nil nil nil nil #(2 #(11 19 11 )45) nil nil nil nil nil nil nil #(2 #(11 19 11 )45) #(2 #(11 19 11 )45) #(2 #(11 19 11 )45) nil nil #(2 #(11 19 11 )45) nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil #(12 #()41) nil 19 nil nil nil nil nil nil nil 18 nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil #(12 #(20 )49) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil 20 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil #(30 #(16 13 9 12 10 )47) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil #(30 #(16 13 9 12 10 )47) nil nil nil nil nil nil nil nil nil nil ) #( nil nil #(17 #(11 )) nil nil #(17 #(11 )) #(17 #(11 )) #(17 #(11 )) nil #(17 #(11 )) nil nil nil #(17 #(11 )) #(17 #(11 )) nil nil #(17 #(11 )) nil #(17 #(11 )) nil nil #(17 #(11 )) #(17 #(11 )) #(17 #(11 )) #(17 #(11 )) #(17 #(11 )) nil nil nil #(17 #(11 )) ) #( 29 nil 4 nil nil nil 13 22 23 nil 21 nil nil 7 30 nil 25 nil nil nil nil nil 9 12 nil nil 8 35 nil nil nil ) #( nil nil nil nil nil 24 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil #(17 #(8 9 6 )) nil nil #(17 #(8 9 6 )) #(17 #(8 9 6 )) #(17 #(8 9 6 )) nil #(17 #(8 9 6 )) nil nil nil #(17 #(8 9 6 )) #(17 #(8 9 6 )) nil nil #(17 #(8 9 6 )) nil #(17 #(8 9 6 )) nil nil #(17 #(8 9 6 )) #(17 #(8 9 6 )) #(17 #(8 9 6 )) #(17 #(8 9 6 )) #(17 #(8 9 6 )) nil nil nil #(17 #(8 9 6 )) ) #( nil nil #(1 #(17 )) nil nil #(1 #(17 )) #(1 #(17 )) #(1 #(17 )) nil #(1 #(17 )) nil nil nil #(1 #(17 )) #(1 #(17 )) nil nil #(1 #(17 )) nil #(1 #(17 )) nil nil #(1 #(17 )) #(1 #(17 )) 28 27 #(1 #(17 )) nil nil nil 26 ) #( nil nil #(1 #(17 31 )35) nil nil #(1 #(17 31 )35) #(1 #(17 31 )35) #(1 #(17 31 )35) nil #(1 #(17 31 )35) nil nil nil #(1 #(17 31 )35) #(1 #(17 31 )35) nil nil #(1 #(17 31 )35) nil #(1 #(17 31 )35) nil nil #(1 #(17 31 )35) #(1 #(17 31 )35) nil nil #(1 #(17 31 )35) nil nil nil nil ) #( nil nil #(1 #(17 26 )38) nil nil #(1 #(17 26 )38) #(1 #(17 26 )38) #(1 #(17 26 )38) nil #(1 #(17 26 )38) nil nil nil #(1 #(17 26 )38) #(1 #(17 26 )38) nil nil #(1 #(17 26 )38) nil #(1 #(17 26 )38) nil nil #(1 #(17 26 )38) #(1 #(17 26 )38) nil nil #(1 #(17 26 )38) nil nil nil nil ) #( nil nil #(1 #(17 25 )46) nil nil #(1 #(17 25 )46) #(1 #(17 25 )46) #(1 #(17 25 )46) nil #(1 #(17 25 )46) nil nil nil #(1 #(17 25 )46) #(1 #(17 25 )46) nil nil #(1 #(17 25 )46) nil #(1 #(17 25 )46) nil nil #(1 #(17 25 )46) #(1 #(17 25 )46) nil nil #(1 #(17 25 )46) nil nil nil nil ) #( 29 nil 4 nil nil #(28 #(1 )36) 13 22 nil #(28 #(1 )36) 21 nil nil 7 30 nil 25 #(28 #(1 )36) nil #(28 #(1 )36) nil nil 9 12 nil nil 8 34 nil nil nil ) #( nil nil 31 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil 10 nil nil 32 nil 13 nil nil nil 14 nil nil 7 nil nil nil nil nil nil nil nil 9 12 nil nil 8 nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 33 nil nil nil nil nil nil nil nil nil ) #( nil nil #(17 #(15 3 5 22 )40) nil nil #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) nil #(17 #(15 3 5 22 )40) nil nil nil #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) nil nil #(17 #(15 3 5 22 )40) nil #(17 #(15 3 5 22 )40) nil nil #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) #(17 #(15 3 5 22 )40) nil nil nil #(17 #(15 3 5 22 )40) ) #( nil nil nil nil nil #(28 #(1 28 )32) nil nil nil #(28 #(1 28 )32) nil nil nil nil nil nil nil #(28 #(1 28 )32) nil #(28 #(1 28 )32) nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil #(9 #(28 )50) nil nil nil #(9 #(28 )50) nil nil nil nil nil nil nil 36 nil #(9 #(28 )50) nil nil nil nil nil nil nil nil nil nil nil ) #( 29 nil 4 nil nil nil 13 22 37 nil 21 nil nil 7 30 nil 25 nil nil nil nil nil 9 12 nil nil 8 35 nil nil nil ) #( nil nil nil nil nil #(9 #(28 18 9 )32) nil nil nil #(9 #(28 18 9 )32) nil nil nil nil nil nil nil nil nil #(9 #(28 18 9 )32) nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil #(29 #()37) nil nil nil nil nil nil nil nil nil nil nil 2 nil nil nil nil 39 nil nil nil nil nil nil nil 40 38 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil #(16 #(21 )42) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil #(29 #(30 29 )32) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil 42 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) ). self constructParseTable: table with: prodTable. self finalState: 42! ! OptimizedScanner subclass: #GrammarSpecScanner instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'T-gen-Interface'! GrammarSpecScanner comment: '================================================= Copyright (c) 1992 by Justin O. Graver. All rights reserved (with exceptions). For complete information evaluate "Object tgenCopyright." ================================================= I am a scanner for T-gen grammar specifications.'! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! GrammarSpecScanner class instanceVariableNames: ''! !GrammarSpecScanner class methodsFor: 'class initialization'! initialize "GrammarSpecScanner initialize" " : [a-zA-Z_][a-zA-Z_0-9]* ; : ([a-zA-Z_][a-zA-Z_0-9]*\:)+ ; : '(~['] | '')+' {compactDoubleApostrophes} ; : \<[a-zA-Z_][a-zA-Z_0-9]*\> ; : \""(~[\""]|\""\""|[\s\t\r])*\"" {ignoreComment} ; : [\s\t\r]+ {ignoreDelimiter} ;" | table | self fsa: #( #( nil nil nil nil nil nil nil nil 2 nil nil nil 2 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 2 nil 3 nil nil nil nil 5 9 9 9 9 nil nil nil nil nil nil nil nil nil nil nil nil nil nil 9 9 10 nil nil 9 nil 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 nil nil nil 9 13 nil 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 9 9 9 nil nil ) #( nil nil nil nil nil nil nil nil 2 nil nil nil 2 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 2 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil 3 nil nil nil 3 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 3 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 3 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 6 6 6 6 6 6 6 8 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 6 6 6 6 6 6 6 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 6 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 6 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 nil nil nil nil 11 nil 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 11 11 11 11 11 11 11 11 11 11 nil nil nil nil 12 nil nil 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 nil nil nil nil 11 nil 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 13 13 13 13 13 13 13 13 13 13 14 nil nil nil nil nil nil 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 nil nil nil nil 13 nil 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 nil nil nil nil 15 nil 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 15 15 15 15 15 15 15 15 15 15 14 nil nil nil nil nil nil 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 nil nil nil nil 15 nil 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 nil nil nil nil nil ) ). table := #( nil #( #( ) #( #('' #ignoreDelimiter) ) ) nil #( #( ) #( #('' #ignoreComment) ) ) nil nil #( #( ) #( #('' #compactDoubleApostrophes) ) ) nil #( #( '^' '+' ';' '*' ')' ':' '}' '(' '|' '{' '?' ) #( ) ) nil nil #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) nil ). self constructFinalStateTable: table! ! AbstractSyntaxTreeBuilder subclass: #GrammarTreeBuilder instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'T-gen-Interface'! !GrammarTreeBuilder methodsFor: 'tree building'! alternate: node1 with: node2 ^node1 alternateWith: node2! concatenate: node1 with: node2 ^node1 concatenateWith: node2! ! OptimizedScanner subclass: #TokenSpecScanner instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'T-gen-Interface'! TokenSpecScanner comment: '================================================= Copyright (c) 1992 by Justin O. Graver. All rights reserved (with exceptions). For complete information evaluate "Object tgenCopyright." ================================================= I am a scanner for T-gen token specifications.'! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! TokenSpecScanner class instanceVariableNames: ''! !TokenSpecScanner class methodsFor: 'class initialization'! initialize "TokenSpecScanner initialize" " : \<[a-zA-Z_][a-zA-Z_0-9]*\> ; : \{[a-zA-Z_][a-zA-Z_0-9]*\} ; : \\[0-9][0-9][0-9] ; : \\o[0-7][0-7][0-7] ; : \\x[0-9A-F][0-9A-F] ; : \\[!!-\~] ; : [!!-\~] ; : \""(~[\""]|\""\""|[\s\t\r])*\"" {ignoreComment} ; : [\s\t\r]+ {ignoreDelimiter} ; " | table | self fsa: #( #( nil nil nil nil nil nil nil nil 2 nil nil nil 2 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 7 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 10 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 22 3 3 3 nil ) #( nil nil nil nil nil nil nil nil 2 nil nil nil 2 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 2 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil 5 nil nil nil 5 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 5 5 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 nil ) #( nil nil nil nil nil nil nil nil 5 nil nil nil 5 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 5 5 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 5 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 nil nil nil nil 8 nil 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 8 8 8 8 8 8 8 8 8 8 nil nil nil nil 9 nil nil 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 nil nil nil nil 8 nil 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12 12 12 12 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 15 11 11 11 11 11 11 11 11 19 11 11 11 11 11 11 nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 13 13 13 13 13 13 13 13 13 13 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 14 14 14 14 14 14 14 14 14 14 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 16 16 16 16 16 16 16 16 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 17 17 17 17 17 17 17 17 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 18 18 18 18 18 18 18 18 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 20 20 20 20 20 20 20 20 20 20 nil nil nil nil nil nil nil 20 20 20 20 20 20 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 21 21 21 21 21 21 21 21 21 21 nil nil nil nil nil nil nil 21 21 21 21 21 21 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 nil nil nil nil 23 nil 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 23 23 23 23 23 23 23 23 23 23 nil nil nil nil nil nil nil 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 nil nil nil nil 23 nil 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 nil nil 24 nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) ). table := #( nil #( #( ) #( #('' #ignoreDelimiter) ) ) #( #( '+' ';' '*' '~' ')' '(' '[' '|' ':' ']' '?' '-' ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) nil #( #( ) #( #('' #ignoreComment) ) ) #( #( ) #( #('' nil) ) ) nil #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) nil #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) nil nil #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) nil #( #( ) #( #('' nil) ) ) #( #( ) #( #('' nil) ) ) nil #( #( ) #( #('' nil) ) ) ). self constructFinalStateTable: table! ! OptimizedLR1Parser subclass: #GrammarSpecParser instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'T-gen-Interface'! GrammarSpecParser comment: '================================================= Copyright (c) 1992 by Justin O. Graver. All rights reserved (with exceptions). For complete information evaluate "Object tgenCopyright." ================================================= I am a parser for T-gen grammar specifications.'! !GrammarSpecParser methodsFor: 'private'! scannerClass ^GrammarSpecScanner! treeBuilderClass ^GrammarTreeBuilder! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! GrammarSpecParser class instanceVariableNames: ''! !GrammarSpecParser class methodsFor: 'class initialization'! initialize "GrammarSpecParser initialize" " gram : rule gram {liftRightChild} ; gram : {GrammarNode} ; rule : nonterm ':' rightParts ';' {RRPGProductionNode} ; nonterm : {NonterminalNode} ; rightParts : regExpr '|' rightParts {alternate:with:} ; rightParts : regExpr ; regExpr : listExpr trans {RRPGRightHandSideNode} ; listExpr : listExpr '^' catExpr {ListNode} ; listExpr : catExpr ; catExpr : expr catExpr {concatenate:with:} ; catExpr : {EpsilonNode} ; expr : baseExpr '*' {StarClosureNode} ; expr : baseExpr '+' {PlusClosureNode} ; expr : baseExpr '?' {OptionalNode} ; expr : baseExpr ; baseExpr : term ; baseExpr : nonterm ; baseExpr : '(' subExpr ')' ; subExpr : listExpr '|' subExpr {alternate:with:} ; subExpr : listExpr ; trans : '{' transSym '}' ; trans : {nil} ; transSym : {TranslationNode} ; transSym : {TranslationNode} ; term : {TerminalNode } ; term : {TerminalNode} ; " | table prodTable | prodTable := #( #expr $ '' ')' #trans #listExpr '(' #regExpr ';' ':' #rightParts #transSym #term #gram '}' #baseExpr '|' '^' #nonterm #subExpr '' '{' #catExpr '?' '+' '' '' #rule '*' 'liftRightChild' 'StarClosureNode' 'OptionalNode' 'RRPGRightHandSideNode' 'RRPGProductionNode' 'nil' 'alternate:with:' 'TranslationNode' 'GrammarNode' 'concatenate:with:' 'PlusClosureNode' 'NonterminalNode' 'ListNode' 'TerminalNode' 'EpsilonNode' ). self tokenTypeTable: (prodTable copyFrom: 1 to: 29). table := #( #( nil #(14 #()38) 14 nil nil nil nil nil nil nil nil nil nil 2 nil nil nil nil 6 nil nil nil nil nil nil nil nil 4 nil ) #( nil 3 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil #(14 #()38) 14 nil nil nil nil nil nil nil nil nil nil 5 nil nil nil nil 6 nil nil nil nil nil nil nil nil 4 nil ) #( nil #(14 #(28 14 )30) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil 7 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( 8 nil 14 #(23 #()44) nil 31 12 28 #(23 #()44) nil 38 nil 9 nil nil 17 #(23 #()44) #(23 #()44) 10 nil 13 #(23 #()44) 24 nil nil nil 11 nil nil ) #( 8 nil 14 #(23 #()44) nil nil 12 nil #(23 #()44) nil nil nil 9 nil nil 17 #(23 #()44) #(23 #()44) 10 nil 13 #(23 #()44) 27 nil nil nil 11 nil nil ) #( nil nil #(16 #(13 )) #(16 #(13 )) nil nil #(16 #(13 )) nil #(16 #(13 )) nil nil nil nil nil nil nil #(16 #(13 )) #(16 #(13 )) nil nil #(16 #(13 )) #(16 #(13 )) nil #(16 #(13 )) #(16 #(13 )) nil #(16 #(13 )) nil #(16 #(13 )) ) #( nil nil #(16 #(19 )) #(16 #(19 )) nil nil #(16 #(19 )) nil #(16 #(19 )) nil nil nil nil nil nil nil #(16 #(19 )) #(16 #(19 )) nil nil #(16 #(19 )) #(16 #(19 )) nil #(16 #(19 )) #(16 #(19 )) nil #(16 #(19 )) nil #(16 #(19 )) ) #( nil nil #(13 #(27 )43) #(13 #(27 )43) nil nil #(13 #(27 )43) nil #(13 #(27 )43) nil nil nil nil nil nil nil #(13 #(27 )43) #(13 #(27 )43) nil nil #(13 #(27 )43) #(13 #(27 )43) nil #(13 #(27 )43) #(13 #(27 )43) nil #(13 #(27 )43) nil #(13 #(27 )43) ) #( 8 nil 14 #(23 #()44) nil 15 12 nil #(23 #()44) nil nil nil 9 nil nil 17 #(23 #()44) #(23 #()44) 10 25 13 #(23 #()44) 24 nil nil nil 11 nil nil ) #( nil nil #(13 #(21 )43) #(13 #(21 )43) nil nil #(13 #(21 )43) nil #(13 #(21 )43) nil nil nil nil nil nil nil #(13 #(21 )43) #(13 #(21 )43) nil nil #(13 #(21 )43) #(13 #(21 )43) nil #(13 #(21 )43) #(13 #(21 )43) nil #(13 #(21 )43) nil #(13 #(21 )43) ) #( nil nil #(19 #(3 )41) #(19 #(3 )41) nil nil #(19 #(3 )41) nil #(19 #(3 )41) #(19 #(3 )41) nil nil nil nil nil nil #(19 #(3 )41) #(19 #(3 )41) nil nil #(19 #(3 )41) #(19 #(3 )41) nil #(19 #(3 )41) #(19 #(3 )41) nil #(19 #(3 )41) nil #(19 #(3 )41) ) #( nil nil nil #(20 #(6 )) nil nil nil nil nil nil nil nil nil nil nil nil 22 16 nil nil nil nil nil nil nil nil nil nil nil ) #( 8 nil 14 #(23 #()44) nil nil 12 nil #(23 #()44) nil nil nil 9 nil nil 17 #(23 #()44) #(23 #()44) 10 nil 13 #(23 #()44) 21 nil nil nil 11 nil nil ) #( nil nil #(1 #(16 )) #(1 #(16 )) nil nil #(1 #(16 )) nil #(1 #(16 )) nil nil nil nil nil nil nil #(1 #(16 )) #(1 #(16 )) nil nil #(1 #(16 )) #(1 #(16 )) nil 19 20 nil #(1 #(16 )) nil 18 ) #( nil nil #(1 #(16 29 )31) #(1 #(16 29 )31) nil nil #(1 #(16 29 )31) nil #(1 #(16 29 )31) nil nil nil nil nil nil nil #(1 #(16 29 )31) #(1 #(16 29 )31) nil nil #(1 #(16 29 )31) #(1 #(16 29 )31) nil nil nil nil #(1 #(16 29 )31) nil nil ) #( nil nil #(1 #(16 24 )32) #(1 #(16 24 )32) nil nil #(1 #(16 24 )32) nil #(1 #(16 24 )32) nil nil nil nil nil nil nil #(1 #(16 24 )32) #(1 #(16 24 )32) nil nil #(1 #(16 24 )32) #(1 #(16 24 )32) nil nil nil nil #(1 #(16 24 )32) nil nil ) #( nil nil #(1 #(16 25 )40) #(1 #(16 25 )40) nil nil #(1 #(16 25 )40) nil #(1 #(16 25 )40) nil nil nil nil nil nil nil #(1 #(16 25 )40) #(1 #(16 25 )40) nil nil #(1 #(16 25 )40) #(1 #(16 25 )40) nil nil nil nil #(1 #(16 25 )40) nil nil ) #( nil nil nil #(6 #(6 18 23 )42) nil nil nil nil #(6 #(6 18 23 )42) nil nil nil nil nil nil nil #(6 #(6 18 23 )42) #(6 #(6 18 23 )42) nil nil nil #(6 #(6 18 23 )42) nil nil nil nil nil nil nil ) #( 8 nil 14 #(23 #()44) nil 15 12 nil #(23 #()44) nil nil nil 9 nil nil 17 #(23 #()44) #(23 #()44) 10 23 13 #(23 #()44) 24 nil nil nil 11 nil nil ) #( nil nil nil #(20 #(6 17 20 )36) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil #(6 #(23 )) nil nil nil nil #(6 #(23 )) nil nil nil nil nil nil nil #(6 #(23 )) #(6 #(23 )) nil nil nil #(6 #(23 )) nil nil nil nil nil nil nil ) #( nil nil nil 26 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil #(16 #(7 20 4 )) #(16 #(7 20 4 )) nil nil #(16 #(7 20 4 )) nil #(16 #(7 20 4 )) nil nil nil nil nil nil nil #(16 #(7 20 4 )) #(16 #(7 20 4 )) nil nil #(16 #(7 20 4 )) #(16 #(7 20 4 )) nil #(16 #(7 20 4 )) #(16 #(7 20 4 )) nil #(16 #(7 20 4 )) nil #(16 #(7 20 4 )) ) #( nil nil nil #(23 #(1 23 )39) nil nil nil nil #(23 #(1 23 )39) nil nil nil nil nil nil nil #(23 #(1 23 )39) #(23 #(1 23 )39) nil nil nil #(23 #(1 23 )39) nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil #(11 #(8 )) nil nil nil nil nil nil nil 29 nil nil nil nil nil nil nil nil nil nil nil nil ) #( 8 nil 14 #(23 #()44) nil 31 12 28 #(23 #()44) nil 30 nil 9 nil nil 17 #(23 #()44) #(23 #()44) 10 nil 13 #(23 #()44) 24 nil nil nil 11 nil nil ) #( nil nil nil nil nil nil nil nil #(11 #(8 17 11 )36) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil 37 nil nil nil #(5 #()35) nil nil nil nil nil nil nil #(5 #()35) 16 nil nil nil 32 nil nil nil nil nil nil nil ) #( nil nil 36 nil nil nil nil nil nil nil nil 34 nil nil nil nil nil nil nil nil nil nil nil nil nil 33 nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil #(12 #(26 )37) nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil 35 nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil #(5 #(22 12 15 )) nil nil nil nil nil nil nil #(5 #(22 12 15 )) nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil nil nil nil nil nil nil #(12 #(3 )37) nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil #(8 #(6 5 )33) nil nil nil nil nil nil nil #(8 #(6 5 )33) nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil nil nil nil nil nil nil nil 39 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) #( nil #(28 #(19 10 11 9 )34) #(28 #(19 10 11 9 )34) nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) ). self constructParseTable: table with: prodTable. self finalState: 3! !