--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SmaCC__SmaCCParserGenerator.st Thu Apr 10 09:11:12 2008 +0000
@@ -0,0 +1,1674 @@
+"{ Package: 'stx:goodies/smaCC' }"
+
+"{ NameSpace: SmaCC }"
+
+ApplicationModel subclass:#SmaCCParserGenerator
+ instanceVariableNames:'tabList parserClassNameHolder scannerClassNameHolder
+ conflictHolder scannerHolder parserHolder testHolder
+ generateDefinitionCommentsHolder generateSymbolCommentsHolder
+ generateItemSetCommentsHolder allowUnicodeHolder ignoreCaseHolder
+ editAcceptChannel loadScannerAndParserFromFileHolder
+ parserEditTextView scannerEditTextView parserDefinitionFileHolder
+ scannerDefinitionFileHolder tabSelectionHolder'
+ classVariableNames:'ShowPrecedenceConflicts'
+ poolDictionaries:''
+ category:'SmaCC-UI'
+!
+
+!SmaCCParserGenerator class methodsFor:'documentation'!
+
+examples
+"
+ openSmaCC
+ <menuItem: 'SmaCC Parser Generator'
+ nameKey: nil
+ menu: #(#menuBar #tools)
+ position: 30.00>
+
+ SmaCC.SmaCCParserGenerator open
+"
+! !
+
+!SmaCCParserGenerator class methodsFor:'initialization'!
+
+initialize
+ ShowPrecedenceConflicts := false.
+! !
+
+!SmaCCParserGenerator class methodsFor:'interface specs'!
+
+compileWindowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#compileWindowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#compileWindowSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: compileWindowSpec
+ window:
+ (WindowSpec
+ label: 'Compile Grammar Tab'
+ name: 'Compile Grammar Tab'
+ bounds: (Rectangle 0 0 696 468)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (VerticalPanelViewSpec
+ name: 'ContentPanel'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ horizontalLayout: fit
+ verticalLayout: top
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (FramedBoxSpec
+ label: 'Classes'
+ name: 'ClassesBox'
+ labelPosition: topLeft
+ translateLabel: true
+ component:
+ (SpecCollection
+ collection: (
+ (VerticalPanelViewSpec
+ name: 'ClassesBoxContent'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ horizontalLayout: fit
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ elementsChangeSize: true
+ component:
+ (SpecCollection
+ collection: (
+ (HorizontalPanelViewSpec
+ name: 'ClassesBoxContentScannerClass'
+ horizontalLayout: left
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (LabelSpec
+ label: 'Scanner class:'
+ name: 'ScannerClassLabel'
+ resizeForLabel: true
+ adjust: left
+ extent: (Point 110 26)
+ )
+ (InputFieldSpec
+ name: 'ScannerClassName'
+ model: scannerClassNameHolder
+ type: string
+ acceptOnLeave: true
+ acceptOnLostFocus: true
+ acceptOnPointerLeave: true
+ extent: (Point 300 26)
+ )
+ (ActionButtonSpec
+ label: 'Select'
+ name: 'ScannerClassFindButton'
+ model: findScannerClass
+ defaultable: true
+ extent: (Point 55 26)
+ )
+ )
+
+ )
+ extent: (Point 650 26)
+ )
+ (HorizontalPanelViewSpec
+ name: 'ClassesBoxContentParserClass'
+ horizontalLayout: left
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (LabelSpec
+ label: 'Parser class:'
+ name: 'ParserClassLabel'
+ adjust: left
+ extent: (Point 110 25)
+ )
+ (InputFieldSpec
+ name: 'ParserClassName'
+ model: parserClassNameHolder
+ type: string
+ acceptOnLeave: true
+ acceptOnLostFocus: true
+ acceptOnPointerLeave: true
+ extent: (Point 300 25)
+ )
+ (ActionButtonSpec
+ label: 'Select'
+ name: 'ParserClassFindButton'
+ model: findParserClass
+ defaultable: true
+ useDefaultExtent: true
+ )
+ )
+
+ )
+ extent: (Point 650 25)
+ )
+ )
+
+ )
+ )
+ )
+
+ )
+ extent: (Point 696 100)
+ )
+ (FramedBoxSpec
+ label: 'Options'
+ name: 'OptionsBox'
+ labelPosition: topLeft
+ translateLabel: true
+ component:
+ (SpecCollection
+ collection: (
+ (PanelViewSpec
+ name: 'OptionsPanel'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ horizontalLayout: fitSpace
+ verticalLayout: fitSpace
+ horizontalSpace: 3
+ verticalSpace: 3
+ ignoreInvisibleComponents: false
+ component:
+ (SpecCollection
+ collection: (
+ (CheckBoxSpec
+ label: 'Load scanner and parser from file'
+ name: 'loadScannerAndParserFromFiles'
+ model: loadScannerAndParserFromFileHolder
+ translateLabel: true
+ useDefaultExtent: true
+ )
+ (CheckBoxSpec
+ label: 'Generate definition comments'
+ name: generateDefinitionComments
+ model: generateDefinitionCommentsHolder
+ useDefaultExtent: true
+ )
+ (CheckBoxSpec
+ label: 'Generate symbol comments'
+ name: generateSymbolComments
+ model: generateSymbolCommentsHolder
+ useDefaultExtent: true
+ )
+ (CheckBoxSpec
+ label: 'Generate item set comments'
+ name: generateItemSetComments
+ model: generateItemSetCommentsHolder
+ useDefaultExtent: true
+ )
+ (CheckBoxSpec
+ label: 'Allow Unicode Characters'
+ name: allowUnicode
+ model: allowUnicodeHolder
+ useDefaultExtent: true
+ )
+ (CheckBoxSpec
+ label: 'Ignore Case'
+ name: ignoreCase
+ model: ignoreCaseHolder
+ useDefaultExtent: true
+ )
+ )
+
+ )
+ )
+ )
+
+ )
+ useDefaultExtent: true
+ )
+ (FramedBoxSpec
+ label: 'Files'
+ name: 'FileBox'
+ labelPosition: topLeft
+ translateLabel: true
+ component:
+ (SpecCollection
+ collection: (
+ (VerticalPanelViewSpec
+ name: 'FileBoxLabelPanel'
+ layout: (LayoutFrame 0 0 0 0 100 0 0 1)
+ horizontalLayout: fit
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (LabelSpec
+ label: 'Scanner:'
+ name: 'ScanneFileLabel'
+ translateLabel: true
+ adjust: right
+ extent: (Point 100 26)
+ )
+ (LabelSpec
+ label: 'Parser:'
+ name: 'ParserFileLabel'
+ translateLabel: true
+ adjust: right
+ extent: (Point 100 25)
+ )
+ )
+
+ )
+ )
+ (VerticalPanelViewSpec
+ name: 'FileBoxFilenameEditPanel'
+ layout: (LayoutFrame 100 0 0 0 -30 1 0 1)
+ horizontalLayout: fit
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (FilenameInputFieldSpec
+ name: 'ScannerFile'
+ enableChannel: loadScannerAndParserFromFileHolder
+ model: scannerDefinitionFileHolder
+ acceptOnPointerLeave: false
+ extent: (Point 520 26)
+ )
+ (FilenameInputFieldSpec
+ name: 'ParserFile'
+ enableChannel: loadScannerAndParserFromFileHolder
+ model: parserDefinitionFileHolder
+ acceptOnPointerLeave: false
+ extent: (Point 520 25)
+ )
+ )
+
+ )
+ )
+ (VerticalPanelViewSpec
+ name: 'FileBoxFilenameButtomPanel'
+ layout: (LayoutFrame -30 1 0 0 0 1 0 1)
+ horizontalLayout: fit
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (ArrowButtonSpec
+ name: 'ScannerFileSelector'
+ model: selectScannerFile
+ enableChannel: loadScannerAndParserFromFileHolder
+ isTriggerOnDown: true
+ actionValue: ''
+ direction: down
+ extent: (Point 30 26)
+ )
+ (ArrowButtonSpec
+ name: 'ParserFileSelection'
+ model: selectParserFile
+ enableChannel: loadScannerAndParserFromFileHolder
+ isTriggerOnDown: true
+ actionValue: ''
+ direction: down
+ extent: (Point 30 25)
+ )
+ )
+
+ )
+ )
+ )
+
+ )
+ extent: (Point 696 100)
+ )
+ )
+
+ )
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 14-02-2008 / 11:23:12 / janfrog"
+!
+
+generateButtonSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#generateButtonSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#generateButtonSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: generateButtonSpec
+ window:
+ (WindowSpec
+ label: 'GenerateButtonCanvas'
+ name: 'GenerateButtonCanvas'
+ min: (Point 10 10)
+ bounds: (Rectangle 0 0 585 58)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (ActionButtonSpec
+ label: 'Compile LALR(1)'
+ name: 'GenerateLARL'
+ layout: (LayoutFrame 0 0 0 0 0 0.5 0 1)
+ translateLabel: true
+ model: compileLALR1
+ )
+ (ActionButtonSpec
+ label: 'Compile LR(1)'
+ name: 'GenerateLR'
+ layout: (LayoutFrame 0 0.5 0 0 0 1 0 1)
+ translateLabel: true
+ model: compileLR1
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 18-03-2006 / 20:44:41 / janfrog"
+!
+
+messagesWindowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#messagesWindowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#messagesWindowSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: messagesWindowSpec
+ window:
+ (WindowSpec
+ label: 'Messages'
+ name: 'Messages'
+ min: (Point 10 10)
+ bounds: (Rectangle 0 0 300 300)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (TextEditorSpec
+ name: 'Messages'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ model: conflictHolder
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ miniScrollerHorizontal: true
+ tabRequiresControl: true
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 14-02-2008 / 10:49:02 / janfrog"
+!
+
+old_windowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#windowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#windowSpec
+ SmaCC::SmaCCParserGenerator open
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: windowSpec
+ window:
+ (WindowSpec
+ label: 'SmaCC Parser Generator'
+ name: 'SmaCC Parser Generator'
+ min: (Point 200 200)
+ bounds: (Rectangle 0 0 634 524)
+ menu: mainMenu
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (TabControlSpec
+ name: subcanvas
+ layout: (LayoutFrame 2 0 2 0 -2 1 -2 1)
+ model: tabList
+ labels: ()
+ )
+ )
+
+ )
+ )
+
+ "Created: / 11-05-2007 / 09:55:16 / janfrog"
+!
+
+parserWindowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#parserWindowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#parserWindowSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: parserWindowSpec
+ window:
+ (WindowSpec
+ label: 'Parser Definition'
+ name: 'Parser Definition'
+ bounds: (Rectangle 0 0 578 352)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (TextEditorSpec
+ name: 'Parser'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ model: parserHolder
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ miniScrollerHorizontal: true
+ acceptChannel: editAcceptChannel
+ tabRequiresControl: true
+ postBuildCallback: postBuildParserDefinitionView:
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 11-05-2007 / 12:30:42 / janfrog"
+!
+
+scannerWindowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#scannerWindowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#scannerWindowSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: scannerWindowSpec
+ window:
+ (WindowSpec
+ label: 'Scanner Definition'
+ name: 'Scanner Definition'
+ bounds: (Rectangle 0 0 200 200)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (TextEditorSpec
+ name: 'ScannerView'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ model: scannerHolder
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ miniScrollerHorizontal: true
+ acceptChannel: editAcceptChannel
+ tabRequiresControl: true
+ postBuildCallback: postBuildScannerDefinitionView:
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 11-05-2007 / 12:31:31 / janfrog"
+!
+
+testWindowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#testWindowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#testWindowSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: testWindowSpec
+ window:
+ (WindowSpec
+ label: 'Unlabeled Canvas'
+ name: 'Unlabeled Canvas'
+ bounds: (Rectangle 0 0 273 200)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (TextEditorSpec
+ name: text
+ layout: (LayoutFrame 0 0 0 0 0 1 -25 1)
+ model: testHolder
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ miniScrollerHorizontal: true
+ acceptChannel: editAcceptChannel
+ tabRequiresControl: true
+ )
+ (HorizontalPanelViewSpec
+ name: 'HorizontalPanel1'
+ layout: (LayoutFrame 0 0 -25 1 0 1 0 1)
+ horizontalLayout: fit
+ verticalLayout: fit
+ horizontalSpace: 3
+ verticalSpace: 3
+ component:
+ (SpecCollection
+ collection: (
+ (ActionButtonSpec
+ label: 'Parse'
+ name: parse
+ model: parse
+ extent: (Point 135 25)
+ )
+ (ActionButtonSpec
+ label: 'Parse and Inspect'
+ name: parseAndInspect
+ model: parseAndInspect
+ extent: (Point 135 25)
+ )
+ )
+
+ )
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 11-05-2007 / 21:38:24 / janfrog"
+!
+
+windowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#windowSpec
+ SmaCC::SmaCCParserGenerator new openInterface:#windowSpec
+ SmaCC::SmaCCParserGenerator open
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: windowSpec
+ window:
+ (WindowSpec
+ label: 'SmaCC Parser Generator'
+ name: 'SmaCC Parser Generator'
+ min: (Point 200 200)
+ bounds: (Rectangle 0 0 638 466)
+ menu: mainMenu
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (NoteBookViewSpec
+ name: 'Tools'
+ layout: (LayoutFrame 0 0 0 0 0 1 -25 1)
+ model: tabSelectionHolder
+ menu: tabList
+ useIndex: true
+ )
+ (UISubSpecification
+ name: 'CompileButtons'
+ layout: (LayoutFrame 0 0 -25 1 0 1 0 1)
+ minorKey: generateButtonSpec
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 14-02-2008 / 11:28:11 / janfrog"
+! !
+
+!SmaCCParserGenerator class methodsFor:'list specs'!
+
+tabList
+ "This resource specification was automatically generated
+ by the TabListEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the TabListEditor may not be able to read the specification."
+
+ "
+ TabListEditor new openOnClass: self andSelector:#tabList
+ "
+
+ <resource: #tabList>
+
+ ^ #(
+ (TabItem
+ label: 'Compile options'
+ createNewBuilder: false
+ minorKey: compileWindowSpec
+ )
+ (TabItem
+ label: 'Messages'
+ createNewBuilder: false
+ minorKey: messagesWindowSpec
+ )
+ (TabItem
+ label: 'Scanner definition'
+ createNewBuilder: false
+ minorKey: scannerWindowSpec
+ )
+ (TabItem
+ label: 'Parser definition'
+ createNewBuilder: false
+ minorKey: parserWindowSpec
+ )
+ (TabItem
+ label: 'Test workspace'
+ createNewBuilder: false
+ minorKey: testWindowSpec
+ )
+ )
+
+ collect:[:aTab| TabItem new fromLiteralArrayEncoding:aTab ]
+
+ "Modified: / 14-02-2008 / 11:02:24 / janfrog"
+! !
+
+!SmaCCParserGenerator class methodsFor:'menu specs'!
+
+mainMenu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:SmaCC::SmaCCParserGenerator andSelector:#mainMenu
+ (Menu new fromLiteralArrayEncoding:(SmaCC::SmaCCParserGenerator mainMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(Menu
+ (
+ (MenuItem
+ label: 'File'
+ translateLabel: true
+ submenu:
+ (Menu
+ (
+ (MenuItem
+ label: 'Load scanner definition'
+ itemValue: loadScannerDefinition
+ translateLabel: true
+ )
+ (MenuItem
+ label: 'Load parser definition'
+ itemValue: loadParserDefinition
+ translateLabel: true
+ )
+ (MenuItem
+ label: '-'
+ )
+ (MenuItem
+ label: 'Save scanner definition'
+ itemValue: saveScannerDefinition
+ translateLabel: true
+ )
+ (MenuItem
+ label: 'Save parser definition'
+ itemValue: saveParserDefinition
+ translateLabel: true
+ )
+ (MenuItem
+ label: '-'
+ )
+ (MenuItem
+ label: 'Exit'
+ itemValue: closeRequest
+ translateLabel: true
+ )
+ )
+ nil
+ nil
+ )
+ )
+ (MenuItem
+ label: 'Grammar'
+ translateLabel: true
+ submenu:
+ (Menu
+ (
+ (MenuItem
+ label: 'Compile LALR(1)'
+ itemValue: compileLALR1
+ translateLabel: true
+ )
+ (MenuItem
+ label: 'Compile LR(1)'
+ itemValue: compileLR1
+ translateLabel: true
+ )
+ )
+ nil
+ nil
+ )
+ )
+ (MenuItem
+ label: 'Help'
+ translateLabel: true
+ startGroup: right
+ submenu:
+ (Menu
+ (
+ (MenuItem
+ label: 'About this Application'
+ itemValue: openAboutThisApplication
+ translateLabel: true
+ )
+ )
+ nil
+ nil
+ )
+ )
+ )
+ nil
+ nil
+ )
+
+ "Modified: / 12-05-2007 / 21:08:14 / janfrog"
+! !
+
+!SmaCCParserGenerator methodsFor:'accessing'!
+
+loadScannerAndParserFromFile
+
+ ^self loadScannerAndParserFromFileHolder value
+
+ "Created: / 11-05-2007 / 12:53:44 / janfrog"
+!
+
+parserClass
+ ^self parserClassNameHolder value asQualifiedReference value
+!
+
+parserClassName
+ ^ self parserClassNameHolder value
+
+ "Created: / 11-05-2007 / 12:41:24 / janfrog"
+!
+
+parserDefinition
+ ^ self loadScannerAndParserFromFileHolder value
+ ifTrue:[ self parserDefinitionFile contents asString ]
+ ifFalse:[ self parserHolder value ]
+
+ "Created: / 18-03-2006 / 16:53:09 / janfrog"
+ "Modified: / 11-05-2007 / 12:52:36 / janfrog"
+!
+
+parserDefinition: aString
+ ^ self parserHolder value: aString
+
+ "Created: / 12-05-2007 / 20:48:49 / janfrog"
+!
+
+parserDefinitionFile
+ ^ self parserDefinitionFileHolder value asFilename
+
+ "Created: / 11-05-2007 / 12:52:36 / janfrog"
+!
+
+scannerClass
+ ^self scannerClassNameHolder value asQualifiedReference value
+
+ "Created: / 11-05-2007 / 12:59:45 / janfrog"
+!
+
+scannerClassName
+ ^ self scannerClassNameHolder value
+
+ "Created: / 11-05-2007 / 12:41:07 / janfrog"
+!
+
+scannerDefinition
+ ^ self loadScannerAndParserFromFileHolder value
+ ifTrue:[ self scannerDefinitionFile contents asString ]
+ ifFalse:[ self scannerHolder value ]
+
+ "Created: / 18-03-2006 / 16:53:09 / janfrog"
+ "Modified: / 11-05-2007 / 12:53:10 / janfrog"
+!
+
+scannerDefinition: aString
+ ^ self scannerHolder value: aString
+
+ "Created: / 12-05-2007 / 20:49:01 / janfrog"
+!
+
+scannerDefinitionFile
+ ^ self scannerDefinitionFileHolder value asFilename
+
+ "Created: / 11-05-2007 / 12:53:10 / janfrog"
+!
+
+tabSelection: index
+
+ self tabSelectionHolder value:2
+
+ "Created: / 14-02-2008 / 11:29:34 / janfrog"
+!
+
+tabSelectionToMessages
+
+ self tabSelection: 2
+
+ "Created: / 14-02-2008 / 11:30:33 / janfrog"
+!
+
+tabSelectionToOptions
+
+ self tabSelection: 1
+
+ "Created: / 14-02-2008 / 11:30:24 / janfrog"
+!
+
+tabSelectionToParserDefinition
+
+ self tabSelection: 4
+
+ "Created: / 14-02-2008 / 11:30:48 / janfrog"
+!
+
+tabSelectionToScannerDefinition
+
+ self tabSelection: 3
+
+ "Created: / 14-02-2008 / 11:30:43 / janfrog"
+! !
+
+!SmaCCParserGenerator methodsFor:'actions'!
+
+aboutThisApplicationText
+ "text for an about box for this application."
+
+ |rev clsRev msg|
+
+ rev := ''.
+
+ (clsRev := self class revision) notNil ifTrue: [rev := ' (rev: ', clsRev printString, ')'].
+
+ msg := 'SmaCC Compiler-Compiler framework.
+Written by John Brant and Don Roberts.\\
+Smalltalk/X UI by Jan Vrany.\\
+Available for VisualWorks, Dolphin, VisualAge and Smalltalk/X.
+\\' withCRs , self class name asBoldText, rev.
+ ^ msg
+
+ "Created: / 13-11-2001 / 12:28:36 / cg"
+ "Modified: / 11-05-2007 / 12:24:42 / janfrog"
+!
+
+compileLALR1
+ self compile: #LALR1
+
+ "Modified: / 11-05-2007 / 12:32:58 / janfrog"
+!
+
+compileLR1
+ self compile: #LR1
+!
+
+findParserClass
+ | class |
+ class := self choose: 'What class do you want to use?'
+ from: (SmaCCParser allSubclasses asSortedCollection: [:a :b | a name < b name]).
+ class isNil ifTrue: [^self].
+ self parserClassNameHolder value: class fullName.
+ (class class includesSelector: #parserDefinitionComment)
+ ifTrue:
+ [(self confirm: 'Do you wish to load the parser definition?')
+ ifTrue:
+ [self parserHolder value: (self
+ removeCommentedPartOf: (class class sourceCodeAt: #parserDefinitionComment))]]
+
+ "Modified: / 11-05-2007 / 12:27:46 / janfrog"
+!
+
+findScannerClass
+ | class |
+ class := self choose: 'What class do you want to use?'
+ from: (SmaCCScanner allSubclasses asSortedCollection: [:a :b | a name < b name]).
+ class isNil ifTrue: [^self].
+ self scannerClassNameHolder value: class fullName.
+ (class class includesSelector: #scannerDefinitionComment)
+ ifTrue:
+ [(self confirm: 'Do you wish to load the scanner definition?')
+ ifTrue:
+ [self scannerHolder value: (self
+ removeCommentedPartOf: (class class sourceCodeAt: #scannerDefinitionComment))]]
+!
+
+loadParserDefinition
+
+ | file stream |
+ (file := Dialog requestFileName:'Select parser definition file' default:'parser.txt')
+ isNilOrEmptyCollection ifTrue:[^self].
+
+ file asFilename exists ifFalse:
+ [(Dialog warn:'File does not exist.').^self].
+
+ stream := file asFilename readStream.
+ [ self parserDefinition: stream contents asString ]
+ ensure: [stream close]
+
+ "Created: / 12-05-2007 / 20:50:34 / janfrog"
+!
+
+loadScannerDefinition
+
+ | file stream |
+ (file := Dialog requestFileName:'Select scanner definition file' default:'parser.txt')
+ isNilOrEmptyCollection ifTrue:[^self].
+
+ file asFilename exists ifFalse:
+ [(Dialog warn:'File does not exist.').^self].
+
+ stream := file asFilename readStream.
+ [ self scannerDefinition: stream contents asString ]
+ ensure: [stream close]
+
+ "Created: / 12-05-2007 / 20:52:19 / janfrog"
+!
+
+openAboutThisAppliaction
+ Dialog
+ about:(resources string:self aboutThisApplicationText)
+ label:(resources string:self aboutThisApplicationLabel)
+ icon:self aboutImage
+!
+
+openDocumentation
+ "opens the documentation file of the Parsergenerator"
+
+ HTMLDocumentView openFullOnDocumentationFile:'../../../goodies/smaCC/documentation/Tutorial.html'
+!
+
+parse
+ self editAcceptChannel value:true.
+ self parseAndEvaluate: [:each | self warn: 'Parses without errors']
+!
+
+parseAndInspect
+ self editAcceptChannel value:true.
+ self parseAndEvaluate: [:each | each inspect]
+!
+
+saveParserDefinition
+
+ | file stream |
+ (file := Dialog requestFileName:'Save parser definition as' default:'parser.txt')
+ isNilOrEmptyCollection ifTrue:[^self].
+
+ file asFilename exists ifTrue:
+ [(Dialog confirm:'File exists. Overwrite?') ifFalse:[^self]].
+
+ stream := file asFilename writeStream.
+ [ stream nextPutAll:self parserDefinition ]
+ ensure: [stream close]
+
+ "Created: / 12-05-2007 / 20:46:15 / janfrog"
+!
+
+saveScannerDefinition
+
+ | file stream |
+ (file := Dialog requestFileName:'Save scanner definition as' default:'scanner.txt')
+ isNilOrEmptyCollection ifTrue:[^self].
+
+ file asFilename exists ifTrue:
+ [(Dialog confirm:'File exists. Overwrite?') ifFalse:[^self]].
+
+ stream := file asFilename writeStream.
+ [ stream nextPutAll:self scannerDefinition ]
+ ensure: [stream close]
+
+ "Created: / 12-05-2007 / 20:46:50 / janfrog"
+!
+
+selectParserFile
+ |fileName|
+
+ (fileName := Dialog
+ requestFileName:'Select parser definition file'
+ default:self guessParserDefinitionFilename
+ fromDirectory:self guessDefinitionFileDirectory)
+ isNilOrEmptyCollection
+ ifFalse:[ self parserDefinitionFileHolder value:fileName ]
+
+ "Modified: / 11-05-2007 / 13:16:01 / janfrog"
+!
+
+selectScannerFile
+ |fileName|
+
+ (fileName := Dialog
+ requestFileName:'Select parser definition file'
+ default:self guessScannerDefinitionFilename
+ fromDirectory:self guessDefinitionFileDirectory)
+
+ isNilOrEmptyCollection
+ ifFalse:[ self scannerDefinitionFileHolder value:fileName ]
+
+ "Modified: / 11-05-2007 / 13:16:16 / janfrog"
+! !
+
+!SmaCCParserGenerator methodsFor:'aspects'!
+
+allowUnicodeHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^allowUnicodeHolder isNil
+ ifTrue:
+ [allowUnicodeHolder := false asValue]
+ ifFalse:
+ [allowUnicodeHolder]
+!
+
+conflictHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ conflictHolder ifNil:
+ [conflictHolder := String new asValue.
+ conflictHolder onChangeEvaluate:
+ [self tabSelectionToMessages]].
+ ^conflictHolder
+
+ "Modified: / 14-02-2008 / 11:35:18 / janfrog"
+!
+
+editAcceptChannel
+ ^editAcceptChannel isNil
+ ifTrue:
+ [editAcceptChannel := TriggerValue new]
+ ifFalse:
+ [editAcceptChannel]
+!
+
+generateDefinitionCommentsHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^generateDefinitionCommentsHolder isNil
+ ifTrue:
+ [generateDefinitionCommentsHolder := false asValue]
+ ifFalse:
+ [generateDefinitionCommentsHolder]
+!
+
+generateItemSetCommentsHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^generateItemSetCommentsHolder isNil
+ ifTrue:
+ [generateItemSetCommentsHolder := false asValue]
+ ifFalse:
+ [generateItemSetCommentsHolder]
+!
+
+generateSymbolCommentsHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^generateSymbolCommentsHolder isNil
+ ifTrue:
+ [generateSymbolCommentsHolder := false asValue]
+ ifFalse:
+ [generateSymbolCommentsHolder]
+!
+
+ignoreCaseHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^ignoreCaseHolder isNil
+ ifTrue:
+ [ignoreCaseHolder := false asValue]
+ ifFalse:
+ [ignoreCaseHolder]
+!
+
+loadScannerAndParserFromFileHolder
+ "automatically generated by UIPainter ..."
+
+ "*** the code below creates a default model when invoked."
+ "*** (which may not be the one you wanted)"
+ "*** Please change as required and accept it in the browser."
+ "*** (and replace this comment by something more useful ;-)"
+
+ loadScannerAndParserFromFileHolder isNil ifTrue:[
+ loadScannerAndParserFromFileHolder := false asValue.
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/ loadScannerAndParserFromFileHolder addDependent:self.
+"/ loadScannerAndParserFromFileHolder onChangeSend:#loadScannerAndParserFromFileHolderChanged to:self.
+ ].
+ ^ loadScannerAndParserFromFileHolder.
+
+ "Created: / 18-03-2006 / 16:34:16 / janfrog"
+!
+
+parserClassNameHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^parserClassNameHolder isNil
+ ifTrue:
+ [parserClassNameHolder := nil asValue]
+ ifFalse:
+ [parserClassNameHolder]
+!
+
+parserDefinitionFileHolder
+ "automatically generated by UIPainter ..."
+ "*** the code below creates a default model when invoked."
+ "*** (which may not be the one you wanted)"
+ "*** Please change as required and accept it in the browser."
+ "*** (and replace this comment by something more useful ;-)"
+
+ parserDefinitionFileHolder isNil ifTrue:[
+ parserDefinitionFileHolder := ValueHolder new.
+
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/ parserFileHolder addDependent:self.
+"/ parserFileHolder onChangeSend:#parserFileHolderChanged to:self.
+ ].
+ ^ parserDefinitionFileHolder.
+
+ "Created: / 11-05-2007 / 12:47:09 / janfrog"
+!
+
+parserHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^parserHolder isNil
+ ifTrue:
+ [parserHolder := String new asValue]
+ ifFalse:
+ [parserHolder]
+!
+
+scannerClassNameHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^scannerClassNameHolder isNil
+ ifTrue:
+ [scannerClassNameHolder := nil asValue]
+ ifFalse:
+ [scannerClassNameHolder]
+!
+
+scannerDefinitionFileHolder
+ "automatically generated by UIPainter ..."
+ "*** the code below creates a default model when invoked."
+ "*** (which may not be the one you wanted)"
+ "*** Please change as required and accept it in the browser."
+ "*** (and replace this comment by something more useful ;-)"
+
+ scannerDefinitionFileHolder isNil ifTrue:[
+ scannerDefinitionFileHolder := ValueHolder new.
+
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/ scannerFileHolder addDependent:self.
+"/ scannerFileHolder onChangeSend:#scannerFileHolderChanged to:self.
+ ].
+ ^ scannerDefinitionFileHolder.
+
+ "Created: / 11-05-2007 / 12:47:20 / janfrog"
+!
+
+scannerHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^scannerHolder isNil
+ ifTrue:
+ [scannerHolder := String new asValue]
+ ifFalse:
+ [scannerHolder]
+!
+
+tabList
+ "Generated by the TabListEditor"
+
+ |list|
+
+ (list := builder bindingAt:#tabList) isNil ifTrue:[
+ builder aspectAt:#tabList put:(list := self class tabList).
+ ].
+ ^ list
+
+ "Created: / 11-05-2007 / 10:12:06 / janfrog"
+!
+
+tabSelectionHolder
+ "automatically generated by UIPainter ..."
+
+ "*** the code below creates a default model when invoked."
+ "*** (which may not be the one you wanted)"
+ "*** Please change as required and accept it in the browser."
+ "*** (and replace this comment by something more useful ;-)"
+
+ tabSelectionHolder isNil ifTrue:[
+ tabSelectionHolder := ValueHolder new.
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/ tabSelectionHolder addDependent:self.
+"/ tabSelectionHolder onChangeSend:#tabSelectionHolderChanged to:self.
+ ].
+ ^ tabSelectionHolder.
+
+ "Created: / 31-10-2007 / 08:08:31 / janfrog"
+!
+
+testHolder
+ "This method was generated by UIDefiner. Any edits made here
+ may be lost whenever methods are automatically defined. The
+ initialization provided below may have been preempted by an
+ initialize method."
+
+ ^testHolder isNil
+ ifTrue:
+ [testHolder := String new asValue]
+ ifFalse:
+ [testHolder]
+! !
+
+!SmaCCParserGenerator methodsFor:'hooks'!
+
+postBuildParserDefinitionView: aView
+
+ parserEditTextView := aView scrolledView
+
+ "Created: / 11-05-2007 / 12:32:11 / janfrog"
+!
+
+postBuildScannerDefinitionView: aView
+
+ scannerEditTextView := aView scrolledView
+
+ "Created: / 11-05-2007 / 12:32:26 / janfrog"
+! !
+
+!SmaCCParserGenerator methodsFor:'initialize-release'!
+
+initialize
+ super initialize.
+" (self tabList)
+ list: #('Scanner' 'Parser' 'Compile' 'Test') asList;
+ selectionIndex: 3.
+ self tabList selectionIndexHolder onChangeSend: #changedTab to: self."
+ self scannerClassNameHolder value: ''.
+ self parserClassNameHolder value: ''.
+ self scannerHolder value: ''.
+ self parserHolder value: ''.
+ self testHolder value: ''.
+ self generateDefinitionCommentsHolder value: true
+
+ "Modified: / 11-05-2007 / 10:11:09 / janfrog"
+! !
+
+!SmaCCParserGenerator methodsFor:'interface opening'!
+
+_postBuildWith: aBuilder
+ "builder == aBuilder ifFalse: [subcanvasBuilder := aBuilder].
+ (aBuilder componentAt: #text)
+ ifNotNil: [:each | each widget controller continuousAccept: true].
+ super postBuildWith: aBuilder"
+
+ "Created: / 11-05-2007 / 10:08:48 / janfrog"
+!
+
+_postOpenWith: aBuilder
+ "super postOpenWith: aBuilder.
+ compileWindowSpec"
+
+ "Created: / 11-05-2007 / 10:08:54 / janfrog"
+! !
+
+!SmaCCParserGenerator methodsFor:'private'!
+
+acceptDefinitions
+
+ scannerEditTextView accept.
+ parserEditTextView accept.
+
+ "Created: / 11-05-2007 / 12:34:48 / janfrog"
+!
+
+choose: title from: collection
+ ^Dialog
+ choose:title
+ fromList:collection
+ lines:collection size
+
+ "Created: / 11-05-2007 / 10:31:04 / janfrog"
+!
+
+compile:aSymbol
+ |grammar stream oldIgnoreCase oldCharacterSize parserCompiler showItemSets |
+
+ self acceptDefinitions.
+ (self scannerClassName isEmpty or:[ self parserClassName isEmpty ]) ifTrue:[
+ ^ self warn:'Both classes are not specified'
+ ].
+ self
+ withWaitCursorDo:[
+ self verifySyntax ifFalse:[
+ ^ self
+ ].
+ oldIgnoreCase := SmaCCGrammar ignoreCase.
+ oldCharacterSize := SmaCCGrammar maximumCharacterValue.
+ [
+ SmaCCGrammar
+ ignoreCase:self ignoreCaseHolder value;
+ maximumCharacterValue:(self allowUnicodeHolder value
+ ifTrue:[ (2 raisedTo:16) - 1 ]
+ ifFalse:[ 255 ]).
+ parserCompiler := SmaCCGrammarCompiler new.
+ parserCompiler
+ buildScanner:self scannerDefinition andParser:self parserDefinition;
+ scannerClass:self scannerClassName;
+ parserClass:self parserClassName.
+ grammar := parserCompiler grammar.
+ grammar type:aSymbol.
+ stream := WriteStream on:Text new.
+ showItemSets := false.
+ [
+ parserCompiler createChanges.
+ self generateDefinitionCommentsHolder value ifTrue:[
+ parserCompiler compileDefinitionComments
+ ].
+ self generateSymbolCommentsHolder value ifTrue:[
+ parserCompiler compileSymbolComment
+ ].
+ self generateItemSetCommentsHolder value ifTrue:[
+ parserCompiler compileItemSetsComment
+ ].
+ parserCompiler compileChanges
+ ] on:SmaCCCompilationNotification
+ do:[:ex |
+ showItemSets := true.
+ (ShowPrecedenceConflicts or:[ ('*precedence*' match:ex messageText) not ]) ifTrue:[
+ stream
+ nextPutAll:'-------------------------\' withCRs asText
+ , ex messageText asText allBold;
+ cr;
+ cr;
+ nextPutAll:ex parameter;
+ cr
+ ].
+ ex pass
+ ].
+ showItemSets ifTrue:[
+ stream cr; nextPutAll:'Item sets' asText allBold; cr; cr.
+ parserCompiler itemSets keysAndValuesDo:
+ [:itemSetNumber :itemSet|
+ itemSet id: itemSetNumber.
+ "/stream nextPutAll: itemSetNumber printString asText allBold.
+ stream nextPut:$:.
+ stream cr.
+ itemSet printOn: stream.
+ stream cr; cr].
+ ].
+ self conflictHolder value:stream contents.
+ ] ensure:[
+ SmaCCGrammar
+ ignoreCase:oldIgnoreCase;
+ maximumCharacterValue:oldCharacterSize
+ ]
+ ]
+
+ "Modified: / 14-02-2008 / 13:30:27 / janfrog"
+!
+
+defaultDefinitionFileDirectory
+
+ ^Filename homeDirectory
+
+ "Created: / 11-05-2007 / 13:02:14 / janfrog"
+!
+
+displayError: aString at: position
+ |w|
+
+ w := self textWidget.
+ w notNil ifTrue:[
+ w takeKeyboardFocus.
+ w widget controller insertAndSelect: aString , ' ->' at: position]
+!
+
+guessDefinitionFileDirectory
+
+ | defDir |
+
+ self scannerClass
+ ifNil:[^self defaultDefinitionFileDirectory].
+ self parserClass
+ ifNil:[^self defaultDefinitionFileDirectory].
+ self scannerClass package ~= self parserClass package
+ ifTrue:[^self defaultDefinitionFileDirectory].
+
+ defDir := Smalltalk getPackageDirectoryForPackage: self scannerClass package.
+ defDir ifNil:[^self defaultDefinitionFileDirectory].
+ (defDir construct:'resources') exists
+ ifTrue:[defDir := defDir construct:'resources'].
+ (defDir construct:'grammar') exists
+ ifTrue:[defDir := defDir construct:'grammar'].
+ ^defDir
+
+ "Created: / 11-05-2007 / 13:01:47 / janfrog"
+!
+
+guessParserDefinitionFilename
+
+ ^'scanner.txt'
+
+ "Created: / 11-05-2007 / 13:16:34 / janfrog"
+!
+
+guessScannerDefinitionFilename
+
+ ^'scanner.txt'
+
+ "Created: / 11-05-2007 / 13:16:28 / janfrog"
+!
+
+parseAndEvaluate: aBlock
+ | class |
+ class := self parserClass.
+ class isNil ifTrue: [^self warn: 'No parser defined'].
+ aBlock value: (class parse: self testHolder value
+ onError:
+ [:aString :position |
+ self tabList selection: 'Test'.
+ self displayError: aString at: position.
+ ^self])
+!
+
+removeCommentedPartOf: aString
+ | inStream outStream |
+ inStream := ReadStream on: aString.
+ outStream := WriteStream on: String new.
+ inStream upTo: $".
+ [inStream atEnd] whileFalse:
+ [(inStream peekFor: $") ifTrue: [outStream nextPut: $"].
+ outStream nextPutAll: (inStream upTo: $")].
+ ^outStream contents
+!
+
+selectedSpec
+ ^(self tabList selection asLowercase , 'WindowSpec') asSymbol
+!
+
+syntaxError: aString inFile:file at:position
+
+ | fileContents skipped lineNo|
+ fileContents := file asFilename contents.
+ skipped := 0.
+ lineNo := 1.
+ fileContents do:[:line|
+ skipped := skipped + line size + 1.
+ (skipped > position) ifTrue:
+ [^Dialog warn:'Syntax error: ',aString, Character cr, ' in ',file,' at line #',lineNo printString].
+ lineNo := lineNo + 1.
+ ]
+
+ "Created: / 09-04-2006 / 18:13:26 / janfrog"
+!
+
+verifyParser
+ ^ [
+ SmaCCGrammarCompiler new buildScanner:self scannerDefinition
+ andParser:self parserDefinition.
+ true
+ ] on:SmaCCParserError
+ do:[:ex |
+ self loadScannerAndParserFromFileHolder value ifTrue:[
+ self
+ syntaxError:ex description
+ inFile:self parserDefinitionFileHolder value
+ at:ex parameter position
+ ] ifFalse:[
+ self tabList selection:'Parser'.
+ self displayError:ex description at:ex parameter position
+ ].
+ ex return:false
+ ]
+
+ "Modified: / 11-05-2007 / 12:47:09 / janfrog"
+!
+
+verifyScanner
+ SmaCCScannerParser parse: self scannerDefinition
+ onError:
+ [:aString :position |
+ self loadScannerAndParserFromFileHolder value
+ ifTrue:
+ [self syntaxError:aString inFile:scannerDefinitionFileHolder value at:position]
+ ifFalse:
+ [self tabSelectionToScannerDefinition.
+ self displayError: aString at: position].
+ ^false].
+ ^true
+
+ "Modified: / 14-02-2008 / 11:31:24 / janfrog"
+!
+
+verifySyntax
+ ^self verifyScanner and: [self verifyParser]
+! !
+
+!SmaCCParserGenerator class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /opt/data/cvs/stx/goodies/smaCC/SmaCC__SmaCCParserGenerator.st,v 1.10 2008-02-17 10:30:09 vranyj1 Exp $'
+! !
+
+SmaCCParserGenerator initialize!