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