summaryrefslogtreecommitdiff
path: root/test/context2.lm
blob: e04354a8364a921e58807ae93ffb5820ec5b8179 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
##### LM #####
context ruby_here

	rl ident_pattern /[a-zA-Z_][a-zA-Z_0-9]*/
	rl number_pattern /[0-9]+/

	lex
		ignore /[ \t\n]+/
		token id /ident_pattern/
		token number /number_pattern/
		literal `<< `* `, `( `) `!
	end

	HereId: str

	token rest_of_line /[^\n]*'\n'/

	lex
		ignore /[ \t\n]+/
		token here_id
			HereData: here_data
			/ident_pattern/
			{
				# Take the text of the here_id from the input stream.
				HereId = input.pull( match_length )

				# Get the data up to the rest of the line.
				parse_stop ROL: rest_of_line(ctx)[ input ]

				# Parse the heredoc data.
				parse_stop HereData: here_data(ctx)[ input ]

				# Push the rest-of-line data back to the input stream.
				input.push( $ROL )

				# Send the here_id token. Attach the heredoc data as an attribute.
				input.push( make_token( typeid<here_id> HereId HereData ) )
			}
	end

	lex
		token here_close_id 
			/ ident_pattern '\n' /
			{
				if match_text == HereId + '\n' {
					input.push( make_token( 
						typeid<here_close_id>
						input.pull( match_length ) ) )
				}
				else 
					input.push( make_token( typeid<here_line> input.pull(match_length) ) )
			}

		token here_line
			/ [^\n]* '\n' /
	end

	def here_data
		[here_line* here_close_id]

	def heredoc
		[`<< here_id]

	def primary
		[id]
	|	[number]
	|	[heredoc]

	def arglist
		[primary arglist_more*]

	def arglist_more
		[`, primary]

	def call
		[id `( arglist? `)]

	def statement
		[primary]
	|	[call]

	token foobar /any+/

	def item
		[statement `!]
	|	[foobar]

	def start 
		[item*]

end # ruby_here

CTX: ruby_here = cons ruby_here []

parse S: ruby_here::start( CTX ) [ stdin ]
print_xml(S)
print('\n')
##### IN #####
print( <<DATA1, more, <<DATA2, 99 )
"&^#(@ almost
!arbitrary text!
DATA1
hello
world
DATA2
!
print( <<DATA1, more, <<DATA2, 99 )
"&^#(@ almost
!arbitrary text!
DATA1
hello
world
DATA2
# error here
##### EXP #####
<ruby_here::start><ruby_here::_repeat_item><ruby_here::item><ruby_here::statement><ruby_here::call><ruby_here::id>print</ruby_here::id><ruby_here::_literal_000d>(</ruby_here::_literal_000d><ruby_here::_opt_arglist><ruby_here::arglist><ruby_here::primary><ruby_here::heredoc><ruby_here::_literal_0007>&lt;&lt;</ruby_here::_literal_0007><ruby_here::here_id>DATA1</ruby_here::here_id></ruby_here::heredoc></ruby_here::primary><ruby_here::_repeat_arglist_more><ruby_here::arglist_more><ruby_here::_literal_000b>,</ruby_here::_literal_000b><ruby_here::primary><ruby_here::id>more</ruby_here::id></ruby_here::primary></ruby_here::arglist_more><ruby_here::arglist_more><ruby_here::_literal_000b>,</ruby_here::_literal_000b><ruby_here::primary><ruby_here::heredoc><ruby_here::_literal_0007>&lt;&lt;</ruby_here::_literal_0007><ruby_here::here_id>DATA2</ruby_here::here_id></ruby_here::heredoc></ruby_here::primary></ruby_here::arglist_more><ruby_here::arglist_more><ruby_here::_literal_000b>,</ruby_here::_literal_000b><ruby_here::primary><ruby_here::number>99</ruby_here::number></ruby_here::primary></ruby_here::arglist_more></ruby_here::_repeat_arglist_more></ruby_here::arglist></ruby_here::_opt_arglist><ruby_here::_literal_000f>)</ruby_here::_literal_000f></ruby_here::call></ruby_here::statement><ruby_here::_literal_0011>!</ruby_here::_literal_0011></ruby_here::item><ruby_here::item><ruby_here::foobar>print( &lt;&lt;DATA1, more, &lt;&lt;DATA2, 99 )
"&amp;^#(@ almost
!arbitrary text!
DATA1
hello
world
DATA2
# error here
</ruby_here::foobar></ruby_here::item></ruby_here::_repeat_item></ruby_here::start>