simplekey.cpp 2.75 KB
Newer Older
Jesse Beder's avatar
Jesse Beder committed
1
2
3
4
5
6
7
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
#include "exp.h"

namespace YAML
{
8
9
	Scanner::SimpleKey::SimpleKey(int pos_, int line_, int column_, int flowLevel_)
		: pos(pos_), line(line_), column(column_), flowLevel(flowLevel_), required(false), pMapStart(0), pKey(0)
Jesse Beder's avatar
Jesse Beder committed
10
11
12
13
14
15
	{
	}

	void Scanner::SimpleKey::Validate()
	{
		if(pMapStart)
16
			pMapStart->status = TS_VALID;
Jesse Beder's avatar
Jesse Beder committed
17
		if(pKey)
18
			pKey->status = TS_VALID;
Jesse Beder's avatar
Jesse Beder committed
19
20
21
22
23
	}

	void Scanner::SimpleKey::Invalidate()
	{
		if(required)
24
			throw ParserException(line, column, "required simple key not found");
Jesse Beder's avatar
Jesse Beder committed
25
26

		if(pMapStart)
27
			pMapStart->status = TS_INVALID;
Jesse Beder's avatar
Jesse Beder committed
28
		if(pKey)
29
			pKey->status = TS_INVALID;
Jesse Beder's avatar
Jesse Beder committed
30
31
32
33
34
35
36
	}

	// InsertSimpleKey
	// . Adds a potential simple key to the queue,
	//   and saves it on a stack.
	void Scanner::InsertSimpleKey()
	{
37
		SimpleKey key(INPUT.pos(), INPUT.line, INPUT.column, m_flowLevel);
Jesse Beder's avatar
Jesse Beder committed
38
39

		// first add a map start, if necessary
40
		key.pMapStart = PushIndentTo(INPUT.column, false);
Jesse Beder's avatar
Jesse Beder committed
41
		if(key.pMapStart)
42
			key.pMapStart->status = TS_UNVERIFIED;
Jesse Beder's avatar
Jesse Beder committed
43
44
45
//		else
//			key.required = true;	// TODO: is this correct?

46
		// then add the (now unverified) key
47
		key.pKey = new Token(TT_KEY, INPUT.line, INPUT.column);
48
		key.pKey->status = TS_UNVERIFIED;
Jesse Beder's avatar
Jesse Beder committed
49
50
51
52
53
		m_tokens.push(key.pKey);

		m_simpleKeys.push(key);
	}

54
	// VerifySimpleKey
Jesse Beder's avatar
Jesse Beder committed
55
56
	// . Determines whether the latest simple key to be added is valid,
	//   and if so, makes it valid.
57
	bool Scanner::VerifySimpleKey()
Jesse Beder's avatar
Jesse Beder committed
58
	{
59
		m_isLastKeyValid = false;
Jesse Beder's avatar
Jesse Beder committed
60
		if(m_simpleKeys.empty())
61
			return m_isLastKeyValid;
Jesse Beder's avatar
Jesse Beder committed
62
63
64

		// grab top key
		SimpleKey key = m_simpleKeys.top();
65
66
67
68
69

		// only validate if we're in the correct flow level
		if(key.flowLevel != m_flowLevel)
			return false;

Jesse Beder's avatar
Jesse Beder committed
70
71
72
73
74
75
76
77
78
79
80
		m_simpleKeys.pop();

		bool isValid = true;

		// needs to be followed immediately by a value
		if(m_flowLevel > 0 && !Exp::ValueInFlow.Matches(INPUT))
			isValid = false;
		if(m_flowLevel == 0 && !Exp::Value.Matches(INPUT))
			isValid = false;

		// also needs to be less than 1024 characters and inline
81
		if(INPUT.line != key.line || INPUT.pos() - key.pos > 1024)
Jesse Beder's avatar
Jesse Beder committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
			isValid = false;

		// invalidate key
		if(isValid)
			key.Validate();
		else
			key.Invalidate();

		// In block style, remember that we've pushed an indent for this potential simple key (if it was starting).
		// If it was invalid, then we need to pop it off.
		// Note: we're guaranteed to be popping the right one (i.e., there couldn't have been anything in
		//       between) since keys have to be inline, and will be invalidated immediately on a newline.
		if(!isValid && m_flowLevel == 0)
			m_indents.pop();

97
		m_isLastKeyValid = isValid;
Jesse Beder's avatar
Jesse Beder committed
98
99
100
		return isValid;
	}

101
	void Scanner::VerifyAllSimpleKeys()
Jesse Beder's avatar
Jesse Beder committed
102
103
	{
		while(!m_simpleKeys.empty())
104
			VerifySimpleKey();
Jesse Beder's avatar
Jesse Beder committed
105
106
	}
}