SmallSenseParser.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Thu, 06 Sep 2012 17:38:47 +0100
changeset 28 f516772ba2b8
parent 19 3b7fd62bf51c
child 29 fe650a6e5704
permissions -rw-r--r--
- SmallSenseChecker class definition added: #initialize #new changed: #checkMethodsForClass: - extensions ...

"{ Package: 'stx:libtool/smallsense' }"

SyntaxHighlighter subclass:#SmallSenseParser
	instanceVariableNames:'error'
	classVariableNames:''
	poolDictionaries:''
	category:'SmallSense-Core'
!


!SmallSenseParser methodsFor:'error handling'!

parseError:message position:startPos to:endPos

    error := ParseErrorNode new 
                errorString: message;
                errorToken:  token asString;
                startPosition: startPos endPosition: endPos.
    ^error

    "Created: / 27-11-2011 / 09:35:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

syntaxError:message position:startPos to:endPos

    ^self parseError:message position:startPos to:endPos

    "Created: / 27-11-2011 / 09:45:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseParser methodsFor:'parsing'!

parseExpressionWithSelf:anObject notifying:someOne ignoreErrors:ignoreErrors ignoreWarnings:ignoreWarnings inNameSpace:aNameSpaceOrNil

    |tree token|

    aNameSpaceOrNil notNil ifTrue:[
        self currentNameSpace:aNameSpaceOrNil
    ].
    self setSelf:anObject.
    self notifying:someOne.
    self ignoreErrors:ignoreErrors.
    self ignoreWarnings:ignoreWarnings.
    token := self nextToken.
    (token == $^) ifTrue:[
        self nextToken.
    ].
    (token == #EOF) ifTrue:[
        ^ nil
    ].
    "/tree := self expression.
    tree := self statementList.    
    (self errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
    ^ tree

    "Created: / 14-12-1999 / 15:11:37 / cg"
    "Created: / 09-07-2011 / 22:23:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseParser methodsFor:'parsing-tweaks'!

blockStatementList
    "parse a blocks statementlist; return a node-tree, nil or #Error"
    
    |thisStatement prevStatement firstStatement eMsg blockStart|

    blockStart := tokenPosition.
    (tokenType == $]) ifTrue:[
        ^ nil
    ].          
    thisStatement := self statement.
    (thisStatement == #Error) ifTrue:[
        ^ #Error
    ].
    firstStatement := thisStatement.
    [
        tokenType == $] or:[ tokenType == #EOF ]
    ] whileFalse:[
        (tokenType == $.) ifFalse:[   
            (tokenType == #EOF) ifTrue:[
                "    self syntaxError:'missing '']'' in block' position:blockStart to:(source position1Based).
                    ^ #Error."
            ].
            (tokenType == $)) ifTrue:[
                eMsg := 'missing '']'' or bad '')'' in block'
            ] ifFalse:[
                eMsg := 'missing ''.'' between statements (i.e. ''' 
                            , tokenType printString , '''-token unexpected)'
            ].          
             "self syntaxError:eMsg position:blockStart to:tokenPosition.
             ^ #Error"
        ].

        prevStatement := thisStatement.    
        (eMsg isNil ) ifTrue:[              
            self nextToken.
        ].
        tokenType == $] ifTrue:[
            "
             *** I had a warning here (since it was not defined
             *** in the blue-book; but PD-code contains a lot of
             *** code with periods at the end so that the warnings
             *** became annoying

             self warning:'period after last statement in block'."
            self markBracketAt:tokenPosition.
            ^ firstStatement
        ].
        thisStatement := self statement.
        (thisStatement == #Error) ifTrue:[
            ^ #Error
        ].
        prevStatement nextStatement:thisStatement.
        (eMsg notNil) ifTrue:[
            self nextToken.
        ].
        eMsg := nil.
    ].
    self markBracketAt:tokenPosition.
    ^ self statementListRewriteHookFor:firstStatement

    "Modified: / 27-07-2010 / 08:57:02 / cg"
    "Modified: / 18-02-2011 / 21:40:33 / Jakub <zelenja7@fel.cvut.cz>"
!

primary
    "parse a primary-expression; return a node-tree, nil or #Error.
     This also cares for namespace-access-pathes."
    
    | node |
    node := super primary.
    "/If an error occured, return the error node"
    node == #Error ifTrue:[
        self assert: error notNil description: 'Parse error occured but no error node.'.
        node := error. error := nil.
    ].
    ^node

    "Modified: / 18-10-2006 / 19:37:50 / cg"
    "Created: / 07-02-2011 / 18:09:31 / Jakub <zelenja7@fel.cvut.cz>"
    "Modified: / 06-04-2011 / 22:40:05 / Jakub <zelenja7@fel.cvut.cz>"
    "Modified: / 27-11-2011 / 09:42:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

statementList
    "parse a statementlist; return a node-tree, nil or #Error.
     Statements must be separated by periods.

     statementList ::= <statement>
                       | <statementList> . <statement>"
    
    |thisStatement prevStatement firstStatement periodPos prevExpr|

    thisStatement := self statement.
    (thisStatement == #Error) ifTrue:[
        self breakPoint: #jv.            
        ^ #Error
    ].
    firstStatement := thisStatement.
    [ tokenType == #EOF ] whileFalse:[
        prevExpr := thisStatement expression.
        (prevExpr notNil 
            and:[ prevExpr isMessage and:[ thisStatement isReturnNode not ] ]) 
                ifTrue:[
                    (#( #'=' #'==' ) includes:prevExpr selector) ifTrue:[
                        self 
                            warning:'useless computation - mistyped assignment (i.e. did you mean '':='') ?'
                            position:prevExpr selectorPosition
                    ].
                ].
        periodPos := tokenPosition.

        (tokenType == $. or:[ firstStatement = thisStatement and:[firstStatement expression isErrorNode] ]) ifTrue:[    
            self nextToken.
        ].
        tokenType == $. ifTrue:[
            self emptyStatement.
        ].
        (tokenType == $]) ifTrue:[
            currentBlock isNil ifTrue:[
                
            ] ifFalse:[
                ^ self statementListRewriteHookFor:firstStatement
            ].
        ].
        (tokenType == #EOF) ifTrue:[
            currentBlock notNil ifTrue:[
                "self parseError:''']'' expected (block nesting error)'."
            ] ifFalse:[
                ^ self statementListRewriteHookFor:firstStatement
            ].
        ].
        prevStatement := thisStatement.
        prevStatement isReturnNode ifTrue:[
            self warning:'statements after return' position:tokenPosition
        ].
        thisStatement := self statement.
        (thisStatement == #Error) ifTrue:[
            self breakPoint: #jv.           
            ^ #Error
        ].
        (thisStatement expression isNil or:[thisStatement expression isErrorNode]) ifTrue:[
            self nextToken.
        ].

        prevStatement nextStatement:thisStatement
    ].
    ^ self statementListRewriteHookFor:firstStatement

    "Modified: / 20-11-2006 / 14:05:52 / cg"
    "Created: / 07-02-2011 / 17:10:44 / Jakub <zelenja7@fel.cvut.cz>"
    "Modified: / 18-02-2011 / 20:34:56 / Jakub <zelenja7@fel.cvut.cz>"
    "Modified: / 27-11-2011 / 16:11:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseParser methodsFor:'syntax coloring'!

markBracketAt:pos

    sourceText isNil ifTrue:[^self].
    ^super markBracketAt:pos

    "Created: / 03-04-2011 / 22:39:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

markFrom:pos1 to:pos2 withEmphasis:fontEmp color:clrIn

    sourceText isNil ifTrue:[^self].
    super markFrom:pos1 to:pos2 withEmphasis:fontEmp color:clrIn

    "Created: / 03-04-2011 / 22:24:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

markFrom:pos1 to:pos2 withEmphasis:fontEmp color:fgClr1 ifNil:fgClr2 backgroundColor:bgClr

    sourceText isNil ifTrue:[^self].
    super markFrom:pos1 to:pos2 withEmphasis:fontEmp color:fgClr1 ifNil:fgClr2 backgroundColor:bgClr

    "Created: / 14-02-2012 / 11:08:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseParser class methodsFor:'documentation'!

version_SVN
    ^ '$Id: SmallSenseParser.st 7922 2012-03-09 07:57:34Z vranyj1 $'
! !