summaryrefslogtreecommitdiff
path: root/test/counting3.lm
blob: ada6c1d94976f987ab8c2494468514ed4266e778 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
context counting
{
	#
	# Regular Definitions
	#
	rl rl_ws /[ \t\n\r\v]+/
	rl rl_id /[a-zA-Z_][a-zA-Z0-9_]*/
	rl rl_num /[0-9]+/

	#
	# Tokens
	#

	lex
		# Ignore whitespace.
		ignore /rl_ws/

		literal ';'

		# Tokens. 
		token id /rl_id/
		token number /rl_num/
	end

	#
	# Global Data
	#

	target: int
	count: int

	#
	# Productions
	#

	def get_target 
		[number]
		{
			count = 0
			target = r1.data.atoi()
			print( 'target: ' target '\n' )
		}

	# Arbitrary item.
	def item 
		[number]
	|	[id]

	def count_items 
		[one_item count_items]
	|	[]

	def one_item 
		[item]
		{
			count = count + 1
			if count > target {
				reject
			} 
			print( 'ITEM\n' )
		}


	# Wrapper which prevents short lists from getting through if the parser
	# encounters an error and needs to backtrack over counted list.
	def counted_list 
		[get_target count_items]
		{
			print( 'trying: ' count ' for: ' target '\n' )
			if count < target {
				reject
			}
		}


	def start 
		[counted_list*]
		{

			for List: counted_list in lhs {
				match List [Count: number Items: count_items]
				print( 'num items: ' Count.data.atoi() '\n' )

				i: int = 1
				for Item: item in Items {
					print( '  item ' i ': ' ^Item '\n' )
					i = i + 1
				}
			}
			print( '*** SUCCESS ***\n' )
		}
}

cons Counting: counting[]
parse counting::start(Counting)[ stdin ]