My favorites | Sign in
Project Home Downloads Wiki Issues Source
Repository:
Checkout   Browse   Changes   Clones  
Changes to /doc-src/manual/style.rst
8f2692346ba5 vs. 50cf79968d0f Compare: vs.  Format:
Revision 50cf79968d0f
Go to: 
Project members, sign in to write a code review
/doc-src/manual/style.rst   8f2692346ba5 /doc-src/manual/style.rst   50cf79968d0f
1 1
2 .. index:: patterns 2 .. index:: patterns
3 .. _style: 3 .. _style:
4 4
5 Patterns 5 Patterns
6 ======== 6 ========
7 7
8 Some guidelines for writing good parsers. 8 Some guidelines for writing good parsers.
9 9
10 10
11 .. index:: operators 11 .. index:: operators
12 12
13 Operators are Matchers 13 Operators are Matchers
14 ---------------------- 14 ----------------------
15 15
16 Remember that operators are just shorthand for matchers (``&`` instead of 16 Remember that operators are just shorthand for matchers (``&`` instead of
17 ``And()`` etc). You don't have 17 `And() <api/redirect.html#lepl.matchers.combine.And>`_ etc). You don't have
18 to use operators --- see the discussion on :ref:`caveatsandlimitations`. 18 to use operators --- see the discussion on :ref:`caveatsandlimitations`.
19 19
20 But remember that ``&`` and ``And()`` *do differ* when using 20 But remember that ``&`` and `And() <api/redirect.html#lepl.matchers.combine.And>`_ *do differ* when using
21 :ref:`separators`. 21 :ref:`separators`.
22 22
23 23
24 .. index:: Or() 24 .. index:: Or()
25 .. _complexor: 25 .. _complexor:
26 26
27 Use Or() With Complex Alternatives 27 Use Or() With Complex Alternatives
28 ---------------------------------- 28 ----------------------------------
29 29
30 Use `Or(..., ..., ...) <api/redirect.html#lepl.matchers.combine.Or>`_ for 30 Use `Or(..., ..., ...) <api/redirect.html#lepl.matchers.combine.Or>`_ for
31 alternatives with productions. The ``|`` syntax can lead to errors because it 31 alternatives with productions. The ``|`` syntax can lead to errors because it
32 binds more tightly than ``>``. 32 binds more tightly than ``>``.
33 33
34 34
35 .. index:: Apply() 35 .. index:: Apply()
36 .. _applycase: 36 .. _applycase:
37 37
38 ``>`` Capitalised; ``>>`` lowercase 38 ``>`` Capitalised; ``>>`` lowercase
39 ----------------------------------- 39 -----------------------------------
40 40
41 Nodes are typically made with constructors and invoked with ``>``, while the 41 Nodes are typically made with constructors and invoked with ``>``, while the
42 processing of results is usually done with mapped functions. So ``>`` is 42 processing of results is usually done with mapped functions. So ``>`` is
43 followed by a Capitalised name, while ``>>`` is followed by a lowercase name. 43 followed by a Capitalised name, while ``>>`` is followed by a lowercase name.
44 Noticing and following this convention can help avoid issues with the 44 Noticing and following this convention can help avoid issues with the
45 behaviour of ``Apply()`` with 45 behaviour of `Apply() <api/redirect.html#lepl.matchers.derived.Apply>`_ with
46 ``raw=False`` (the default implementation of ``>``), which adds an extra level 46 ``raw=False`` (the default implementation of ``>``), which adds an extra level
47 of nesting and is usually inappropriate for use with functions. 47 of nesting and is usually inappropriate for use with functions.
48 48
49 ``throw`` can be used with ``>>`` or ``>``. 49 ``throw`` can be used with ``>>`` or ``>``.
50 50
51 51
52 .. index:: Separator() 52 .. index:: Separator()
53 .. _separator: 53 .. _separator:
54 54
55 Define Words Before Using DroppedSpace (or Separator) 55 Define Words Before Using DroppedSpace (or Separator)
56 ----------------------------------------------------- 56 -----------------------------------------------------
57 57
58 ``DroppedSpace()`` and ``Separator()`` 58 `DroppedSpace() <api/redirect.html#lepl.matchers.operators.DroppedSpace>`_ and `Separator() <api/redirect.html#lepl.matchers.operators.Separator>`_
59 simplify the handling of spaces in the grammar. To avoid confusion, split 59 simplify the handling of spaces in the grammar. To avoid confusion, split
60 your grammar into two. The first part, defining words, should come before 60 your grammar into two. The first part, defining words, should come before
61 ``with``; the second part should come after. 61 ``with``; the second part should come after.
62 62
63 >>> # words defined here 63 >>> # words defined here
64 >>> word = Letter()[:,...] 64 >>> word = Letter()[:,...]
65 >>> with DroppedSpace(): 65 >>> with DroppedSpace():
66 >>> # sentences defined here 66 >>> # sentences defined here
67 >>> sentence = word[1:] 67 >>> sentence = word[1:]
68 68
69 69
70 Explicitly Exclude Spaces 70 Explicitly Exclude Spaces
71 ------------------------- 71 -------------------------
72 72
73 By default, repetition in Lepl is greedy. This means that, no matter what 73 By default, repetition in Lepl is greedy. This means that, no matter what
74 ``Separator()`` is used, `Any()[:] 74 `Separator() <api/redirect.html#lepl.matchers.operators.Separator>`_ is used, `Any()[:]
75 <api/redirect.html#lepl.match.Any>`_ will swallow the *entire* input. 75 <api/redirect.html#lepl.match.Any>`_ will swallow the *entire* input.
76 76
77 So handling spaces in a grammar takes two steps: 77 So handling spaces in a grammar takes two steps:
78 78
79 1. Exclude the spaces from matchers that produce results. 79 1. Exclude the spaces from matchers that produce results.
80 80
81 2. Use ``Separator()`` to "mop up" the 81 2. Use `Separator() <api/redirect.html#lepl.matchers.operators.Separator>`_ to "mop up" the
82 input that remains. 82 input that remains.
83 83
84 84
85 .. index:: Delayed() 85 .. index:: Delayed()
86 86
87 Use Delayed() For Recursive Definitions 87 Use Delayed() For Recursive Definitions
88 --------------------------------------- 88 ---------------------------------------
89 89
90 Sometimes a grammar needs to refer to matchers before they are defined. The 90 Sometimes a grammar needs to refer to matchers before they are defined. The
91 ``Delayed()`` matcher acts as a 91 `Delayed() <api/redirect.html#lepl.matchers.core.Delayed>`_ matcher acts as a
92 placeholder which can be passed to other functions. It can be defined later 92 placeholder which can be passed to other functions. It can be defined later
93 using ``+=``:: 93 using ``+=``::
94 94
95 >>> expr = Delayed() 95 >>> expr = Delayed()
96 >>> number = Digit()[1:,...] 96 >>> number = Digit()[1:,...]
97 >>> with Separator(r'\s*'): 97 >>> with Separator(r'\s*'):
98 >>> term = number | '(' & expr & ')' 98 >>> term = number | '(' & expr & ')'
99 >>> muldiv = Any('*/') 99 >>> muldiv = Any('*/')
100 >>> factor = term & (muldiv & term)[:] 100 >>> factor = term & (muldiv & term)[:]
101 >>> addsub = Any('+-') 101 >>> addsub = Any('+-')
102 >>> expr += factor & (addsub & factor)[:] 102 >>> expr += factor & (addsub & factor)[:]
103 103
104 104
105 Imports 105 Imports
106 ------- 106 -------
107 107
108 The most commonly used classes are exposed via the ``lepl`` module, so simple 108 The most commonly used classes are exposed via the `lepl <api/redirect.html#lepl>`_ module, so simple
109 scripts can use:: 109 scripts can use::
110 110
111 from lepl import * 111 from lepl import *
112 112
Powered by Google Project Hosting