Parser.st
changeset 20 f8dd8ba75205
parent 19 84a1ddf215a5
child 21 338c3cfeffbf
equal deleted inserted replaced
19:84a1ddf215a5 20:f8dd8ba75205
    32        poolDictionaries:''
    32        poolDictionaries:''
    33        category:'System-Compiler'
    33        category:'System-Compiler'
    34 !
    34 !
    35 
    35 
    36 Parser comment:'
    36 Parser comment:'
    37 
       
    38 COPYRIGHT (c) 1989 by Claus Gittinger
    37 COPYRIGHT (c) 1989 by Claus Gittinger
    39              All Rights Reserved
    38              All Rights Reserved
    40 
       
    41 $Header: /cvs/stx/stx/libcomp/Parser.st,v 1.10 1994-03-30 10:10:24 claus Exp $
       
    42 '!
    39 '!
    43 
    40 
    44 !Parser class methodsFor:'documentation'!
    41 !Parser class methodsFor:'documentation'!
       
    42 
       
    43 copyright
       
    44 "
       
    45  COPYRIGHT (c) 1989 by Claus Gittinger
       
    46               All Rights Reserved
       
    47 
       
    48  This software is furnished under a license and may be used
       
    49  only in accordance with the terms of that license and with the
       
    50  inclusion of the above copyright notice.   This software may not
       
    51  be provided or otherwise made available to, or used by, any
       
    52  other person.  No title to or ownership of the software is
       
    53  hereby transferred.
       
    54 "
       
    55 !
       
    56 
       
    57 version
       
    58 "
       
    59 $Header: /cvs/stx/stx/libcomp/Parser.st,v 1.11 1994-06-02 20:26:08 claus Exp $
       
    60 "
       
    61 !
    45 
    62 
    46 documentation
    63 documentation
    47 "
    64 "
    48     Parser is used for both parsing and evaluating smalltalk expressions;
    65     Parser is used for both parsing and evaluating smalltalk expressions;
    49     it first builds a parseTree which is then interpreted (evaluate) or
    66     it first builds a parseTree which is then interpreted (evaluate) or
    64     the parser for referencedXVars or modifiedXVars (see SystemBrowser).
    81     the parser for referencedXVars or modifiedXVars (see SystemBrowser).
    65 
    82 
    66     You can also use parsers for all kinds of other things (ChangesBrowser for
    83     You can also use parsers for all kinds of other things (ChangesBrowser for
    67     example analyzes the expressions in the changelist ...) by looking at the
    84     example analyzes the expressions in the changelist ...) by looking at the
    68     parsers tree. (Although this is somewhat dangerous, since it exports the
    85     parsers tree. (Although this is somewhat dangerous, since it exports the
    69     compilers internals ... better style would be to add specialized query
    86     compilers internals ... better style is to add specialized query methods here,
    70      methods here.)
    87     which will be done incrementally.)
    71 
    88 
    72     One instance of Parser is created to parse one method or expression - i.e.
    89     One instance of Parser is created to parse one method or expression - i.e.
    73     its not suggested to reuse parsers.
    90     its not suggested to reuse parsers.
    74 
    91 
    75     Instance variables:
    92     Instance variables:
   148     ^ self 
   165     ^ self 
   149         evaluate:aStringOrStream 
   166         evaluate:aStringOrStream 
   150         in:nil 
   167         in:nil 
   151         receiver:nil 
   168         receiver:nil 
   152         notifying:nil 
   169         notifying:nil 
       
   170         logged:false
   153         ifFail:nil 
   171         ifFail:nil 
   154 
   172 
   155     "
   173     "
   156      Compiler evaluate:'1 + 2'
   174      Compiler evaluate:'1 + 2'
   157      Compiler evaluate:'''hello world'' asSortedCollection displayString printNL'
   175      Compiler evaluate:'''hello world'' asSortedCollection displayString printNL'
   158      Compiler evaluate:'''hello world'' asSortedCollection printNL'
   176      Compiler evaluate:'''hello world'' asSortedCollection printNL'
   159     "
   177     "
       
   178 !
       
   179 
       
   180 evaluate:aStringOrStream ifFail:failBlock
       
   181     "return the result of evaluating an expression in aStringOrStream.
       
   182      In case of any syntax errors, return the value of failBlock."
       
   183 
       
   184     ^ self 
       
   185         evaluate:aStringOrStream 
       
   186         in:nil 
       
   187         receiver:nil 
       
   188         notifying:nil 
       
   189         logged:false
       
   190         ifFail:failBlock 
       
   191 
       
   192     "
       
   193      Compiler evaluate:'1 +' ifFail:['oops']   
       
   194 
       
   195     "
       
   196 !
       
   197 
       
   198 evaluate:aStringOrStream logged:logged
       
   199     "return the result of evaluating an expression in aStringOrStream"
       
   200 
       
   201     ^ self 
       
   202         evaluate:aStringOrStream 
       
   203         in:nil 
       
   204         receiver:nil 
       
   205         notifying:nil 
       
   206         logged:logged
       
   207         ifFail:nil 
   160 !
   208 !
   161 
   209 
   162 evaluate:aStringOrStream notifying:requestor
   210 evaluate:aStringOrStream notifying:requestor
   163     "return the result of evaluating aString, 
   211     "return the result of evaluating aString, 
   164      errors are reported to requestor"
   212      errors are reported to requestor"
   166     ^ self 
   214     ^ self 
   167         evaluate:aStringOrStream 
   215         evaluate:aStringOrStream 
   168         in:nil 
   216         in:nil 
   169         receiver:nil 
   217         receiver:nil 
   170         notifying:requestor
   218         notifying:requestor
       
   219         logged:false
   171         ifFail:nil 
   220         ifFail:nil 
   172 
   221 
   173 !
   222 !
   174 
   223 
   175 evaluate:aString receiver:anObject notifying:requestor
   224 evaluate:aStringOrStream receiver:anObject notifying:requestor
   176     "return the result of evaluating aString, 
   225     "return the result of evaluating aString, 
   177      errors are reported to requestor. Allow access to
   226      errors are reported to requestor. Allow access to
   178      anObject as self and to its instVars (used in the inspector)"
   227      anObject as self and to its instVars (used in the inspector)"
   179 
   228 
   180     ^ self 
   229     ^ self 
   181         evaluate:aString
   230         evaluate:aStringOrStream
   182         in:nil
   231         in:nil
   183         receiver:anObject
   232         receiver:anObject
   184         notifying:requestor
   233         notifying:requestor
       
   234         logged:false
   185         ifFail:nil
   235         ifFail:nil
   186 !
   236 !
   187 
   237 
   188 evaluate:aStringOrStream in:aContext receiver:anObject 
   238 evaluate:aStringOrStream in:aContext receiver:anObject 
   189                                     notifying:requestor
   239                                     notifying:requestor
   190                                        ifFail:failBlock
   240                                        ifFail:failBlock
       
   241     ^ self 
       
   242         evaluate:aStringOrStream
       
   243         in:nil
       
   244         receiver:anObject
       
   245         notifying:requestor
       
   246         logged:false
       
   247         ifFail:nil
       
   248 !
       
   249 
       
   250 evaluate:aStringOrStream in:aContext receiver:anObject notifying:requestor logged:logged ifFail:failBlock
       
   251     "return the result of evaluating aStringOrStream, errors are reported to requestor. 
       
   252      Allow access to anObject as self and to its instVars (used in the inspector).
       
   253      If logged is true, an entry is added to the change-file. If the failBlock argument
       
   254      is non-nil, it is evaluated if an error occurs."
       
   255 
       
   256     "XXX: logging is not yet implemented"
       
   257 
   191     |parser tree mustBackup|
   258     |parser tree mustBackup|
   192 
   259 
   193     aStringOrStream isNil ifTrue:[^ nil].
   260     aStringOrStream isNil ifTrue:[^ nil].
   194     aStringOrStream isStream ifTrue:[
   261     aStringOrStream isStream ifTrue:[
   195         parser := self for:aStringOrStream.
   262         parser := self for:aStringOrStream.
   236 
   303 
   237 !Parser class methodsFor:'parsing'!
   304 !Parser class methodsFor:'parsing'!
   238 
   305 
   239 selectorInExpression:aString
   306 selectorInExpression:aString
   240     "parse an expression - return the selector. Used for
   307     "parse an expression - return the selector. Used for
   241      SystemBrowsers implementors/senders query-box initial text"
   308      SystemBrowsers implementors/senders query-box initial text."
   242 
   309 
   243     |tree parser|
   310     |tree parser|
   244 
   311 
   245     (aString isNil or:[aString isEmpty]) ifTrue:[^ nil].
   312     (aString isNil or:[aString isEmpty]) ifTrue:[^ nil].
   246 
   313 
   263     parser ignoreErrors.
   330     parser ignoreErrors.
   264     parser nextToken.
   331     parser nextToken.
   265     ^ parser degeneratedKeywordExpressionForSelector
   332     ^ parser degeneratedKeywordExpressionForSelector
   266 
   333 
   267 "
   334 "
   268     Parser selectorInExpression:'foo at:1 put:(5 * bar)'
   335     Parser selectorInExpression:'foo at:1 put:(5 * bar)'     
   269     Parser selectorInExpression:'(foo at:1) at:1'
   336     Parser selectorInExpression:'(foo at:1) at:1'           
   270     Parser selectorInExpression:'1 + 4'
   337     Parser selectorInExpression:'1 + 4'                     
   271     Parser selectorInExpression:'1 negated'
   338     Parser selectorInExpression:'1 negated'                 
   272     Parser selectorInExpression:'at:1 put:5'
   339     Parser selectorInExpression:'at:1 put:5'            
   273     Parser selectorInExpression:'a := foo at:1 put:5'
   340     Parser selectorInExpression:'a := foo at:1 put:5'    
   274 "
   341 "
   275 !
   342 !
   276 
   343 
   277 parseExpression:aString
   344 parseExpression:aString
   278     "parse aString as an expression; return the parseTree, nil or #error"
   345     "parse aString as an expression; return the parseTree, nil or #error"
   307 parseMethodSpecification:aString
   374 parseMethodSpecification:aString
   308     "parse a methods selector & arg specification; 
   375     "parse a methods selector & arg specification; 
   309      return the parser, nil or #error"
   376      return the parser, nil or #error"
   310 
   377 
   311     ^ self parseMethodSpecification:aString in:nil
   378     ^ self parseMethodSpecification:aString in:nil
       
   379 
       
   380     "
       
   381      |p|
       
   382 
       
   383      p := Parser parseMethodSpecification:'foo:arg1 bar:arg2 baz:arg3'.
       
   384      'nArgs: ' print. p numberOfMethodArgs printNL.
       
   385      'args:  ' print. p methodArgs printNL.
       
   386      'sel:   ' print. p selector printNL
       
   387     "
   312 !
   388 !
   313 
   389 
   314 parseMethodSpecification:aString in:aClass
   390 parseMethodSpecification:aString in:aClass
   315     "parse a methods selector & arg spec for a given class;
   391     "parse a methods selector & arg spec for a given class;
   316      return the parser, nil or #error"
   392      return the parser, nil or #error"
   328 parseMethodArgAndVarSpecification:aString
   404 parseMethodArgAndVarSpecification:aString
   329     "parse a methods selector, arg and var spec;
   405     "parse a methods selector, arg and var spec;
   330      return the parser, nil or #error"
   406      return the parser, nil or #error"
   331 
   407 
   332     ^ self parseMethodArgAndVarSpecification:aString in:nil
   408     ^ self parseMethodArgAndVarSpecification:aString in:nil
       
   409 
       
   410     "
       
   411      |p|
       
   412 
       
   413      p := Parser parseMethodArgAndVarSpecification:'foo:arg1 bar:arg2 baz:arg3 |l1 l2|'.
       
   414      'nArgs:  ' print. p numberOfMethodArgs printNL.
       
   415      'args:   ' print. p methodArgs printNL.
       
   416      'sel:    ' print. p selector printNL.
       
   417      'nLocal: ' print. p numberOfMethodVars printNL.
       
   418      'locals: ' print. p methodVars printNL.
       
   419     "
   333 !
   420 !
   334 
   421 
   335 parseMethodArgAndVarSpecification:aString in:aClass
   422 parseMethodArgAndVarSpecification:aString in:aClass
   336     "parse a methods selector, arg and var spec for a given class;
   423     "parse a methods selector, arg and var spec for a given class;
   337      return the parser, nil or #error"
   424      return the parser, nil or #error"
   349 
   436 
   350 parseMethod:aString
   437 parseMethod:aString
   351     "parse a method; return parser, nil or #error"
   438     "parse a method; return parser, nil or #error"
   352 
   439 
   353     ^ self parseMethod:aString in:nil
   440     ^ self parseMethod:aString in:nil
       
   441 
       
   442     "
       
   443      |p|
       
   444 
       
   445      p := Parser parseMethod:'foo:arg1 bar:arg2 baz:arg3 |l1 l2| l1 := 0. l2 := arg1. ^ self'.
       
   446      'nArgs:  ' print. p numberOfMethodArgs printNL.
       
   447      'args:   ' print. p methodArgs printNL.
       
   448      'sel:    ' print. p selector printNL.
       
   449      'nLocal: ' print. p numberOfMethodVars printNL.
       
   450      'locals: ' print. p methodVars printNL.
       
   451      'tree:   ' printNL. p tree printAllOn:Stdout. Stdout cr.
       
   452     "
   354 !
   453 !
   355 
   454 
   356 parseMethod:aString in:aClass
   455 parseMethod:aString in:aClass
   357     "parse a method for a given class; return , nil or #error"
   456     "parse a method for a given class; return , nil or #error"
   358 
   457 
   361     aString isNil ifTrue:[^ nil].
   460     aString isNil ifTrue:[^ nil].
   362     parser := self for:(ReadStream on:aString) in:aClass.
   461     parser := self for:(ReadStream on:aString) in:aClass.
   363     tree := parser parseMethod.
   462     tree := parser parseMethod.
   364     (parser errorFlag or:[tree == #Error]) ifTrue:[^ nil].
   463     (parser errorFlag or:[tree == #Error]) ifTrue:[^ nil].
   365     ^ parser
   464     ^ parser
       
   465 ! !
       
   466 
       
   467 !Parser class methodsFor:'unparsing'!
       
   468 
       
   469 methodSpecificationForSelector:aSelector
       
   470     "given a selector such as #foo:bar:, return a string that could
       
   471      serve as a methods specification source code.
       
   472      To be used for code generators"
       
   473 
       
   474     ^ self methodSpecificationForSelector:aSelector 
       
   475                                  argNames:#('arg1' 'arg2' 'arg3' 'arg4' 'arg5' 'arg6'
       
   476                                             'arg7' 'arg8' 'arg9' 'arg10' 'arg11' 'arg12'
       
   477                                             'arg13' 'arg14' 'arg15')
       
   478     "
       
   479      Parser methodSpecificationForSelector:#foo:bar:   
       
   480      Parser methodSpecificationForSelector:#+   
       
   481      Parser methodSpecificationForSelector:#negated   
       
   482     "
       
   483 !
       
   484 
       
   485 methodSpecificationForSelector:aSelector argNames:argNames
       
   486     "given a selector such as #foo:bar:, return a string that could
       
   487      serve as a methods specification source code.
       
   488      To be used for code generators"
       
   489 
       
   490     |s nargs parts|
       
   491 
       
   492     s := WriteStream on:String new.
       
   493     nargs := aSelector nArgsIfSelector.
       
   494     nargs == 0 ifTrue:[
       
   495         s nextPutAll:aSelector
       
   496     ] ifFalse:[
       
   497         parts := aSelector partsIfSelector.
       
   498         1 to:nargs do:[:i |
       
   499             s nextPutAll:(parts at:i); space;
       
   500               nextPutAll:(argNames at:i); space.
       
   501         ]
       
   502     ].
       
   503     ^ s contents
       
   504 
       
   505     "
       
   506      Parser methodSpecificationForSelector:#foo:bar: argNames:#('one' 'two' 'three')  
       
   507      Parser methodSpecificationForSelector:#+ argNames:#('one')  
       
   508      Parser methodSpecificationForSelector:#negated   
       
   509     "
   366 ! !
   510 ! !
   367 
   511 
   368 !Parser class methodsFor:'controlling compilation'!
   512 !Parser class methodsFor:'controlling compilation'!
   369 
   513 
   370 compileLazy:aBoolean
   514 compileLazy:aBoolean
  1097         ].
  1241         ].
  1098         sel := self selectorCheck:sel for:receiver position:pos1 to:pos2.
  1242         sel := self selectorCheck:sel for:receiver position:pos1 to:pos2.
  1099         try := MessageNode receiver:receiver selector:sel args:args.
  1243         try := MessageNode receiver:receiver selector:sel args:args.
  1100         (try isMemberOf:String) ifTrue:[
  1244         (try isMemberOf:String) ifTrue:[
  1101             self parseError:try position:pos1 to:pos2.
  1245             self parseError:try position:pos1 to:pos2.
  1102             receiver := MessageNode receiver:receiver selector:sel args:args fold:false
  1246             receiver := MessageNode receiver:receiver selector:sel args:args fold:false.
       
  1247             note := receiver plausibilityCheck.
       
  1248             note notNil ifTrue:[
       
  1249                 self warning:note position:pos1 to:pos2
       
  1250             ].
       
  1251             receiver lineNumber:lno
  1103         ] ifFalse:[
  1252         ] ifFalse:[
  1104             receiver := try
  1253             receiver := try
  1105         ].
  1254         ].
  1106         note := receiver plausibilityCheck.
       
  1107         note notNil ifTrue:[
       
  1108             self warning:note position:pos1 to:pos2
       
  1109         ].
       
  1110         receiver lineNumber:lno
       
  1111     ].
  1255     ].
  1112     ^ receiver
  1256     ^ receiver
  1113 !
  1257 !
  1114 
  1258 
  1115 degeneratedKeywordExpressionForSelector
  1259 degeneratedKeywordExpressionForSelector
  1167         arg := self unaryExpression.
  1311         arg := self unaryExpression.
  1168         (arg == #Error) ifTrue:[^ #Error].
  1312         (arg == #Error) ifTrue:[^ #Error].
  1169         try := BinaryNode receiver:receiver selector:sel arg:arg.
  1313         try := BinaryNode receiver:receiver selector:sel arg:arg.
  1170         (try isMemberOf:String) ifTrue:[
  1314         (try isMemberOf:String) ifTrue:[
  1171             self parseError:try position:pos to:tokenPosition.
  1315             self parseError:try position:pos to:tokenPosition.
  1172             receiver := BinaryNode receiver:receiver selector:sel arg:arg fold:false
  1316             receiver := BinaryNode receiver:receiver selector:sel arg:arg fold:false.
       
  1317             note := receiver plausibilityCheck.
       
  1318             note notNil ifTrue:[
       
  1319                 self warning:note position:pos to:tokenPosition
       
  1320             ].
       
  1321             receiver lineNumber:lno
  1173         ] ifFalse:[
  1322         ] ifFalse:[
  1174             receiver := try
  1323             receiver := try
  1175         ].
  1324         ].
  1176         note := receiver plausibilityCheck.
       
  1177         note notNil ifTrue:[
       
  1178             self warning:note position:pos to:tokenPosition
       
  1179         ].
       
  1180         receiver lineNumber:lno
       
  1181     ].
  1325     ].
  1182     ^ receiver
  1326     ^ receiver
  1183 !
  1327 !
  1184 
  1328 
  1185 unaryExpression
  1329 unaryExpression
  1194         pos2 := pos + tokenName size - 1.
  1338         pos2 := pos + tokenName size - 1.
  1195         sel := self selectorCheck:tokenName for:receiver position:pos to:pos2.
  1339         sel := self selectorCheck:tokenName for:receiver position:pos to:pos2.
  1196         try := UnaryNode receiver:receiver selector:sel.
  1340         try := UnaryNode receiver:receiver selector:sel.
  1197         (try isMemberOf:String) ifTrue:[
  1341         (try isMemberOf:String) ifTrue:[
  1198             self warning:try position:pos to:pos2.
  1342             self warning:try position:pos to:pos2.
  1199             receiver := UnaryNode receiver:receiver selector:sel fold:false
  1343             receiver := UnaryNode receiver:receiver selector:sel fold:false.
       
  1344             receiver lineNumber:tokenLineNr.
  1200         ] ifFalse:[
  1345         ] ifFalse:[
  1201             receiver := try
  1346             receiver := try
  1202         ].
  1347         ].
  1203         receiver lineNumber:tokenLineNr.
       
  1204         self nextToken.
  1348         self nextToken.
  1205     ].
  1349     ].
  1206     ^ receiver
  1350     ^ receiver
  1207 !
  1351 !
  1208 
  1352 
  1726 
  1870 
  1727 array
  1871 array
  1728     |arr elem pos1|
  1872     |arr elem pos1|
  1729 
  1873 
  1730     pos1 := tokenPosition.
  1874     pos1 := tokenPosition.
  1731     arr := OrderedCollection new:200.
  1875     arr := OrderedCollection new:20.
  1732     [tokenType ~~ $) ] whileTrue:[
  1876     [tokenType ~~ $) ] whileTrue:[
  1733         elem := self arrayConstant.
  1877         elem := self arrayConstant.
  1734         (elem == #Error) ifTrue:[
  1878         (elem == #Error) ifTrue:[
  1735             (tokenType == #EOF) ifTrue:[
  1879             (tokenType == #EOF) ifTrue:[
  1736                 self syntaxError:'unterminated array-constant; '')'' expected' 
  1880                 self syntaxError:'unterminated array-constant; '')'' expected' 
  1748     "started with ST-80 R4 - allow byteArray constants as #[ ... ]"
  1892     "started with ST-80 R4 - allow byteArray constants as #[ ... ]"
  1749 
  1893 
  1750     |arr elem pos1 pos2|
  1894     |arr elem pos1 pos2|
  1751 
  1895 
  1752     pos1 := tokenPosition.
  1896     pos1 := tokenPosition.
  1753     arr := OrderedCollection new.
  1897     arr := OrderedCollection new:50.
  1754     [tokenType ~~ $] ] whileTrue:[
  1898     [tokenType ~~ $] ] whileTrue:[
  1755         pos2 := tokenPosition.
  1899         pos2 := tokenPosition.
  1756         elem := self arrayConstant.
  1900         elem := self arrayConstant.
  1757         (elem == #Error) ifTrue:[
  1901         (elem == #Error) ifTrue:[
  1758             (tokenType == #EOF) ifTrue:[
  1902             (tokenType == #EOF) ifTrue:[
  1967     (dists size ~~ 0) ifTrue:[
  2111     (dists size ~~ 0) ifTrue:[
  1968         dists sortWith:names.
  2112         dists sortWith:names.
  1969         dists := dists reverse.             
  2113         dists := dists reverse.             
  1970         names := names reverse.
  2114         names := names reverse.
  1971         n := names size min:10.
  2115         n := names size min:10.
  1972         ^ names copyTo:n
  2116         names := names copyTo:n.
       
  2117 
       
  2118         "if it starts with a lower case character, add all local & instvar names"
       
  2119         (aString at:1) isLowercase ifTrue:[
       
  2120             methodVarNames size > 0 ifTrue:[
       
  2121                 names add:'---- method locals ----'.
       
  2122                 methodVarNames do:[:methodVarName |
       
  2123                     names add:methodVarName.
       
  2124                 ].
       
  2125             ].
       
  2126 
       
  2127 
       
  2128             methodArgs notNil ifTrue:[
       
  2129                 names add:'---- method arguments ----'.
       
  2130                 methodArgNames do:[:methodArgName |
       
  2131                     names add:methodArgName.
       
  2132                 ]
       
  2133             ].
       
  2134 
       
  2135             names add:'---- instance variables ----'.
       
  2136             PrevInstVarNames do:[:instVarName |
       
  2137                 (names includes:instVarName) ifFalse:[
       
  2138                     names add:instVarName.
       
  2139                 ]
       
  2140             ]
       
  2141         ].
       
  2142 
       
  2143         ^ names
  1973     ].
  2144     ].
  1974     ^ nil
  2145     ^ nil
  1975 !
  2146 !
  1976 
  2147 
  1977 correctVariable
  2148 correctVariable