diff options
Diffstat (limited to 'test/counting1.lm')
-rw-r--r-- | test/counting1.lm | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/test/counting1.lm b/test/counting1.lm new file mode 100644 index 00000000..bd0154ec --- /dev/null +++ b/test/counting1.lm @@ -0,0 +1,91 @@ + +# +# 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 start +{ + # Ignore whitespace. + ignore /rl_ws/ + + # Tokens. + token id /rl_id/ + token number /rl_num/ +} + +# +# Global Data +# + +global int target + +# +# Productions +# + + +def get_target + [number] + { + match lhs [Number:number] + target = Number.data.atoi() + } + +# Arbitrary item. +def item + [number] +| [id] + +# Type definition for the count_items nonterminal. +def count_items + int count + + # List production one. The condition stops the + # greedy list when it has gone too far. + [count_items item] + { + # Pass up the data + lhs.count = r1.count + 1 + if lhs.count > target { + reject + } + } + + # List production two, the base. +| [] + { + lhs.count = 0 + } + +# 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] + { + if r2.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' ) + + int i = 1 + for Item:item in Items { + print( ' item ', i, ': ', Item, '\n' ) + i = i + 1 + } + } + } |