@@ -15,6 +15,19 @@ type TokenReader interface {
1515 ReadToken () (Token , error )
1616}
1717
18+ // ParseFlags is a bitset of any boolean flags that can be set for a Parser.
19+ type ParseFlags uint
20+
21+ func (f ParseFlags ) isSet (flags ParseFlags ) bool {
22+ return f & flags == flags
23+ }
24+
25+ const (
26+ // Whether to treat an end-of-line (newline) as a sentinel. This is the same as using
27+ // newlines instead of semicolons.
28+ ParseSentinelEOL ParseFlags = 1 << iota
29+ )
30+
1831// Parser consumes tokens from a TokenReader and constructs a codf *Document from it.
1932//
2033// The Document produced by the Parser is kept for the duration of the parser's lifetime, so it is
@@ -23,6 +36,8 @@ type Parser struct {
2336 doc * Document
2437 next tokenConsumer
2538
39+ flags ParseFlags
40+
2641 lastToken Token
2742 lastErr error
2843
@@ -49,6 +64,16 @@ func NewParser() *Parser {
4964 return p
5065}
5166
67+ // Flags returns the current ParseFlags for the receiver.
68+ func (p * Parser ) Flags () ParseFlags {
69+ return p .flags
70+ }
71+
72+ // SetFlags sets the ParseFlags for the receiver.
73+ func (p * Parser ) SetFlags (flags ParseFlags ) {
74+ p .flags = flags
75+ }
76+
5277func (p * Parser ) nextToken (tr TokenReader ) (tok Token , err error ) {
5378 tok , err = tr .ReadToken ()
5479 p .lastToken , p .lastErr = tok , err
@@ -107,7 +132,7 @@ func (p *Parser) ParseExpr(tr TokenReader) (ExprNode, error) {
107132 exp := exprParser {}
108133 p .ctx = []parseNode {& exp }
109134 p .parseErr = nil
110- p .next = skipWhitespace (p .parseStatement )
135+ p .next = p . skipInsignificantWhitespace (p .parseStatement )
111136 if err := p .Parse (tr ); err != nil {
112137 return nil , err
113138 }
@@ -220,7 +245,7 @@ func (p *Parser) beginSegment(tok Token) (tokenConsumer, error) {
220245 // Start statement
221246 stmt := & Statement {NameTok : & Literal {tok }}
222247 p .pushContext (stmt )
223- return skipWhitespace (p .parseStatement ), nil
248+ return p . skipInsignificantWhitespace (p .parseStatement ), nil
224249 }
225250 return nil , unexpected (tok , "expected statement or section name" )
226251}
@@ -236,11 +261,35 @@ func skipWhitespace(next tokenConsumer) (consumer tokenConsumer) {
236261 return consumer
237262}
238263
264+ func (p * Parser ) skipInsignificantWhitespace (next tokenConsumer ) (consumer tokenConsumer ) {
265+ if ! p .flags .isSet (ParseSentinelEOL ) {
266+ return skipWhitespace (next )
267+ }
268+ consumer = func (tok Token ) (tokenConsumer , error ) {
269+ if tok .Kind == TWhitespace && tok .Start .Line == tok .End .Line {
270+ return consumer , nil
271+ } else if tok .Kind == TComment {
272+ return consumer , nil
273+ }
274+ return next (tok )
275+ }
276+ return consumer
277+ }
278+
239279func (p * Parser ) parseStatementSentinel (tok Token ) (tokenConsumer , error ) {
240280 switch tok .Kind {
241281 case TEOF :
242282 return nil , p .closeError (tok )
243283
284+ case TWhitespace :
285+ if stmt , ok := p .context ().(* Statement ); ok {
286+ p .popContext ()
287+ stmt .EndTok = tok
288+ p .context ().(parentNode ).addChild (stmt )
289+ return p .beginSegment , nil
290+ }
291+ return nil , p .closeError (tok )
292+
244293 case TSemicolon :
245294 if stmt , ok := p .context ().(* Statement ); ok {
246295 p .popContext ()
@@ -257,7 +306,7 @@ func (p *Parser) parseStatementSentinel(tok Token) (tokenConsumer, error) {
257306 if err := p .context ().(segmentNode ).addExpr (ary ); err != nil {
258307 return nil , err
259308 }
260- return skipWhitespace (p .parseStatement ), nil
309+ return p . skipInsignificantWhitespace (p .parseStatement ), nil
261310 }
262311 return nil , p .closeError (tok )
263312
@@ -272,7 +321,7 @@ func (p *Parser) parseStatementSentinel(tok Token) (tokenConsumer, error) {
272321 if err := p .context ().(segmentNode ).addExpr (m ); err != nil {
273322 return nil , err
274323 }
275- return skipWhitespace (p .parseStatement ), nil
324+ return p . skipInsignificantWhitespace (p .parseStatement ), nil
276325 }
277326 return nil , p .closeError (tok )
278327
@@ -294,14 +343,14 @@ func (p *Parser) beginArray(tok Token) (tokenConsumer, error) {
294343 StartTok : tok ,
295344 Elems : []ExprNode {},
296345 })
297- return skipWhitespace (p .parseStatement ), nil
346+ return p . skipInsignificantWhitespace (p .parseStatement ), nil
298347}
299348
300349func (p * Parser ) beginMap (tok Token ) (tokenConsumer , error ) {
301350 m := newMapBuilder ()
302351 m .m .StartTok = tok
303352 p .pushContext (m )
304- return skipWhitespace (p .parseStatement ), nil
353+ return p . skipInsignificantWhitespace (p .parseStatement ), nil
305354}
306355
307356func (p * Parser ) parseStatement (tok Token ) (tokenConsumer , error ) {
@@ -327,7 +376,7 @@ func (p *Parser) parseStatement(tok Token) (tokenConsumer, error) {
327376 if err := p .context ().(segmentNode ).addExpr (& Literal {tok }); err != nil {
328377 return nil , err
329378 }
330- return skipWhitespace (p .parseStatement ), nil
379+ return p . skipInsignificantWhitespace (p .parseStatement ), nil
331380 }
332381
333382 return p .parseStatementSentinel (tok )
0 commit comments