readme: add information section
[nit.git] / lib / parser_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # This file is free software, which comes along with NIT. This software is
4 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
6 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
7 # is kept unaltered, and a notification of the changes is added.
8 # You are allowed to redistribute it and sell it, alone or is a part of
9 # another product.
10
11 # Simple base for hand-made parsers of all kinds
12 module parser_base
13
14 # Basic facilities for common parser operations on String sources
15 class StringProcessor
16 # Source document to parse
17 protected var src: String
18
19 # Length of the source document
20 protected var len: Int is noinit
21
22 # Current position in `src`
23 protected var pos = 0
24
25 # Position at which current line started
26 protected var line_start = 0
27
28 # Current line in `src`
29 protected var line = 1
30
31 # Offset in the current line
32 protected fun line_offset: Int do return pos - line_start + 1
33
34 init do
35 _len = src.length
36 end
37
38 # Gives the current location in the `src`
39 fun current_location: Location do return new Location(line, line_offset)
40
41 # Advances in `src` until a non-whitespace character is encountered
42 protected fun ignore_whitespaces do
43 var srclen = _len
44 var p = _pos
45 if p >= srclen then return
46 var c = src[p]
47 while c.is_whitespace do
48 p += 1
49 if p >= srclen then break
50 if c == '\n' then
51 _line += 1
52 _line_start = p
53 end
54 c = src[p]
55 end
56 _pos = p
57 return
58 end
59
60 # Reads characters until pattern `s` is found
61 protected fun ignore_until(s: String): Int do
62 if s.length == 0 then return _pos
63 var srclen = _len
64 var p = _pos
65 if p >= srclen then return -1
66 loop
67 var c = s[0]
68 var src_c = src[p]
69 while src_c != c do
70 p += 1
71 if p >= srclen then
72 _pos = p
73 return -1
74 end
75 if src_c == '\n' then
76 line += 1
77 line_start= pos
78 end
79 src_c = src[p]
80 end
81 var relpos = p
82 var fnd = true
83 for i in s do
84 if relpos >= srclen then
85 fnd = false
86 break
87 end
88 if src[relpos] != i then
89 p += 1
90 fnd = false
91 break
92 end
93 relpos += 1
94 end
95 if fnd then
96 _pos = p
97 return p
98 end
99 end
100 end
101
102 # Ignores any printable character until a whitespace is encountered
103 protected fun ignore_until_whitespace: Int do
104 while not src[pos].is_whitespace do pos += 1
105 return pos
106 end
107
108 # Returns the current location as a `Location` object
109 protected fun hot_location: Location do return new Location(line, line_offset)
110 end
111
112 # Information about the location of an entity in a source document
113 class Location
114 # Line in which the element is described
115 var line: Int
116 # Offset in the line at which the element is positioned
117 var offset: Int
118
119 redef fun to_s do return "line {line}, position {offset}"
120 end