@@ -51,32 +51,46 @@ when isMainModule:
5151 import " ../combparser/combparser"
5252 import lists
5353
54- proc charmatch (charsets: varargs [set [char ]]): StringParser [string ] =
55- (proc (input: string ): Maybe [(string , string ), string ] =
56- var pos = 0
57- for c in input:
58- for s in charsets:
59- if c in s: pos += 1
60- if pos > 0 :
61- Just [(string , string ), string ]((input[0 .. pos], input[(pos + 1 ) .. input.len]))
62- else :
63- Nothing [(string , string ), string ](`pos` & " : Couldn't match regex \" " & `regexStr` & " \" " , input)
64- )
54+ macro charmatch (charset: set [char ]): untyped =
55+ let pos = lineInfo (callsite ())
56+ result = quote do :
57+ (proc (input: string ): Maybe [(string , string ), string ] =
58+ var pos = 0
59+ for c in input:
60+ if c in `charset`: pos += 1
61+ else : break
62+ if pos > 0 :
63+ Just [(string , string ), string ]((input[0 .. pos- 1 ], input[pos .. input.len]))
64+ else :
65+ Nothing [(string , string ), string ](`pos` & " : Couldn't match characters \" " & (if `charset` == Whitespace : " Whitespace" else : $ `charset`) & " \" " , input)
66+ )
6567
68+ macro allbut (but: string ): untyped =
69+ let pos = lineInfo (callsite ())
70+ result = quote do :
71+ (proc (input: string ): Maybe [(string , string ), string ] =
72+ var pos = input.find (`but`)
73+ if pos == - 1 :
74+ pos = input.len
75+ if pos > 0 :
76+ Just [(string , string ), string ]((input[0 .. pos- 1 ], input[pos .. input.len]))
77+ else :
78+ Nothing [(string , string ), string ](`pos` & " : All-but \" " & `but` & " \" failed" , input)
79+ )
6680
6781 proc ignorefirst [T](first: StringParser [string ], catch: StringParser [T]): StringParser [T] =
6882 (first + catch).map (proc (input: tuple [f1: string , f2: T]): T = input.f2) / catch
6983
7084 proc ignorelast [T](catch: StringParser [T], last: StringParser [string ]): StringParser [T] =
7185 (catch + last).map (proc (input: tuple [f1: T, f2: string ]): T = input.f1) / catch
7286
87+ proc ignoresides [T](first: StringParser [string ], catch: StringParser [T], last: StringParser [string ]): StringParser [T] =
88+ ignorefirst (first, catch).ignorelast (last)
89+
7390 proc andor (first, last: StringParser [string ]): StringParser [string ] =
7491 (first + last).map (proc (input: tuple [f1, f2: string ]): string = input.f1 & input.f2) /
7592 (first / last)
7693
77- proc ws (value: string ): StringParser [string ] =
78- regex (r " \s* " & value & r " \s* " )
79-
8094 proc combine (list: seq [string ], sep: string ): string =
8195 result = " "
8296 for entry in list:
@@ -86,49 +100,97 @@ when isMainModule:
86100 proc combine (list: seq [string ]): string =
87101 list.combine (" " )
88102
89- proc combine (t: tuple [f1, f2: string ]): string = t.f1 & t.f2
103+ proc combine (t: tuple [f1, f2: string ]): string =
104+ if t.f1 == nil :
105+ t.f2
106+ elif t.f2 == nil :
107+ t.f1
108+ else :
109+ t.f1 & t.f2
90110
91- proc combine [T](t: tuple [f1: T, f2: string ]): string = t.f1.combine () & t.f2
111+ proc combine [T](t: tuple [f1: T, f2: string ]): string =
112+ if t.f2 == nil :
113+ t.f1.combine ()
114+ else :
115+ t.f1.combine () & t.f2
92116
93- proc combine [T](t: tuple [f1: string , f2: T]): string = t.f1 & t.f2.combine ()
117+ proc combine [T](t: tuple [f1: string , f2: T]): string =
118+ if t.f1 == nil :
119+ t.f2.combine ()
120+ else :
121+ t.f1 & t.f2.combine ()
94122
95123 proc combine [T, U](t: tuple [f1: T, f2: U]): string = t.f1.combine () & t.f2.combine ()
96124
97- proc endcomment (): StringParser [string ] = regex ( r " \s*//.*\s* " ). repeat ( 1 ) .map (combine)
125+ proc combine [T, U](t: tuple [f1: T, f2: StringParser [U]]): string = t.f1. combine () & t.f2 .map (combine)
98126
99- proc inlinecomment (): StringParser [string ] = regex (r " \s*/\*.*\*/\s* " ).repeat (1 ).map (combine)
127+ proc combine [T, U](t: tuple [f1: StringParser [T], f2: StringParser [U]]): string = t.f1.map (combine) & t.f2.map (combine)
128+
129+ proc combine [T](list: seq [T]): string =
130+ result = " "
131+ for entry in list:
132+ result = result & entry.combine ()
133+
134+ proc optwhitespace [T](parser: StringParser [T]): StringParser [T] =
135+ ignorefirst (charmatch (Whitespace ), parser).ignorelast (charmatch (Whitespace ))
136+
137+ proc ws (value: string ): StringParser [string ] =
138+ optwhitespace (s (value))
139+
140+ proc endcomment (): StringParser [string ] =
141+ ignorefirst (charmatch (Whitespace ), s (" //" ) + allbut (" \n " ) + s (" \n " )).repeat (1 ).map (combine)
142+
143+ proc inlinecomment (): StringParser [string ] =
144+ ignorefirst (charmatch (Whitespace ), s (" /*" ) + allbut (" */" ) + s (" */" )).repeat (1 ).map (combine)
100145
101146 proc comment (): StringParser [string ] = andor (endcomment (), inlinecomment ()).repeat (1 ).map (combine)
102147
103148 proc endstatement (): StringParser [string ] =
104149 ignorefirst (inlinecomment (), ws (" ;" )).ignorelast (comment ())
105150
106151 proc str (): StringParser [string ] =
107- ignorefirst (inlinecomment (), regex ( r " \s*\ "" [^ "" ]* \"" \s* " )).map (
108- proc (n: string ): string =
109- n. strip ()[ 1 ..^ 2 ]
152+ ignorefirst (inlinecomment (), optwhitespace ( s ( " \" " ) + allbut ( " \" " ) + s ( " \" " ) )).map (
153+ proc (n: auto ): string =
154+ n[ 0 ][ 1 ]
110155 ).ignorelast (comment ())
111156
112- proc number (): StringParser [string ] = regex (r " \s*[0-9]+\s* " ).map (proc (n: string ): string =
113- n.strip ())
157+ proc number (): StringParser [string ] =
158+ # n.strip())
159+ optwhitespace (charmatch (Digits ))
114160
115161 proc strip (input: string ): string =
116162 input.strip (true , true )
117163
118164 proc enumname (): StringParser [string ] =
119- ignorefirst (comment (), regex (r " \s*[A-Z]*\s* " )).ignorelast (comment ()).map (strip)
165+ ignorefirst (comment (),
166+ optwhitespace (charmatch ({'A' .. 'Z' }))
167+ ).ignorelast (comment ())
120168
121169 proc token (): StringParser [string ] =
122- ignorefirst (comment (), regex (r " \s*[a-z][a-zA-Z0-9_]*\s* " )).ignorelast (comment ()).map (strip)
170+ ignorefirst (comment (),
171+ (
172+ ignorefirst (charmatch (Whitespace ), charmatch ({'a' .. 'z' })) +
173+ ignorelast (optional (charmatch ({'a' .. 'z' , 'A' .. 'Z' , '0' .. '9' , '_' })), charmatch (Whitespace ))
174+ ).map (combine)
175+ ).ignorelast (comment ())
123176
124177 proc token (name: string ): StringParser [string ] =
125178 ignorefirst (comment (), ws (name)).ignorelast (comment ()).map (strip)
126179
127180 proc class (): StringParser [string ] =
128- ignorefirst (comment (), regex (r " \s*[A-Z][a-zA-Z0-9_]*\s* " )).ignorelast (comment ()).map (strip)
181+ ignorefirst (comment (),
182+ (
183+ ignorefirst (charmatch (Whitespace ), charmatch ({'A' .. 'Z' })) +
184+ ignorelast (optional (charmatch ({'a' .. 'z' , 'A' .. 'Z' , '0' .. '9' , '_' })), charmatch (Whitespace ))
185+ ).map (combine)
186+ ).ignorelast (comment ())
129187
130188 proc typespecifier (): StringParser [string ] =
131- ignorefirst (comment (), regex (r " \s*[A-Za-z0-9_\.]*\s* " )).ignorelast (comment ()).map (strip)
189+ ignorefirst (comment (),
190+ (
191+ optwhitespace (charmatch ({'a' .. 'z' , 'A' .. 'Z' , '0' .. '9' , '_' , '.' }))
192+ )
193+ ).ignorelast (comment ())
132194
133195 type
134196 ReservedType = enum
0 commit comments