[Subversion] / SCALE / scale / dsl.txt  

Diff of /SCALE/scale/dsl.txt

Parent Directory | Revision Log

version 2087, Sun Sep 4 20:31:01 2005 UTC version 2088, Sun Sep 4 23:18:43 2005 UTC
Line 368 
Line 368 
     ...      ...
   
   
   Parsing Declarations
   ====================
   
   The SCALE language consists entirely of "declaration" statements.  A
   declaration is an expression with optional assignment prefixes, an optional
   "context" clause, and an optional nested block.  Here are some examples of
   valid SCALE declarations::
   
       >>> samples = dsl.parse_block(dsl.tokenize_string("""
       ...
       ... foo(gee):
       ...     zing from Zang
       ...     bar = baz = squidge() from spammity>=1.2:
       ...         answer = 42
       ...
       ... "whiz" = "oh boy" = 123 * 456
       ...
       ... something = me from:
       ...     me = 789
       ...
       ... """))
   
   The ``parse_declarations()`` function yields 4-element tuples containing the
   assigned names, value expression, context clause, and nested block for each
   statement in a given block::
   
       >>> def print_decl(names, expr, context, block):
       ...     if names:
       ...         print "Assigned to:", names
       ...     print "Expression:", `dsl.detokenize(expr)`
       ...     if context is not None:
       ...         print "Context:", `dsl.detokenize(context)`
       ...     if block:
       ...         print "Block:"
       ...         print dsl.detokenize(dsl.flatten_block(block),8).rstrip()
       ...     print
   
       >>> for names, expr, context, block in dsl.parse_declarations(samples):
       ...     print_decl(names, expr, context, block)
       ...
       Expression: 'foo(gee)'
       Block:
               zing from Zang
               bar = baz = squidge() from spammity>=1.2:
                   answer = 42
       ...
       Assigned to: ['whiz', 'oh boy']
       Expression: '123 * 456'
       ...
       Assigned to: ['something']
       Expression: 'me'
       Context: ''
       Block:
               me = 789
       ...
   
       >>> for names,expr,context,block in dsl.parse_declarations(samples[0][1]):
       ...     print_decl(names, expr, context, block)
       ...
       Expression: 'zing'
       Context: 'Zang'
       ...
       Assigned to: ['bar', 'baz']
       Expression: 'squidge()'
       Context: 'spammity>=1.2'
       Block:
               answer = 42
       ...
   
   As you can see, the `context` of a declaration is either a token list or None,
   depending on whether a "from" clause appeared in the declaration.  `names` is
   a (possibly empty) list of the names to which the expression is being assigned,
   with quoted strings being treated as if they were normal identifiers.  `expr`,
   meanwhile, is the token list for the declaration's value expression, and
   `block` is the nested block beneath the statement, if any.  The `expr` and
   `context` token lists are stripped of whitespace tokens at the top level, and
   do not contain the ``:`` if one was present at the end of the declaration.
   
   If a parsed line is not a valid declaration, a ``TokenError`` is raised.  Valid
   declarations must end with a ``:`` if and only if an indented block follows::
   
       >>> def try_parsing(s):
       ...     list(
       ...         dsl.parse_declarations(dsl.parse_block(dsl.tokenize_string(s)))
       ...     )
   
       >>> try_parsing("xyz:")
       Traceback (most recent call last):
         ...
       TokenError: ("Expected indented block following ':'", (1, 4))
   
       >>> try_parsing("xyz\n  foo")
       Traceback (most recent call last):
         ...
       TokenError: ("Expected ':' before indented block", (1, 3))
   
   And the "from" clause of a declaration can only be empty if it introduces a
   block::
   
       >>> try_parsing("xyz from:\n  foo")     # okay
       >>> try_parsing("xyz from 123")         # also okay
       >>> try_parsing("xyz from")             # not okay
       Traceback (most recent call last):
         ...
       TokenError: ("Expected context or ':' after 'from'", (1, 8))
   
   It's also not valid to omit the expression if the declaration assigns to any
   names::
   
       >>> try_parsing("from foo")         # okay
       >>> try_parsing("foo = from bar")   # not okay
       Traceback (most recent call last):
         ...
       TokenError: ('Expected expression', (1, 5))
       >>> try_parsing("foo =")   # also not okay
       Traceback (most recent call last):
         ...
       TokenError: ('Expected expression', (1, 5))
   
   It's also an error to assign to something that's not an identifier or quoted
   string::
   
       >>> try_parsing("abc = '123' = 456")    # okay, assigns 'abc' and '123'
       >>> try_parsing("123 = 456")            # can't assign to number!
       Traceback (most recent call last):
         ...
       TokenError: ("Expected name or string before '='", (1, 4))
   
   It's important to note, however, that ``parse_declarations()`` does not
   prescribe or guarantee any particular syntax for the `expr` and `context`
   clauses.  So, they are not guaranteed to be valid Python expressions.  This
   means that you can create SCALE dialects with different expression or context
   syntax, but it also means that you should be prepared for the possibility of
   syntax errors within the expression or context clause.
   


Generate output suitable for use with a patch program
Legend:
Removed from v.2087  
changed lines
  Added in v.2088

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help