diff options
author | Adrian Thurston <thurston@complang.org> | 2015-01-23 17:01:07 -0500 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-01-23 17:01:07 -0500 |
commit | 72a8d8a9dd19453db5764a8c11e8f5e1c5a4f351 (patch) | |
tree | 45f1f8142fdfe36ef19013f2d0a6d8227717545d | |
parent | 92da67efa0e2d0f6c7858bd35d4e1bbad61d1e3b (diff) | |
download | colm-72a8d8a9dd19453db5764a8c11e8f5e1c5a4f351.tar.gz |
revert "moved away the larger grammars for known langs"
This reverts commit 04a32202c1aae4a1c69539ce7dd21dff3a93c7fb.
-rw-r--r-- | test/binary1.lm | 1938 | ||||
-rw-r--r-- | test/generate1.lm | 773 | ||||
-rw-r--r-- | test/generate2.lm | 223 | ||||
-rw-r--r-- | test/lookup1.lm | 2594 |
4 files changed, 5528 insertions, 0 deletions
diff --git a/test/binary1.lm b/test/binary1.lm new file mode 100644 index 00000000..d84790c6 --- /dev/null +++ b/test/binary1.lm @@ -0,0 +1,1938 @@ + +context binary + +# Used for most of the grammar. +token octet /any/ + +# Filled in during the parsing of resource records. Determine what RR_UNKNOWN +# translates to. +rr_type_value: int +rr_class_value: int + +# Tokens generated from RR_UNKNOWN. Used to pick the kind +# of resource record to attempt to parse. +token RR_A // # 1 a host address +token RR_NS // # 2 an authoritative name server +token RR_MD // # 3 a mail destination (Obsolete - use MX) +token RR_MF // # 4 a mail forwarder (Obsolete - use MX) +token RR_CNAME // # 5 the canonical name for an alias +token RR_SOA // # 6 marks the start of a zone of authority +token RR_MB // # 7 a mailbox domain name (EXPERIMENTAL) +token RR_MG // # 8 a mail group member (EXPERIMENTAL) +token RR_MR // # 9 a mail rename domain name (EXPERIMENTAL) +token RR_NULL // # 10 a null RR (EXPERIMENTAL) +token RR_WKS // # 11 a well known service description +token RR_PTR // # 12 a domain name pointer +token RR_HINFO // # 13 host information +token RR_MINFO // # 14 mailbox or mail list information +token RR_MX // # 15 mail exchange +token RR_TXT // # 16 text strings + +token RR_UNKNOWN + /''/ + { + id: int = typeid<RR_UNKNOWN> + if rr_type_value == 1 + id = typeid<RR_A> + elsif rr_type_value == 2 + id = typeid<RR_NS> + elsif rr_type_value == 5 + id = typeid<RR_CNAME> + elsif rr_type_value == 12 + id = typeid<RR_PTR> + elsif rr_type_value == 15 + id = typeid<RR_MX> + elsif rr_type_value == 16 + id = typeid<RR_TXT> + + input->push( make_token( id '' ) ) + } + +# Convert two octets in network order into an unsigned 16 bit value. +int network_uord16( o1: octet o2: octet ) +{ + return o1.data.uord8() * 256 + o2.data.uord8() +} + + +def message + [header questions answers authorities additionals] + +question_count: int +answer_count: int +authority_count: int +additional_count: int + +# Message Header +# +# 1 1 1 1 1 1 +# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | ID | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | QDCOUNT | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | ANCOUNT | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | NSCOUNT | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | ARCOUNT | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +def header + [header_id header_fields count count count count] + { + question_count = r3.count + answer_count = r4.count + authority_count = r5.count + additional_count = r6.count + } + +def header_id + [octet octet] + +def header_fields + [octet octet] + +def count + count: int + [octet octet] + { + lhs.count = network_uord16( r1 r2 ) + } + +# +# Counting Primitives +# +# Uses a stack of lengths. Using a stack allows for counted lists to be +# nested. As the list is consumed it brings the count down to zero. To use +# it, push a new count value to the list and include it in a +# right-recursive list like so: +# +# def LIST +# [count_inc ITEM LIST] +# [count_end] +# end +# + +struct int_el + Int: int + + list_el el +end + +CL: list<int_el> + +int start_list( count: int ) +{ + IntEl: int_el = new int_el + IntEl->Int = count + CL->push( IntEl ) +} + +def count_inc + [] + { + if top( CL ) == 0 { + reject + } else { + Int: int = pop( CL ) + Int = Int - 1 + push( CL Int ) + } + } + +def count_end + [] + { + if top( CL ) != 0 { + reject + } else { + CL->pop() + } + } + +# +# Octet List +# + +# General octet list. Length must be set to use this. +def octet_list + [count_inc octet octet_list] +| [count_end] + + +# +# Names +# + +def name + [name_part* name_end] + +# Name part lists are terminated by a zero length or a pointer. +def name_end + # Zero length ending + [octet] + { + val: int = r1.data.uord8() + if val != 0 { + reject + } + } + + # Pointer ending + # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + # | 1 1| OFFSET | + # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| [octet octet] + { + val: int = r1.data.uord8() + if val < 64 { + reject + } + } + +# +# Get some number of bytes. +# + +# How many to get +nbytes: int + +# We use this token to eliminate the lookahead that would be needed to +# cause a reduce of part_len. This forces whatever comes before nbytes to +# be reduced before nbytes_data token is fetched from the scanner. We need +# this because nbytes_data depends on the nbytes in the context and we need +# to ensure that it is set. +token nb_empty /''/ + +# Fetch nbytes bytes. +token nbytes_data + /''/ + { + input->push( make_token( typeid<nbytes_data> input->pull(nbytes) ) ) + } + +def nbytes + [nb_empty nbytes_data] + +def name_part + [part_len nbytes] + + +def part_len + [octet] + { + # A name part list is terminated either by a zero length or a pointer, + # which must have the two high bits set. + count: int = r1.data.uord8() + if count == 0 || count >= 64 { + reject + } else { + # Set the number of bytes to get for the name part. + nbytes = count + } + } + +# +# Resource Records +# + +# 1 1 1 1 1 1 +# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | | +# / / +# / NAME / +# | | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | TYPE | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | CLASS | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | TTL | +# | | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | RDLENGTH | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| +# / RDATA / +# / / +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +def resource_record + [name rr_type rr_class ttl rdlength rdata] + +def rr_type + [octet octet] + { + rr_type_value = network_uord16( r1 r2 ) + } + +def rr_class + value: int + [octet octet] + { + rr_class_value = network_uord16( r1 r2 ) + } + +def ttl + [octet octet octet octet] + +token rdata_bytes + /''/ + { + input->push( make_token( typeid<rdata_bytes> input->pull(rdata_length) ) ) + } + +def rdlength + [octet octet] + { + rdata_length = network_uord16( r1 r2 ) + } + +rdata_length: int + +def rdata + [RR_UNKNOWN rdata_bytes] +| [RR_A address] +| [RR_NS name] +| [RR_CNAME name] +| [RR_PTR name] +| [RR_MX octet octet name] +| [RR_TXT rdata_bytes] + + +# +# Address +# +def address [octet octet octet octet] + +# +# List of Questions +# + +def questions + [load_question_count question_list] + +def load_question_count + [] + { + start_list( question_count ) + } + +def question_list + [count_inc question question_list] +| [count_end] + +# +# Question +# + +# 1 1 1 1 1 1 +# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | | +# / QNAME / +# / / +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | QTYPE | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | QCLASS | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +def question + [name qtype qclass] + +def qtype + [octet octet] + +def qclass + [octet octet] + +# +# List of Answers +# + +def answers + [load_answer_count answer_list] + +def load_answer_count + [] + { + start_list( answer_count ) + } + +def answer_list + [count_inc answer answer_list] +| [count_end] + +# +# Answer +# + +def answer + [resource_record] + +# +# List of Authorities +# + +def authorities + [load_authority_count authority_list] + +def load_authority_count + [] + { + start_list( authority_count ) + } + +def authority_list + [count_inc authority authority_list] +| [count_end] + +# +# Authority +# + +def authority + [resource_record] + +# +# List of Additionals +# + +def additionals + [load_additional_count additional_list] + +def load_additional_count + [] + { + start_list( additional_count ) + } + +def additional_list + [count_inc additional additional_list] +| [count_end] + +# +# Additional +# + +def additional + [resource_record] + + +def start + [message*] + +# +# Grammar End. +# + +int print_RR_UNKNOWN( s: start ) +{ + for I:rdata in s { + if match I [u:RR_UNKNOWN rdata_bytes] { + print( 'UNKNOWN TYPE\n' ) + } + } +} + +int print_RR_A( s: start ) +{ + for I:rdata in s { + if match I [RR_A o1:octet o2:octet o3:octet o4:octet] { + print( 'RR_A: ' o1.data.uord8() '.' o2.data.uord8() '.' + o3.data.uord8() '.' o4.data.uord8() '\n' ) + } + } +} + +struct name_map_el + Name: name + map_el<int> el +end + +int print_name( n: name m: map<int name_map_el> ) +{ + for P: name_part in n { + match P [part_len D:nbytes] + print( D '.' ) + } + + for E:name_end in n { + if match E [o1:octet o2:octet] { + val: int = (o1.data.uord8() - 192) * 256 + o2.data.uord8() + print( '[' val ']' ) + nameInMap: name_map_el = m->find( val ) + print_name( nameInMap->Name m ) + } + } +} + +int print_all_names( s: start ) +{ + for M: message in s { + m: map<int name_map_el> = new map<int name_map_el> + + O: octet = octet in M + + for N: name in M { + match N [name_part* E:name_end] + + for NP: name_part* in N { + if match NP [L: octet nbytes name_part*] { + messageOffset: int = L.pos - O.pos + construct n: name [NP E] + El: name_map_el = new name_map_el + El->key = messageOffset + El->Name = n + m->insert( El ) + } + } + } + + for I: name in M { + print_name( I m ) + print( '\n' ) + } + } +} + +end # binary + +Binary: binary = new binary +Binary->CL = new list<binary::int_el> + +int top( L: list<binary::int_el> ) +{ + Top: binary::int_el = L->top + return Top->Int +} + +int pop( L: list<binary::int_el> ) +{ + Top: binary::int_el = L->pop() + return Top->Int +} + +int push( L: list<binary::int_el> Int: int ) +{ + Top: binary::int_el = new binary::int_el + Top->Int = Int + L->push( Top ) +} + +parse S: binary::start(Binary) [ stdin ] +print_all_names( S ) +print( '*** SUCCESS ***\n' ) +##### EXP ##### +www.google.ca. +www.google.ca. +[12]www.google.ca. +www.google.com. +[43]www.google.com. +www.l.[47]google.com. +[71]www.l.[47]google.com. +[75]l.[47]google.com. +a.[75]l.[47]google.com. +[75]l.[47]google.com. +d.[75]l.[47]google.com. +[75]l.[47]google.com. +e.[75]l.[47]google.com. +[75]l.[47]google.com. +f.[75]l.[47]google.com. +[75]l.[47]google.com. +g.[75]l.[47]google.com. +[75]l.[47]google.com. +b.[75]l.[47]google.com. +[107]a.[75]l.[47]google.com. +[123]d.[75]l.[47]google.com. +[139]e.[75]l.[47]google.com. +[155]f.[75]l.[47]google.com. +[171]g.[75]l.[47]google.com. +[187]b.[75]l.[47]google.com. +clients1.google.ca. +clients1.google.ca. +[12]clients1.google.ca. +clients.l.google.com. +[48]clients.l.google.com. +[56]l.google.com. +e.[56]l.google.com. +[56]l.google.com. +f.[56]l.google.com. +[56]l.google.com. +g.[56]l.google.com. +[56]l.google.com. +b.[56]l.google.com. +[56]l.google.com. +a.[56]l.google.com. +[56]l.google.com. +d.[56]l.google.com. +[98]e.[56]l.google.com. +[114]f.[56]l.google.com. +[130]g.[56]l.google.com. +[146]b.[56]l.google.com. +[162]a.[56]l.google.com. +[178]d.[56]l.google.com. +en-us.fxfeeds.mozilla.com. +en-us.fxfeeds.mozilla.com. +[12]en-us.fxfeeds.mozilla.com. +fxfeeds.mozilla.org. +[55]fxfeeds.mozilla.org. +[63]mozilla.org. +ns1.[63]mozilla.org. +[63]mozilla.org. +ns2.[63]mozilla.org. +[63]mozilla.org. +ns3.[63]mozilla.org. +[104]ns1.[63]mozilla.org. +[122]ns2.[63]mozilla.org. +[140]ns3.[63]mozilla.org. +fxfeeds.mozilla.com. +fxfeeds.mozilla.com. +[12]fxfeeds.mozilla.com. +fxfeeds.mozilla.org. +[49]fxfeeds.mozilla.org. +[57]mozilla.org. +ns2.[57]mozilla.org. +[57]mozilla.org. +ns3.[57]mozilla.org. +[57]mozilla.org. +ns1.[57]mozilla.org. +[98]ns2.[57]mozilla.org. +[116]ns3.[57]mozilla.org. +[134]ns1.[57]mozilla.org. +newsrss.bbc.co.uk. +newsrss.bbc.co.uk. +[12]newsrss.bbc.co.uk. +newsrss.bbc.net.uk. +[47]newsrss.bbc.net.uk. +[55]bbc.net.uk. +ns0.thdo.bbc.co.[63]uk. +[55]bbc.net.uk. +ns0.rbsov.[104]bbc.co.[63]uk. +[95]ns0.thdo.bbc.co.[63]uk. +[125]ns0.rbsov.[104]bbc.co.[63]uk. +news.google.ca. +news.google.ca. +[12]news.google.ca. +news.google.com. +[44]news.google.com. +news.l.[49]google.com. +[73]news.l.[49]google.com. +[78]l.[49]google.com. +d.[78]l.[49]google.com. +[78]l.[49]google.com. +e.[78]l.[49]google.com. +[78]l.[49]google.com. +f.[78]l.[49]google.com. +[78]l.[49]google.com. +g.[78]l.[49]google.com. +[78]l.[49]google.com. +b.[78]l.[49]google.com. +[78]l.[49]google.com. +a.[78]l.[49]google.com. +[110]d.[78]l.[49]google.com. +[126]e.[78]l.[49]google.com. +[142]f.[78]l.[49]google.com. +[158]g.[78]l.[49]google.com. +[174]b.[78]l.[49]google.com. +[190]a.[78]l.[49]google.com. +nt3.ggpht.com. +nt3.ggpht.com. +[12]nt3.ggpht.com. +news.l.google.com. +[43]news.l.google.com. +[48]l.google.com. +f.[48]l.google.com. +[48]l.google.com. +g.[48]l.google.com. +[48]l.google.com. +b.[48]l.google.com. +[48]l.google.com. +a.[48]l.google.com. +[48]l.google.com. +d.[48]l.google.com. +[48]l.google.com. +e.[48]l.google.com. +[90]f.[48]l.google.com. +[106]g.[48]l.google.com. +[122]b.[48]l.google.com. +[138]a.[48]l.google.com. +[154]d.[48]l.google.com. +[170]e.[48]l.google.com. +csi.gstatic.com. +csi.gstatic.com. +[12]csi.gstatic.com. +csi.l.google.com. +[45]csi.l.google.com. +[49]l.google.com. +d.[49]l.google.com. +[49]l.google.com. +e.[49]l.google.com. +[49]l.google.com. +f.[49]l.google.com. +[49]l.google.com. +g.[49]l.google.com. +[49]l.google.com. +b.[49]l.google.com. +[49]l.google.com. +a.[49]l.google.com. +[91]d.[49]l.google.com. +[107]e.[49]l.google.com. +[123]f.[49]l.google.com. +[139]g.[49]l.google.com. +[155]b.[49]l.google.com. +[171]a.[49]l.google.com. +www.nytimes.com. +www.nytimes.com. +[12]www.nytimes.com. +nytimes.com. +nydns1.about.[57]com. +[49]nytimes.com. +ns1t.[49]nytimes.com. +[49]nytimes.com. +nydns2.[79]about.[57]com. +[72]nydns1.about.[57]com. +[99]ns1t.[49]nytimes.com. +[118]nydns2.[79]about.[57]com. +graphics8.nytimes.com. +graphics8.nytimes.com. +[12]graphics8.nytimes.com. +graphics478.nytimes.com.edgesuite.net. +[51]graphics478.nytimes.com.edgesuite.net. +a1116.x.akamai.[85]net. +[102]a1116.x.akamai.[85]net. +[102]a1116.x.akamai.[85]net. +[108]x.akamai.[85]net. +n0x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n1x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n6x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n3x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n2x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n7x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n5x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n8x.[110]akamai.[85]net. +[108]x.akamai.[85]net. +n4x.[110]akamai.[85]net. +[163]n0x.[110]akamai.[85]net. +[181]n1x.[110]akamai.[85]net. +[199]n6x.[110]akamai.[85]net. +[217]n3x.[110]akamai.[85]net. +[235]n2x.[110]akamai.[85]net. +[253]n7x.[110]akamai.[85]net. +[271]n5x.[110]akamai.[85]net. +[289]n8x.[110]akamai.[85]net. +[307]n4x.[110]akamai.[85]net. +timespeople.nytimes.com. +timespeople.nytimes.com. +[12]timespeople.nytimes.com. +nytimes.com. +nydns2.about.[65]com. +[57]nytimes.com. +nydns1.[87]about.[65]com. +[57]nytimes.com. +ns1t.[57]nytimes.com. +[80]nydns2.about.[65]com. +[107]nydns1.[87]about.[65]com. +[128]ns1t.[57]nytimes.com. +googleads.g.doubleclick.net. +googleads.g.doubleclick.net. +[12]googleads.g.doubleclick.net. +pagead.l.doubleclick.net. +[57]pagead.l.doubleclick.net. +[64]l.doubleclick.net. +b.l.google.com. +[64]l.doubleclick.net. +d.[113]l.google.com. +[64]l.doubleclick.net. +e.[113]l.google.com. +[64]l.doubleclick.net. +f.[113]l.google.com. +[64]l.doubleclick.net. +g.[113]l.google.com. +[64]l.doubleclick.net. +a.[113]l.google.com. +[111]b.l.google.com. +[139]d.[113]l.google.com. +[155]e.[113]l.google.com. +[171]f.[113]l.google.com. +[187]g.[113]l.google.com. +[203]a.[113]l.google.com. +up.nytimes.com. +up.nytimes.com. +[12]up.nytimes.com. +up.about.akadns.net. +[44]up.about.akadns.net. +[53]akadns.net. +eur1.[53]akadns.net. +[53]akadns.net. +use3.[53]akadns.net. +[53]akadns.net. +use4.[53]akadns.net. +[53]akadns.net. +usw2.[53]akadns.net. +[53]akadns.net. +za.akadns.org. +[53]akadns.net. +zb.[172]akadns.org. +[53]akadns.net. +zc.[172]akadns.org. +[53]akadns.net. +zd.[172]akadns.org. +[53]akadns.net. +asia9.[53]akadns.net. +[93]eur1.[53]akadns.net. +[112]use3.[53]akadns.net. +[131]use4.[53]akadns.net. +[150]usw2.[53]akadns.net. +[169]za.akadns.org. +[196]zb.[172]akadns.org. +[213]zc.[172]akadns.org. +[230]zd.[172]akadns.org. +[247]asia9.[53]akadns.net. +pix04.revsci.net. +pix04.revsci.net. +[12]pix04.revsci.net. +revsci.net. +ns2.p16.dynect.[57]net. +[50]revsci.net. +ns3.[76]p16.dynect.[57]net. +[50]revsci.net. +ns1.[76]p16.dynect.[57]net. +[50]revsci.net. +ns4.[76]p16.dynect.[57]net. +[72]ns2.p16.dynect.[57]net. +[101]ns3.[76]p16.dynect.[57]net. +[119]ns1.[76]p16.dynect.[57]net. +[137]ns4.[76]p16.dynect.[57]net. +wt.o.nytimes.com. +wt.o.nytimes.com. +[12]wt.o.nytimes.com. +nytimes.webtrends.akadns.net. +[46]nytimes.webtrends.akadns.net. +[64]akadns.net. +use3.[64]akadns.net. +[64]akadns.net. +use4.[64]akadns.net. +[64]akadns.net. +usw2.[64]akadns.net. +[64]akadns.net. +za.akadns.org. +[64]akadns.net. +zb.[164]akadns.org. +[64]akadns.net. +zc.[164]akadns.org. +[64]akadns.net. +zd.[164]akadns.org. +[64]akadns.net. +asia9.[64]akadns.net. +[64]akadns.net. +eur1.[64]akadns.net. +[104]use3.[64]akadns.net. +[123]use4.[64]akadns.net. +[142]usw2.[64]akadns.net. +[161]za.akadns.org. +[188]zb.[164]akadns.org. +[205]zc.[164]akadns.org. +[222]zd.[164]akadns.org. +[239]asia9.[64]akadns.net. +[259]eur1.[64]akadns.net. +te.nytimes.com. +ar.voicefive.com. +te.nytimes.com. +[12]te.nytimes.com. +nytd.te.tacoda.net. +[44]nytd.te.tacoda.net. +te.tacoda.akadns.[59]net. +[76]te.tacoda.akadns.[59]net. +[86]akadns.[59]net. +use4.[86]akadns.[59]net. +[86]akadns.[59]net. +usw2.[86]akadns.[59]net. +[86]akadns.[59]net. +za.akadns.org. +[86]akadns.[59]net. +zb.[164]akadns.org. +[86]akadns.[59]net. +zc.[164]akadns.org. +[86]akadns.[59]net. +zd.[164]akadns.org. +[86]akadns.[59]net. +asia9.[86]akadns.[59]net. +[86]akadns.[59]net. +eur1.[86]akadns.[59]net. +[86]akadns.[59]net. +use3.[86]akadns.[59]net. +[123]use4.[86]akadns.[59]net. +[142]usw2.[86]akadns.[59]net. +[161]za.akadns.org. +[188]zb.[164]akadns.org. +[205]zc.[164]akadns.org. +[222]zd.[164]akadns.org. +[239]asia9.[86]akadns.[59]net. +[259]eur1.[86]akadns.[59]net. +[278]use3.[86]akadns.[59]net. +ar.voicefive.com. +[12]ar.voicefive.com. +ar.gta.voicefive.com. +[46]ar.gta.voicefive.com. +[49]gta.voicefive.com. +gta02.ord.[53]voicefive.com. +[49]gta.voicefive.com. +gta01.iad.[53]voicefive.com. +[49]gta.voicefive.com. +gta01.[102]ord.[53]voicefive.com. +[49]gta.voicefive.com. +gta02.[126]iad.[53]voicefive.com. +[96]gta02.ord.[53]voicefive.com. +[120]gta01.iad.[53]voicefive.com. +[144]gta01.[102]ord.[53]voicefive.com. +[164]gta02.[126]iad.[53]voicefive.com. +www.google.com. +www.google.com. +[12]www.google.com. +www.l.google.com. +[44]www.l.google.com. +[48]l.google.com. +d.[48]l.google.com. +[48]l.google.com. +e.[48]l.google.com. +[48]l.google.com. +f.[48]l.google.com. +[48]l.google.com. +g.[48]l.google.com. +[48]l.google.com. +b.[48]l.google.com. +[48]l.google.com. +a.[48]l.google.com. +[90]d.[48]l.google.com. +[106]e.[48]l.google.com. +[122]f.[48]l.google.com. +[138]g.[48]l.google.com. +[154]b.[48]l.google.com. +[170]a.[48]l.google.com. +www.google-analytics.com. +www.google-analytics.com. +[12]www.google-analytics.com. +www-google-analytics.l.google.com. +[54]www-google-analytics.l.google.com. +[75]l.google.com. +f.[75]l.google.com. +[75]l.google.com. +g.[75]l.google.com. +[75]l.google.com. +b.[75]l.google.com. +[75]l.google.com. +a.[75]l.google.com. +[75]l.google.com. +d.[75]l.google.com. +[75]l.google.com. +e.[75]l.google.com. +[117]f.[75]l.google.com. +[133]g.[75]l.google.com. +[149]b.[75]l.google.com. +[165]a.[75]l.google.com. +[181]d.[75]l.google.com. +[197]e.[75]l.google.com. +pagead2.googlesyndication.com. +pagead2.googlesyndication.com. +[12]pagead2.googlesyndication.com. +pagead.l.google.com. +[59]pagead.l.google.com. +[66]l.google.com. +g.[66]l.google.com. +[66]l.google.com. +b.[66]l.google.com. +[66]l.google.com. +a.[66]l.google.com. +[66]l.google.com. +d.[66]l.google.com. +[66]l.google.com. +e.[66]l.google.com. +[66]l.google.com. +f.[66]l.google.com. +[108]g.[66]l.google.com. +[124]b.[66]l.google.com. +[140]a.[66]l.google.com. +[156]d.[66]l.google.com. +[172]e.[66]l.google.com. +[188]f.[66]l.google.com. +maps.google.com. +maps.google.com. +[12]maps.google.com. +maps.l.google.com. +[45]maps.l.google.com. +[50]l.google.com. +b.[50]l.google.com. +[50]l.google.com. +a.[50]l.google.com. +[50]l.google.com. +d.[50]l.google.com. +[50]l.google.com. +e.[50]l.google.com. +[50]l.google.com. +f.[50]l.google.com. +[50]l.google.com. +g.[50]l.google.com. +[92]b.[50]l.google.com. +[108]a.[50]l.google.com. +[124]d.[50]l.google.com. +[140]e.[50]l.google.com. +[156]f.[50]l.google.com. +[172]g.[50]l.google.com. +maps.gstatic.com. +maps.gstatic.com. +[12]maps.gstatic.com. +www2.l.google.com. +[46]www2.l.google.com. +[51]l.google.com. +a.[51]l.google.com. +[51]l.google.com. +d.[51]l.google.com. +[51]l.google.com. +e.[51]l.google.com. +[51]l.google.com. +f.[51]l.google.com. +[51]l.google.com. +g.[51]l.google.com. +[51]l.google.com. +b.[51]l.google.com. +[93]a.[51]l.google.com. +[109]d.[51]l.google.com. +[125]e.[51]l.google.com. +[141]f.[51]l.google.com. +[157]g.[51]l.google.com. +[173]b.[51]l.google.com. +www.calgaryherald.com. +www.calgaryherald.com. +[12]www.calgaryherald.com. +calgaryherald.com. +ns1.canwest.[69]com. +[55]calgaryherald.com. +ns2.[88]canwest.[69]com. +[84]ns1.canwest.[69]com. +[110]ns2.[88]canwest.[69]com. +a123.g.akamai.net. +a123.g.akamai.net. +[12]a123.g.akamai.net. +[12]a123.g.akamai.net. +members.canada.com. +members.canada.com. +[12]members.canada.com. +canada.com. +ns2.canwest.[59]com. +[52]canada.com. +ns1.[78]canwest.[59]com. +[74]ns2.canwest.[59]com. +[100]ns1.[78]canwest.[59]com. +www.canada.com. +www.canada.com. +[12]www.canada.com. +canada.com. +ns1.canwest.[55]com. +[48]canada.com. +ns2.[74]canwest.[55]com. +[70]ns1.canwest.[55]com. +[96]ns2.[74]canwest.[55]com. +s9.addthis.com. +s9.addthis.com. +[12]s9.addthis.com. +wildcard.addthis.com.edgekey.net. +[44]wildcard.addthis.com.edgekey.net. +e2943.c.akamaiedge.[73]net. +[90]e2943.c.akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n7c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n5c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n8c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n0c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n6c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n1c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n4c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n3c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n2c.[98]akamaiedge.[73]net. +[139]n7c.[98]akamaiedge.[73]net. +[157]n5c.[98]akamaiedge.[73]net. +[175]n8c.[98]akamaiedge.[73]net. +[193]n0c.[98]akamaiedge.[73]net. +[211]n6c.[98]akamaiedge.[73]net. +[229]n1c.[98]akamaiedge.[73]net. +[247]n4c.[98]akamaiedge.[73]net. +[265]n3c.[98]akamaiedge.[73]net. +[283]n2c.[98]akamaiedge.[73]net. +communities.canada.com. +communities.canada.com. +[12]communities.canada.com. +canada.com. +ns1.canwest.[63]com. +[56]canada.com. +ns2.[82]canwest.[63]com. +[78]ns1.canwest.[63]com. +[104]ns2.[82]canwest.[63]com. +canwestglobal.112.2o7.net. +beacon.securestudies.com. +beacon.securestudies.com. +[12]beacon.securestudies.com. +beacon.gta.securestudies.com. +[54]beacon.gta.securestudies.com. +[61]gta.securestudies.com. +gta02.iad.[65]securestudies.com. +[61]gta.securestudies.com. +gta02.ord.[65]securestudies.com. +[61]gta.securestudies.com. +gta01.[118]iad.[65]securestudies.com. +[61]gta.securestudies.com. +gta01.[142]ord.[65]securestudies.com. +[112]gta02.iad.[65]securestudies.com. +[136]gta02.ord.[65]securestudies.com. +[160]gta01.[118]iad.[65]securestudies.com. +[180]gta01.[142]ord.[65]securestudies.com. +canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +2o7.net. +ns1.dal.omniture.com. +[155]2o7.net. +ns1.sj1.[182]omniture.com. +[155]2o7.net. +ns1.sj2.[182]omniture.com. +[174]ns1.dal.omniture.com. +[208]ns1.sj1.[182]omniture.com. +[230]ns1.sj2.[182]omniture.com. +s7.addthis.com. +s7.addthis.com. +[12]s7.addthis.com. +wildcard.addthis.com.edgekey.net. +[44]wildcard.addthis.com.edgekey.net. +e2943.c.akamaiedge.[73]net. +[90]e2943.c.akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n5c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n8c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n0c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n6c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n1c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n4c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n3c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n2c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n7c.[98]akamaiedge.[73]net. +[139]n5c.[98]akamaiedge.[73]net. +[157]n8c.[98]akamaiedge.[73]net. +[175]n0c.[98]akamaiedge.[73]net. +[193]n6c.[98]akamaiedge.[73]net. +[211]n1c.[98]akamaiedge.[73]net. +[229]n4c.[98]akamaiedge.[73]net. +[247]n3c.[98]akamaiedge.[73]net. +[265]n2c.[98]akamaiedge.[73]net. +[283]n7c.[98]akamaiedge.[73]net. +csi.gstatic.com. +csi.gstatic.com. +[12]csi.gstatic.com. +csi.l.google.com. +[45]csi.l.google.com. +[49]l.google.com. +d.[49]l.google.com. +[49]l.google.com. +e.[49]l.google.com. +[49]l.google.com. +f.[49]l.google.com. +[49]l.google.com. +g.[49]l.google.com. +[49]l.google.com. +b.[49]l.google.com. +[49]l.google.com. +a.[49]l.google.com. +[91]d.[49]l.google.com. +[107]e.[49]l.google.com. +[123]f.[49]l.google.com. +[139]g.[49]l.google.com. +[155]b.[49]l.google.com. +[171]a.[49]l.google.com. +www.thestar.com. +www.thestar.com. +[12]www.thestar.com. +[16]thestar.com. +ns1.[16]thestar.com. +[16]thestar.com. +ns2.[16]thestar.com. +[61]ns1.[16]thestar.com. +[79]ns2.[16]thestar.com. +beacon.scorecardresearch.com. +beacon.scorecardresearch.com. +[12]beacon.scorecardresearch.com. +beacon.gta.scorecardresearch.com. +[58]beacon.gta.scorecardresearch.com. +[65]gta.scorecardresearch.com. +gta01.iad.[69]scorecardresearch.com. +[65]gta.scorecardresearch.com. +gta02.ord.[69]scorecardresearch.com. +[65]gta.scorecardresearch.com. +gta01.[150]ord.[69]scorecardresearch.com. +[65]gta.scorecardresearch.com. +gta02.[126]iad.[69]scorecardresearch.com. +[120]gta01.iad.[69]scorecardresearch.com. +[144]gta02.ord.[69]scorecardresearch.com. +[168]gta01.[150]ord.[69]scorecardresearch.com. +[188]gta02.[126]iad.[69]scorecardresearch.com. +media.thestar.topscms.com. +media.thestar.topscms.com. +[12]media.thestar.topscms.com. +media.thestar.topscms.com.edgesuite.net. +[55]media.thestar.topscms.com.edgesuite.net. +a1520.g.akamai.[91]net. +[108]a1520.g.akamai.[91]net. +[108]a1520.g.akamai.[91]net. +[114]g.akamai.[91]net. +n0g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n4g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n2g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n5g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n7g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n6g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n8g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n1g.[116]akamai.[91]net. +[114]g.akamai.[91]net. +n3g.[116]akamai.[91]net. +[169]n0g.[116]akamai.[91]net. +[187]n4g.[116]akamai.[91]net. +[205]n2g.[116]akamai.[91]net. +[223]n5g.[116]akamai.[91]net. +[241]n7g.[116]akamai.[91]net. +[259]n6g.[116]akamai.[91]net. +[277]n8g.[116]akamai.[91]net. +[295]n1g.[116]akamai.[91]net. +[313]n3g.[116]akamai.[91]net. +www.addthis.com. +www.addthis.com. +[12]www.addthis.com. +vp-www.addthis.com. +[45]vp-www.addthis.com. +[52]addthis.com. +eur2.akam.net. +[52]addthis.com. +usc1.[98]akam.net. +[52]addthis.com. +usc2.[98]akam.net. +[52]addthis.com. +usw1.[98]akam.net. +[52]addthis.com. +usw6.[98]akam.net. +[52]addthis.com. +asia3.[98]akam.net. +[52]addthis.com. +ns1-33.[98]akam.net. +[52]addthis.com. +ns1-43.[98]akam.net. +[93]eur2.akam.net. +[120]usc1.[98]akam.net. +[139]usc2.[98]akam.net. +[158]usw1.[98]akam.net. +[177]usw6.[98]akam.net. +[196]asia3.[98]akam.net. +[216]ns1-33.[98]akam.net. +[237]ns1-43.[98]akam.net. +n.thestar.com. +n.thestar.com. +[12]n.thestar.com. +thestar.com.122.2o7.net. +[43]thestar.com.122.2o7.net. +[43]thestar.com.122.2o7.net. +[43]thestar.com.122.2o7.net. +[43]thestar.com.122.2o7.net. +[43]thestar.com.122.2o7.net. +[43]thestar.com.122.2o7.net. +[59]2o7.net. +ns1.sj1.omniture.com. +[59]2o7.net. +ns1.sj2.[184]omniture.com. +[59]2o7.net. +ns1.dal.[184]omniture.com. +[176]ns1.sj1.omniture.com. +[210]ns1.sj2.[184]omniture.com. +[232]ns1.dal.[184]omniture.com. +news.therecord.com. +news.therecord.com. +[12]news.therecord.com. +therecord.com. +ns1.thestar.[62]com. +[52]therecord.com. +ns2.[81]thestar.[62]com. +[77]ns1.thestar.[62]com. +[103]ns2.[81]thestar.[62]com. +media.therecord.topscms.com. +media.therecord.topscms.com. +[12]media.therecord.topscms.com. +media.therecord.topscms.com.edgesuite.net. +[57]media.therecord.topscms.com.edgesuite.net. +a847.g.akamai.[95]net. +[112]a847.g.akamai.[95]net. +[112]a847.g.akamai.[95]net. +[117]g.akamai.[95]net. +n2g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n5g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n7g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n6g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n8g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n1g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n3g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n0g.[119]akamai.[95]net. +[117]g.akamai.[95]net. +n4g.[119]akamai.[95]net. +[172]n2g.[119]akamai.[95]net. +[190]n5g.[119]akamai.[95]net. +[208]n7g.[119]akamai.[95]net. +[226]n6g.[119]akamai.[95]net. +[244]n8g.[119]akamai.[95]net. +[262]n1g.[119]akamai.[95]net. +[280]n3g.[119]akamai.[95]net. +[298]n0g.[119]akamai.[95]net. +[316]n4g.[119]akamai.[95]net. +media.therecord.com. +www.goldbook.ca. +media.therecord.com. +[12]media.therecord.com. +therecord.com. +ns2.thestar.[63]com. +[53]therecord.com. +ns1.[82]thestar.[63]com. +[78]ns2.thestar.[63]com. +[104]ns1.[82]thestar.[63]com. +www.goldbook.ca. +[12]www.goldbook.ca. +goldbook.ca. +[45]goldbook.ca. +[45]goldbook.ca. +ns4.everydns.net. +[45]goldbook.ca. +ns1.[90]everydns.net. +[45]goldbook.ca. +ns2.[90]everydns.net. +[45]goldbook.ca. +ns3.[90]everydns.net. +[86]ns4.everydns.net. +[116]ns1.[90]everydns.net. +[134]ns2.[90]everydns.net. +[152]ns3.[90]everydns.net. +torstardigital.122.2o7.net. +torstardigital.122.2o7.net. +[12]torstardigital.122.2o7.net. +[12]torstardigital.122.2o7.net. +[12]torstardigital.122.2o7.net. +[12]torstardigital.122.2o7.net. +[12]torstardigital.122.2o7.net. +[12]torstardigital.122.2o7.net. +2o7.net. +ns1.dal.omniture.com. +[140]2o7.net. +ns1.sj1.[167]omniture.com. +[140]2o7.net. +ns1.sj2.[167]omniture.com. +[159]ns1.dal.omniture.com. +[193]ns1.sj1.[167]omniture.com. +[215]ns1.sj2.[167]omniture.com. +news.google.ca. +news.google.ca. +[12]news.google.ca. +news.google.com. +[44]news.google.com. +news.l.[49]google.com. +[73]news.l.[49]google.com. +[78]l.[49]google.com. +e.[78]l.[49]google.com. +[78]l.[49]google.com. +b.[78]l.[49]google.com. +[78]l.[49]google.com. +a.[78]l.[49]google.com. +[78]l.[49]google.com. +g.[78]l.[49]google.com. +[78]l.[49]google.com. +d.[78]l.[49]google.com. +[78]l.[49]google.com. +f.[78]l.[49]google.com. +[110]e.[78]l.[49]google.com. +[126]b.[78]l.[49]google.com. +[142]a.[78]l.[49]google.com. +[158]g.[78]l.[49]google.com. +[174]d.[78]l.[49]google.com. +[190]f.[78]l.[49]google.com. +googleads.g.doubleclick.net. +googleads.g.doubleclick.net. +[12]googleads.g.doubleclick.net. +pagead.l.doubleclick.net. +[57]pagead.l.doubleclick.net. +[64]l.doubleclick.net. +g.l.google.com. +[64]l.doubleclick.net. +a.[113]l.google.com. +[64]l.doubleclick.net. +b.[113]l.google.com. +[64]l.doubleclick.net. +d.[113]l.google.com. +[64]l.doubleclick.net. +e.[113]l.google.com. +[64]l.doubleclick.net. +f.[113]l.google.com. +[111]g.l.google.com. +[139]a.[113]l.google.com. +[155]b.[113]l.google.com. +[171]d.[113]l.google.com. +[187]e.[113]l.google.com. +[203]f.[113]l.google.com. +www.montrealgazette.com. +www.montrealgazette.com. +[12]www.montrealgazette.com. +montrealgazette.com. +ns2.canwest.[73]com. +[57]montrealgazette.com. +ns1.[92]canwest.[73]com. +[88]ns2.canwest.[73]com. +[114]ns1.[92]canwest.[73]com. +a123.g.akamai.net. +a123.g.akamai.net. +[12]a123.g.akamai.net. +[12]a123.g.akamai.net. +members.canada.com. +members.canada.com. +[12]members.canada.com. +canada.com. +ns2.canwest.[59]com. +[52]canada.com. +ns1.[78]canwest.[59]com. +[74]ns2.canwest.[59]com. +[100]ns1.[78]canwest.[59]com. +www.cbc.ca. +www.cbc.ca. +[12]www.cbc.ca. +www.cbc.ca.edgesuite.net. +[40]www.cbc.ca.edgesuite.net. +a1849.gc.akamai.[61]net. +[78]a1849.gc.akamai.[61]net. +[78]a1849.gc.akamai.[61]net. +[84]gc.akamai.[61]net. +n6gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n1gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n4gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n8gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n2gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n0gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n7gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n5gc.[87]akamai.[61]net. +[84]gc.akamai.[61]net. +n3gc.[87]akamai.[61]net. +[140]n6gc.[87]akamai.[61]net. +[159]n1gc.[87]akamai.[61]net. +[178]n4gc.[87]akamai.[61]net. +[197]n8gc.[87]akamai.[61]net. +[216]n2gc.[87]akamai.[61]net. +[235]n0gc.[87]akamai.[61]net. +[254]n7gc.[87]akamai.[61]net. +[273]n5gc.[87]akamai.[61]net. +[292]n3gc.[87]akamai.[61]net. +a.cbc.ca. +a.cbc.ca. +[12]a.cbc.ca. +ehg-cbc.hitbox.com. +[38]ehg-cbc.hitbox.com. +[46]hitbox.com. +dns06.omniture.[53]com. +[46]hitbox.com. +dns05.[92]omniture.[53]com. +[46]hitbox.com. +dns04.[92]omniture.[53]com. +[46]hitbox.com. +dns03.[92]omniture.[53]com. +[46]hitbox.com. +dns02.[92]omniture.[53]com. +[46]hitbox.com. +dns01.[92]omniture.[53]com. +[86]dns06.omniture.[53]com. +[115]dns05.[92]omniture.[53]com. +[135]dns04.[92]omniture.[53]com. +[155]dns03.[92]omniture.[53]com. +[175]dns02.[92]omniture.[53]com. +[195]dns01.[92]omniture.[53]com. +assets.loomia.com. +assets.loomia.com. +[12]assets.loomia.com. +a.[19]loomia.com. +[47]a.[19]loomia.com. +[19]loomia.com. +ns15.dnsmadeeasy.[26]com. +[19]loomia.com. +ns14.[84]dnsmadeeasy.[26]com. +[19]loomia.com. +ns12.[84]dnsmadeeasy.[26]com. +[19]loomia.com. +ns11.[84]dnsmadeeasy.[26]com. +[19]loomia.com. +ns13.[84]dnsmadeeasy.[26]com. +[19]loomia.com. +ns10.[84]dnsmadeeasy.[26]com. +recs-social.loomia.com. +recs-social.loomia.com. +[12]recs-social.loomia.com. +rec-assets.[24]loomia.com. +[52]rec-assets.[24]loomia.com. +[24]loomia.com. +ns14.dnsmadeeasy.[31]com. +[24]loomia.com. +ns11.[98]dnsmadeeasy.[31]com. +[24]loomia.com. +ns12.[98]dnsmadeeasy.[31]com. +[24]loomia.com. +ns15.[98]dnsmadeeasy.[31]com. +[24]loomia.com. +ns10.[98]dnsmadeeasy.[31]com. +[24]loomia.com. +ns13.[98]dnsmadeeasy.[31]com. +e1.clearspring.com. +static-cache.loomia.com. +static-cache.loomia.com. +[12]static-cache.loomia.com. +static-cache.loomia.com.edgesuite.net. +[53]static-cache.loomia.com.edgesuite.net. +a298.g.akamai.[87]net. +[104]a298.g.akamai.[87]net. +[104]a298.g.akamai.[87]net. +[109]g.akamai.[87]net. +n4g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n2g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n5g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n7g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n6g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n8g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n1g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n3g.[111]akamai.[87]net. +[109]g.akamai.[87]net. +n0g.[111]akamai.[87]net. +[164]n4g.[111]akamai.[87]net. +[182]n2g.[111]akamai.[87]net. +[200]n5g.[111]akamai.[87]net. +[218]n7g.[111]akamai.[87]net. +[236]n6g.[111]akamai.[87]net. +[254]n8g.[111]akamai.[87]net. +[272]n1g.[111]akamai.[87]net. +[290]n3g.[111]akamai.[87]net. +[308]n0g.[111]akamai.[87]net. +e1.clearspring.com. +[12]e1.clearspring.com. +[15]clearspring.com. +usc2.akam.net. +[15]clearspring.com. +usw1.[69]akam.net. +[15]clearspring.com. +usw6.[69]akam.net. +[15]clearspring.com. +asia3.[69]akam.net. +[15]clearspring.com. +ns1-33.[69]akam.net. +[15]clearspring.com. +ns1-43.[69]akam.net. +[15]clearspring.com. +eur2.[69]akam.net. +[15]clearspring.com. +usc1.[69]akam.net. +csi.gstatic.com. +csi.gstatic.com. +[12]csi.gstatic.com. +csi.l.google.com. +[45]csi.l.google.com. +[49]l.google.com. +b.[49]l.google.com. +[49]l.google.com. +e.[49]l.google.com. +[49]l.google.com. +d.[49]l.google.com. +[49]l.google.com. +a.[49]l.google.com. +[49]l.google.com. +f.[49]l.google.com. +[49]l.google.com. +g.[49]l.google.com. +[91]b.[49]l.google.com. +[107]e.[49]l.google.com. +[123]d.[49]l.google.com. +[139]a.[49]l.google.com. +[155]f.[49]l.google.com. +[171]g.[49]l.google.com. +www.gstatic.com. +www.gstatic.com. +[12]www.gstatic.com. +www2.l.google.com. +[45]www2.l.google.com. +[50]l.google.com. +d.[50]l.google.com. +[50]l.google.com. +f.[50]l.google.com. +[50]l.google.com. +e.[50]l.google.com. +[50]l.google.com. +b.[50]l.google.com. +[50]l.google.com. +a.[50]l.google.com. +[50]l.google.com. +g.[50]l.google.com. +[92]d.[50]l.google.com. +[108]f.[50]l.google.com. +[124]e.[50]l.google.com. +[140]b.[50]l.google.com. +[156]a.[50]l.google.com. +[172]g.[50]l.google.com. +i.ytimg.com. +i.ytimg.com. +[12]i.ytimg.com. +ytimg.l.google.com. +[41]ytimg.l.google.com. +[47]l.google.com. +b.[47]l.google.com. +[47]l.google.com. +a.[47]l.google.com. +[47]l.google.com. +g.[47]l.google.com. +[47]l.google.com. +d.[47]l.google.com. +[47]l.google.com. +f.[47]l.google.com. +[47]l.google.com. +e.[47]l.google.com. +[89]b.[47]l.google.com. +[105]a.[47]l.google.com. +[121]g.[47]l.google.com. +[137]d.[47]l.google.com. +[153]f.[47]l.google.com. +[169]e.[47]l.google.com. +news.bbc.co.uk. +news.bbc.co.uk. +[12]news.bbc.co.uk. +newswww.bbc.net.uk. +[44]newswww.bbc.net.uk. +[52]bbc.net.uk. +ns0.rbsov.bbc.co.[60]uk. +[52]bbc.net.uk. +ns0.thdo.[102]bbc.co.[60]uk. +[92]ns0.rbsov.bbc.co.[60]uk. +[123]ns0.thdo.[102]bbc.co.[60]uk. +node1.bbcimg.co.uk. +node1.bbcimg.co.uk. +[12]node1.bbcimg.co.uk. +img.bbc.net.uk. +[48]img.bbc.net.uk. +[52]bbc.net.uk. +ns0.rbsov.bbc.co.[60]uk. +[52]bbc.net.uk. +ns0.thdo.[102]bbc.co.[60]uk. +[92]ns0.rbsov.bbc.co.[60]uk. +[123]ns0.thdo.[102]bbc.co.[60]uk. +newsimg.bbc.co.uk. +newsimg.bbc.co.uk. +[12]newsimg.bbc.co.uk. +newsimg.bbc.net.uk. +[47]newsimg.bbc.net.uk. +news.bbc.co.uk.edgesuite.net. +[79]news.bbc.co.uk.edgesuite.net. +a1733.g.akamai.[104]net. +[121]a1733.g.akamai.[104]net. +[121]a1733.g.akamai.[104]net. +[127]g.akamai.[104]net. +n7g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n6g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n8g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n1g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n3g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n0g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n4g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n2g.[129]akamai.[104]net. +[127]g.akamai.[104]net. +n5g.[129]akamai.[104]net. +[182]n7g.[129]akamai.[104]net. +[200]n6g.[129]akamai.[104]net. +[218]n8g.[129]akamai.[104]net. +[236]n1g.[129]akamai.[104]net. +[254]n3g.[129]akamai.[104]net. +[272]n0g.[129]akamai.[104]net. +[290]n4g.[129]akamai.[104]net. +[308]n2g.[129]akamai.[104]net. +[326]n5g.[129]akamai.[104]net. +stats.bbc.co.uk. +stats.bbc.co.uk. +[12]stats.bbc.co.uk. +[12]stats.bbc.co.uk. +bbc.co.uk. +ns1.thls.[65]bbc.co.uk. +[65]bbc.co.uk. +ns1.thdo.[65]bbc.co.uk. +[65]bbc.co.uk. +ns1.rbsov.[65]bbc.co.uk. +[65]bbc.co.uk. +ns1.[65]bbc.co.uk. +[86]ns1.thls.[65]bbc.co.uk. +[109]ns1.thdo.[65]bbc.co.uk. +[132]ns1.rbsov.[65]bbc.co.uk. +[156]ns1.[65]bbc.co.uk. +visualscience.external.bbc.co.uk. +js.revsci.net. +visualscience.external.bbc.co.uk. +[12]visualscience.external.bbc.co.uk. +csvtm.interactionscience.com. +[62]csvtm.interactionscience.com. +[68]interactionscience.com. +ns1.sj1.omniture.[87]com. +[68]interactionscience.com. +ns1.sj2.[128]omniture.[87]com. +[68]interactionscience.com. +ns1.dal.[128]omniture.[87]com. +[120]ns1.sj1.omniture.[87]com. +[151]ns1.sj2.[128]omniture.[87]com. +[173]ns1.dal.[128]omniture.[87]com. +js.revsci.net. +[12]js.revsci.net. +[15]revsci.net. +ns3.p16.dynect.[22]net. +[15]revsci.net. +ns4.[63]p16.dynect.[22]net. +[15]revsci.net. +ns2.[63]p16.dynect.[22]net. +[15]revsci.net. +ns1.[63]p16.dynect.[22]net. +pix04.revsci.net. +pix04.revsci.net. +[12]pix04.revsci.net. +[18]revsci.net. +ns4.p16.dynect.[25]net. +[18]revsci.net. +ns1.[66]p16.dynect.[25]net. +[18]revsci.net. +ns3.[66]p16.dynect.[25]net. +[18]revsci.net. +ns2.[66]p16.dynect.[25]net. +pixel.quantserve.com. +pixel.quantserve.com. +[12]pixel.quantserve.com. +map-pb.quantserve.com.akadns.net. +[50]map-pb.quantserve.com.akadns.net. +ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[96]ac-na.[57]quantserve.com.akadns.net. +[72]akadns.net. +za.akadns.org. +[72]akadns.net. +zb.[231]akadns.org. +[72]akadns.net. +zc.[231]akadns.org. +[72]akadns.net. +zd.[231]akadns.org. +[72]akadns.net. +asia9.[72]akadns.net. +[72]akadns.net. +eur1.[72]akadns.net. +[72]akadns.net. +use3.[72]akadns.net. +[72]akadns.net. +use4.[72]akadns.net. +[72]akadns.net. +usw2.[72]akadns.net. +[228]za.akadns.org. +[255]zb.[231]akadns.org. +[272]zc.[231]akadns.org. +[289]zd.[231]akadns.org. +[306]asia9.[72]akadns.net. +[326]eur1.[72]akadns.net. +[345]use3.[72]akadns.net. +www.vancouversun.com. +www.vancouversun.com. +[12]www.vancouversun.com. +vancouversun.com. +ns1.canwest.[67]com. +[54]vancouversun.com. +ns2.[86]canwest.[67]com. +[82]ns1.canwest.[67]com. +[108]ns2.[86]canwest.[67]com. +www.scan.nowpublic.com. +www.scan.nowpublic.com. +[12]www.scan.nowpublic.com. +a1.panthercdn.com. +[52]a1.panthercdn.com. +[55]panthercdn.com. +ns1.[55]panthercdn.com. +[55]panthercdn.com. +ns2.[55]panthercdn.com. +[99]ns1.[55]panthercdn.com. +[117]ns2.[55]panthercdn.com. +a123.g.akamai.net. +a123.g.akamai.net. +[12]a123.g.akamai.net. +[12]a123.g.akamai.net. +feeds.theplatform.com. +canwestglobal.112.2o7.net. +beacon.securestudies.com. +canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +[12]canwestglobal.112.2o7.net. +2o7.net. +ns1.sj1.omniture.com. +[155]2o7.net. +ns1.sj2.[182]omniture.com. +[155]2o7.net. +ns1.dal.[182]omniture.com. +[174]ns1.sj1.omniture.com. +[208]ns1.sj2.[182]omniture.com. +[230]ns1.dal.[182]omniture.com. +beacon.securestudies.com. +[12]beacon.securestudies.com. +beacon.gta.securestudies.com. +[54]beacon.gta.securestudies.com. +[61]gta.securestudies.com. +gta02.ord.[65]securestudies.com. +[61]gta.securestudies.com. +gta01.iad.[65]securestudies.com. +[61]gta.securestudies.com. +gta01.[118]ord.[65]securestudies.com. +[61]gta.securestudies.com. +gta02.[142]iad.[65]securestudies.com. +[112]gta02.ord.[65]securestudies.com. +[136]gta01.iad.[65]securestudies.com. +[160]gta01.[118]ord.[65]securestudies.com. +[180]gta02.[142]iad.[65]securestudies.com. +feeds.theplatform.com. +[12]feeds.theplatform.com. +[18]theplatform.com. +sea1tpgtm01.[18]theplatform.com. +[18]theplatform.com. +bfi1tpgtm01.[18]theplatform.com. +[67]sea1tpgtm01.[18]theplatform.com. +[93]bfi1tpgtm01.[18]theplatform.com. +s7.addthis.com. +s7.addthis.com. +[12]s7.addthis.com. +wildcard.addthis.com.edgekey.net. +[44]wildcard.addthis.com.edgekey.net. +e2943.c.akamaiedge.[73]net. +[90]e2943.c.akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n5c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n8c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n0c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n6c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n1c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n4c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n3c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n2c.[98]akamaiedge.[73]net. +[96]c.akamaiedge.[73]net. +n7c.[98]akamaiedge.[73]net. +[139]n5c.[98]akamaiedge.[73]net. +[157]n8c.[98]akamaiedge.[73]net. +[175]n0c.[98]akamaiedge.[73]net. +[193]n6c.[98]akamaiedge.[73]net. +[211]n1c.[98]akamaiedge.[73]net. +[229]n4c.[98]akamaiedge.[73]net. +[247]n3c.[98]akamaiedge.[73]net. +[265]n2c.[98]akamaiedge.[73]net. +[283]n7c.[98]akamaiedge.[73]net. +ad.doubleclick.net. +ad.doubleclick.net. +[12]ad.doubleclick.net. +dart-ad.l.doubleclick.net. +[48]dart-ad.l.doubleclick.net. +[48]dart-ad.l.doubleclick.net. +[56]l.doubleclick.net. +g.l.google.com. +[56]l.doubleclick.net. +a.[121]l.google.com. +[56]l.doubleclick.net. +b.[121]l.google.com. +[56]l.doubleclick.net. +d.[121]l.google.com. +[56]l.doubleclick.net. +e.[121]l.google.com. +[56]l.doubleclick.net. +f.[121]l.google.com. +[119]g.l.google.com. +[147]a.[121]l.google.com. +[163]b.[121]l.google.com. +[179]d.[121]l.google.com. +[195]e.[121]l.google.com. +[211]f.[121]l.google.com. +*** SUCCESS *** diff --git a/test/generate1.lm b/test/generate1.lm new file mode 100644 index 00000000..54a342a4 --- /dev/null +++ b/test/generate1.lm @@ -0,0 +1,773 @@ +context generate + # Regular definitions + rl ident_char /[a-zA-Z_]/ + + # List used as a stack of indentations. + struct int_el + Int: int + list_el el + end + IndentStack: list<int_el> + + # Has a newline been sent for this '\n' .. whitespace match. + newline_sent: int + + # Tokens. + lex + # Python keywords. + literal `and `del `from `not `while `as `elif `global `or + `with `assert `else `if `pass `yield `break `except + `import `print `class `exec `in `raise `continue + `finally `is `return `def `for `lambda `try + + # Identifiers + rl lowercase /'a'..'z'/ + rl uppercase /'A'..'Z'/ + rl letter /lowercase | uppercase/ + token identifier /(letter|'_') (letter | digit | '_')*/ + + # Literals + rl escapeseq /'\\' any / + rl longstringchar /[^\\]/ + rl shortstringchar_s /[^\\\n']/ + rl shortstringchar_d /[^\\\n"]/ + rl longstringitem /longstringchar | escapeseq/ + rl shortstringitem_s /shortstringchar_s | escapeseq/ + rl shortstringitem_d /shortstringchar_d | escapeseq/ + rl longstring /"'''" longstringitem* :>> "'''" | '"""' longstringitem* :>> '"""'/ + rl shortstring /"'" shortstringitem_s* "'" | '"' shortstringitem_d* '"'/ + rl stringprefix /"r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"/ + token stringliteral /stringprefix? (shortstring | longstring)/ + + # Integers + rl hexdigit /digit | 'a'..'f' | 'A'..'F'/ + rl octdigit /'0'..'7'/ + rl nonzerodigit /'1'..'9'/ + rl hexinteger /'0' ('x' | 'X') hexdigit+/ + rl octinteger /'0' octdigit+/ + rl decimalinteger /nonzerodigit digit* | '0'/ + token integer /decimalinteger | octinteger | hexinteger/ + token longinteger /integer ('l' | 'L')/ + + # Floats. + rl exponent /('e' | 'E') ('+' | '-')? digit+/ + rl fraction /'.' digit+/ + rl intpart /digit+/ + rl pointfloat /intpart? fraction | intpart '.'/ + rl exponentfloat /(intpart | pointfloat) exponent/ + token floatnumber /pointfloat | exponentfloat/ + + # Imaginaries. + token imagnumber /(floatnumber | intpart) ("j" | "J")/ + + # Operators. + literal `+ `- `* `** `/ `// `% `<< `>> `& `| `^ + `~ `< `> `<= `>= `== `!= `<> + + # Delimiters + literal `( `) `[ `] `{ `} `@ `, `: `. `` `= `; + `+= `-= `*= `/= `//= `%= `&= `|= `^= `>>= `<<= + `**= + + literal `... + + # In general whitespace is ignored. + ignore WS /' '+/ + + # Find and ignore entire blank lines. + token BLANK_LINE + / '\n' [ \t]* ('#' [^\n]*)? '\n' / + { + # Need to shorten to take off the newline. + # Turn it into ignore. + input->push_ignore( make_token( typeid<WS> input->pull(match_length - 1) ) ) + } + + # Find and ignore comments. + token COMMENT + / '#' [^\n]* '\n' / + { + # Need to shorten to take off the newline. Turn it into ignore. + input->push_ignore( make_token( typeid<WS> input->pull(match_length - 1) ) ) + } + + # These tokens are generated + token INDENT // + token DEDENT // + token NEWLINE // + ignore IND_WS // + + token INDENTATION + /'\n' [ \t]*/ + { + # We have squared up INDENTs and DEDENTs. Ignore the entire match. + input->push_ignore( make_token( typeid<WS> input->pull(match_length) ) ) + + # We have already sent the newline, compute the indentation level. + data_length: int = match_length - 1 + + Top: int_el = IndentStack->top + if data_length > Top->Int { + # The indentation level is more than the level on the top + # of the stack. This is an indent event. Send as an INDENT. + input->push( make_token( typeid<INDENT> '' ) ) + + # Push to the stack as per python manual. + IntEl: int_el = new int_el + IntEl->Int = data_length + IndentStack->push( IntEl ) + } else { + while data_length < Top->Int { + # The indentation level is less than the level on the top of + # the stack. Pop the level and send one dedent. This flow of + # control will execute until we find the right indentation level + # to match up with. + IndentStack->pop() + + # Send as a DEDENT + input->push( make_token( typeid<DEDENT> '' ) ) + + Top = IndentStack->top + } + } + + # FIXME: if data.length is now > top of stack then error. This + # means the outdent does not match anything. + + # First the newline. + input->push( make_token( typeid<NEWLINE> '' ) ) + } + end + + # Blank lines or comment lines at the beginning of the file. + token LEADER / ( [ \t]* ('#' [^\n]*)? '\n' )* / + + # Ordering productions for resolving ambiguities. + def O1 [] + def O2 [] + + def start + [file_input] + + def file_input + [file_input_forms*] + + def file_input_forms + [statement] + | [NEWLINE] + + def statement + [stmt_list NEWLINE] + | [compound_stmt] + + def stmt_list + [simple_stmt another_stmt* opt_semi] + + def another_stmt + [`; simple_stmt] + + def opt_semi + [`;] + | [] + + def suite + [stmt_list NEWLINE] + | [NEWLINE INDENT statement_seq DEDENT] + + def statement_seq + [statement_seq statement] + | [statement] + + def compound_stmt + [if_stmt] + | [while_stmt] + | [for_stmt] + | [funcdef] + + def if_stmt + [`if expression `: suite elif_part* opt_else_part] + + def elif_part + [`elif expression `: suite] + + def opt_else_part + [`else `: suite] + | [] + + def while_stmt + [`while expression `: suite opt_else_part] + + def for_stmt + [`for target_list `in expression_list `: suite opt_else_part] + + def funcdef + [`def funcname `( opt_parameter_list `) `: suite] + + def funcname + [identifier] + + def dotted_name + [dotted_name `. identifier] + | [identifier] + + def opt_parameter_list + [parameter_list] + | [] + + def parameter_list + [defparameter_list defparameter opt_comma] + + def defparameter_list + [defparameter_list defparameter `,] + | [] + + def defparameter + [parameter] + | [parameter `= expression] + + def sublist + [sublist_pl opt_comma] + + def sublist_pl + [sublist_pl `, parameter] + | [parameter] + + def parameter + [identifier] + | [`( sublist `)] + + def classname + [identifier] + + def simple_stmt + [expression_stmt] + | [assignment_stmt] + | [print_stmt] + + def expression_stmt + [expression_list] + + def assignment_stmt + [target_equals_list expression_list] + + def target_equals_list + [target_equals_list target_equals] + | [target_equals] + + def target_equals + [target_list `=] + + def target_list + [target_list_core opt_comma] + + def target_list_core + [target_list_core `, target] + | [target] + + def target + [target_atom target_ext_rep] + + def target_atom + [identifier] + | [`( target_list `)] + | [`[ target_list `]] + + def target_ext_rep + [target_ext target_ext_rep] + | [] + + def target_ext + [attributeref] + | [O1 subscription] + | [O2 slicing] + + def print_stmt + [`print opt_expression_list] + + def opt_expression_list + [expression_list] + | [] + + def expression_list + [expression_list_core opt_comma] + + def expression_list_core + [expression_list_core `, expression] + | [expression] + + def opt_comma + [`,] + | [] + + def expression + [or_test `if or_test `else test] + | [or_test] + | [lambda_form] + + def or_test + [or_test `or and_test] + | [and_test] + + def and_test + [and_test `and not_test] + | [not_test] + + def not_test + [comparison] + | [`not not_test] + + def lambda_form + [`lambda opt_parameter_list `: expression] + + def test + [or_test] + | [lambda_form] + + def comparison + [or_expr comparison_part*] + + def comparison_part + [comp_operator or_expr] + + def comp_operator + [`<] | [`>] | [`==] | [`>=] | [`<=] | [`<>] | [`!=] | [`is] | + [`is `not] | [`in] | [`not `in] + + def or_expr + [primary] + + def primary + [atom primary_ext_rep] + + def atom + [identifier] + | [pyliteral] + | [enclosure] + + def primary_ext_rep + [primary_ext primary_ext_rep] + | [] + + def primary_ext + [attributeref] + | [O1 subscription] + | [O2 slicing] + | [call] + + def pyliteral + [stringliteral] + | [integer] + | [longinteger] + | [floatnumber] + | [imagnumber] + + def enclosure + [parenth_form] + | [list_display] + | [generator_expression] + | [dict_display] + | [string_conversion] + + def parenth_form + [`( opt_expression_list `)] + + def list_display + [`[ opt_listmaker `]] + + def opt_listmaker + [listmaker] + | [] + + def listmaker + [expression list_for] + | [expression listmaker_ext* opt_comma] + + def listmaker_ext + [`, expression] + + def opt_list_iter + [list_iter] + | [] + + def list_iter + [list_for] + | [list_if] + + def list_if + [`if test opt_list_iter] + + def list_for + [`for expression_list `in testlist opt_list_iter] + + def testlist + [test testlist_ext* opt_comma] + + def testlist_ext + [`, test ] + + def generator_expression + [`( test genexpr_for `)] + + def genexpr_for + [`for expression_list `in test opt_genexpr_iter] + + def opt_genexpr_iter + [genexpr_iter] + | [] + + def genexpr_iter + [genexpr_for] + | [genexpr_if] + + def genexpr_if + [`if test opt_genexpr_iter] + + def dict_display + [`{ opt_key_datum_list `}] + + def opt_key_datum_list + [key_datum_list] + | [] + + def key_datum_list + [key_datum key_datum_list_ext* opt_comma] + + def key_datum_list_ext + [`, key_datum] + + def key_datum + [expression `: expression] + + def string_conversion + [`` expression_list ``] + + def attributeref + [`. identifier] + + def subscription + [`[ expression_list `]] + + # The natural ordered choice does not suffice here. Must force it. + + def slicing + [simple_slicing] + | [extended_slicing] + + def simple_slicing + [`[ short_slice `]] + + def extended_slicing + [`[ slice_list `]] + + def slice_list + [slice_item slice_list_ext* opt_comma] + + def slice_list_ext + [`, slice_item] + + def slice_item + [expression] + | [proper_slice] + | [ellipsis] + + def proper_slice + [short_slice] + | [long_slice] + + def short_slice + [`:] + | [`: upper_bound] + | [lower_bound `:] + | [lower_bound `: upper_bound] + + def long_slice + [short_slice `: stride] + | [short_slice `:] + + def lower_bound + [expression] + + def upper_bound + [expression] + + def stride + [expression] + + def ellipsis + [`...] + + def call + [`( opt_argument_list `)] + + def opt_argument_list + [argument_list opt_comma] + | [] + + def argument_list + [positional_arguments opt_comma_keyword_arguments] + | [keyword_arguments] + + def positional_arguments + [positional_arguments `, expression] + | [expression] + + def opt_comma_keyword_arguments + [`, keyword_arguments] + | [] + + def keyword_arguments + [keyword_arguments `, keyword_item] + | [keyword_item] + + def keyword_item + [identifier `= expression] + +end # generate + +int print_stmts( S: generate::start ) +{ + for Stmt: generate::statement in S + print( 'STMT: ' ^Stmt '\n' ) +} + +int print_target_subscriptions_and_slicings( Start: generate::start ) +{ + for TI: generate::target_ext in Start { + if match TI [generate::subscription] { + print( 'TARGET SUBSCRIPTION: ' ^TI '\n' ) + } + + if match TI [generate::simple_slicing] { + print( 'TARGET SIMPLE SLICING: ' ^TI '\n' ) + } + + if match TI [generate::extended_slicing] { + print( 'TARGET EXTENDED SLICING: ' ^TI '\n' ) + } + } + +} + +int print_primary_subscriptions_and_slicings( Start: generate::start ) +{ + for PI: generate::primary_ext in Start { + if match PI [generate::subscription] { + print( 'PRIMARY SUBSCRIPTION: ' ^PI '\n' ) + } + + if match PI [generate::simple_slicing] { + print( 'PRIMARY SIMPLE SLICING: ' ^PI '\n' ) + } + + if match PI [generate::extended_slicing] { + print( 'PRIMARY EXTENDED SLICING: ' ^PI '\n' ) + } + } +} + +Generate: generate = new generate + +# List used as a stack of indentations. +Generate->IndentStack = new list<generate::int_el> +IntEl: generate::int_el = new generate::int_el +IntEl->Int = 0 +Generate->IndentStack->push( IntEl ) + +# Has a newline been sent for this '\n' .. whitespace match. +Generate->newline_sent = 0 + +parse S: generate::start(Generate)[ stdin ] + +print( '*** SUCCESS ***\n' ) +print( ^S '\n' ) +print( '***\n' ) +print_stmts( S ) +print_target_subscriptions_and_slicings( S ) +print_primary_subscriptions_and_slicings( S ) +print( '*** SUCCESS ***\n' ) +##### IN ##### + +# dude, this is a comment + # some more +hello +def dude(): + yes + awesome; + + # Here we have a comment + def realy_awesome(): # hi there + in_more + + same_level + def one_liner(): first; second # both inside one_liner + + back_down + +last_statement + +# dude, this is a comment + # some more +hello +if 1: + yes + awesome; + + # Here we have a comment + if ('hello'): # hi there + in_more + + same_level + if ['dude', 'dudess'].horsie(): first; second # both inside one_liner + 1 + + back_down + +last_statement + +hello = 1.1(20); + +# subscription +a[1] = b[2]; + +# simple slicing +c[1:1] = d[2:2]; + +# simple slicing +e[1:1, 2:2] = f[3:3, 4:4]; +##### EXP ##### +*** SUCCESS *** + +hello +def dude(): + yes + awesome; + + # Here we have a comment + def realy_awesome(): # hi there + in_more + + same_level + def one_liner(): first; second # both inside one_liner + + back_down + +last_statement + +# dude, this is a comment + # some more +hello +if 1: + yes + awesome; + + # Here we have a comment + if ('hello'): # hi there + in_more + + same_level + if ['dude', 'dudess'].horsie(): first; second # both inside one_liner + 1 + + back_down + +last_statement + +hello = 1.1(20); + +# subscription +a[1] = b[2]; + +# simple slicing +c[1:1] = d[2:2]; + +# simple slicing +e[1:1, 2:2] = f[3:3, 4:4]; +*** +STMT: hello +STMT: def dude(): + yes + awesome; + + # Here we have a comment + def realy_awesome(): # hi there + in_more + + same_level + def one_liner(): first; second # both inside one_liner + + back_down + +STMT: yes +STMT: awesome; + + # Here we have a comment +STMT: def realy_awesome(): # hi there + in_more + + same_level + def one_liner(): first; second # both inside one_liner + +STMT: in_more + +STMT: same_level +STMT: def one_liner(): first; second # both inside one_liner + +STMT: back_down + +STMT: last_statement + +# dude, this is a comment + # some more +STMT: hello +STMT: if 1: + yes + awesome; + + # Here we have a comment + if ('hello'): # hi there + in_more + + same_level + if ['dude', 'dudess'].horsie(): first; second # both inside one_liner + 1 + + back_down + +STMT: yes +STMT: awesome; + + # Here we have a comment +STMT: if ('hello'): # hi there + in_more + + same_level + if ['dude', 'dudess'].horsie(): first; second # both inside one_liner + 1 + +STMT: in_more + +STMT: same_level +STMT: if ['dude', 'dudess'].horsie(): first; second # both inside one_liner +STMT: 1 + +STMT: back_down + +STMT: last_statement + +STMT: hello = 1.1(20); + +# subscription +STMT: a[1] = b[2]; + +# simple slicing +STMT: c[1:1] = d[2:2]; + +# simple slicing +STMT: e[1:1, 2:2] = f[3:3, 4:4]; +TARGET SUBSCRIPTION: [1] +TARGET SIMPLE SLICING: [1:1] +TARGET EXTENDED SLICING: [1:1, 2:2] +PRIMARY SUBSCRIPTION: [2] +PRIMARY SIMPLE SLICING: [2:2] +PRIMARY EXTENDED SLICING: [3:3, 4:4] +*** SUCCESS *** diff --git a/test/generate2.lm b/test/generate2.lm new file mode 100644 index 00000000..1637044a --- /dev/null +++ b/test/generate2.lm @@ -0,0 +1,223 @@ +context generate + struct open_item + type: str + num: int + + list_el el + end + + open_item new_open_item( type: str num: int ) + { + OI: open_item = new open_item + OI->type = type + OI->num = num + return OI + } + + OpenStack: list<open_item> + + lex + token stray_close // + + token ocurly /'{'+/ + { + input->pull( match_length ) + + OI: open_item = new_open_item( '{' match_length ) + OpenStack->push( OI ) + i: int = 0 + while ( i < match_length ) { + input->push( make_token( typeid<ocurly> '{' ) ) + i = i + 1 + } + } + + token ccurly1 // + token ccurly2 // + token ccurly3 // + token missing_curly // + + token tmp1 /'}'+/ + { + if OpenStack->length > 0 && OpenStack->top->type == '{' { + length: int = 3 + if ( length > match_length ) + length = match_length + + Top: open_item = OpenStack->pop() + if ( length > Top->num ) + length = Top->num + + if ( length == 1 ) + input->push( make_token( typeid<ccurly1> input->pull( 1 ) ) ) + else if ( length == 2 ) + input->push( make_token( typeid<ccurly2> input->pull( 2 ) ) ) + else if ( length == 3 ) + input->push( make_token( typeid<ccurly3> input->pull( 3 ) ) ) + + Top->num = Top->num - length + + if ( Top->num > 0 ) + OpenStack->push( Top ) + } + else { + input->push( make_token( typeid<stray_close> input->pull( match_length ) ) ) + } + } + + token osquare /'['+/ + { + input->pull( match_length ) + OI: open_item = new_open_item( '[' match_length ) + OpenStack->push( OI ) + i: int = 0 + while ( i < match_length ) { + input->push( make_token( typeid<osquare> '[' ) ) + i = i + 1 + } + } + + token csquare1 // + token csquare2 // + token missing_square // + + token tmp2 /']'+/ + { + if OpenStack->length > 0 && OpenStack->top->type == '[' { + length: int = 2 + if ( length > match_length ) + length = match_length + + Top: open_item = OpenStack->pop() + if ( length > Top->num ) + length = Top->num + + if ( length == 1 ) + input->push( make_token( typeid<csquare1> input->pull( 1 ) ) ) + else if ( length == 2 ) + input->push( make_token( typeid<csquare2> input->pull( 2 ) ) ) + + Top->num = Top->num - length + + if ( Top->num > 0 ) + OpenStack->push( Top ) + } + else { + input->push( make_token( typeid<stray_close> input->pull( match_length ) ) ) + } + } + + literal `| + token char /any/ + + preeof { + while ( OpenStack->length > 0 ) { + Top: open_item = OpenStack->pop() + i: int + if ( Top->type == '{' ) { + i = 0 + while ( i < Top->num ) { + input->push( make_token( typeid<missing_curly> '}' ) ) + i = i + 1 + } + } + else if ( Top->type == '[' ) { + i = 0 + while ( i < Top->num ) { + input->push( make_token( typeid<missing_square> ']' ) ) + i = i + 1 + } + } + } + } + end + + # + # Internal Links + # + + + lex + literal `http: + literal `ftp: + literal `mailto: + end + + def el_prefix + [`http:] + | [`ftp:] + | [`mailto:] + + def external_link + [osquare item* csquare1] + + def internal_link + [osquare osquare item* csquare2] + + def unclosed_square + [osquare item* missing_square] + + # + # Templates + # + + def sing_template + [ocurly item* ccurly1] + + def template + [ocurly ocurly item* ccurly2] + + def parameter + [ocurly ocurly ocurly item* ccurly3] + + def unclosed_curly + [ocurly item* missing_curly] + + # + # Template Parameters + # + + + def U1 [] + def U2 [] + def U3 [] + + def item + [external_link] + | [internal_link] + | [unclosed_curly] + | [sing_template] + | [template] + | [parameter] + | [unclosed_curly] + | [stray_close] + | [osquare] + | [`|] + | [char] + + def start + [item*] + +end # generate + +Generate: generate = new generate + +Generate->OpenStack = new list<generate::open_item> +Sentinal: generate::open_item = new_open_item( '** SENTINAL **' 1 ) +Generate->OpenStack->push( Sentinal ) + +parse S: generate::start(Generate)[stdin] + +if S { + for I: generate::external_link in S + print( 'EXTERNAL LINK: ' I '\n' ) + + for I: generate::internal_link in S + print( 'INTERNAL LINK: ' I '\n' ) +} +##### IN ##### +[external] +[[internal]] +##### EXP ##### +EXTERNAL LINK: [external] +INTERNAL LINK: [[internal]] diff --git a/test/lookup1.lm b/test/lookup1.lm new file mode 100644 index 00000000..38902582 --- /dev/null +++ b/test/lookup1.lm @@ -0,0 +1,2594 @@ + +context lookup + struct list_lang_object_el + Obj: lang_object + list_el el + end + + alias list_lang_object + list<list_lang_object_el> + + alias list_declaration_data + list<declaration_data> + + alias list_declarator_data + list<declarator_data> + + struct list_int_el + Int: int + list_el el + end + + alias list_int + list<list_int_el> + + struct map_list_lang_object_el + List: list_lang_object + map_el<str> el + end + + alias map_list_lang_object + map<str map_list_lang_object_el> + + # + # Data types for global data. + # + + # Language objects. + struct lang_object + typeId: int + name: str + + # If the object is a typedef, this points to the real object. + typedefOf: lang_object + + objectMap: map_list_lang_object + inherited: list_lang_object + lookupParent: lang_object + specializationOf: lang_object + end + + # This structure is used to keep track of information necessary to make a + # declaration. While parsing a declaration it records the declaration's + # attributes. + struct declaration_data + isTypedef: int + isFriend: int + isTemplate: int + + typeObj: lang_object + + list_el el + end + + struct declarator_data + qualObj: lang_object + pdcScope: lang_object + lookupObj: lang_object + + list_el el + end + + # Constants for language object types. + NamespaceType: int + ClassType: int + TemplateClassType: int + EnumType: int + IdType: int + TypedefType: int + TemplateIdType: int + + # + # Global data declarations + # + + # Object stacks. + curNamespace: list_lang_object + declNs: list_lang_object + lookupNs: list_lang_object + qualNs: list_lang_object + templateParamNs: list_lang_object + + # Declaration, declarator data. + declarationData: list_declaration_data + declaratorData: list_declarator_data + + # Template declarations + templDecl: list_int + + # Root namespace object + rootNamespace: lang_object + + # + # Identifier lookup. + # + + # Lookup the token in the members of an object. + lang_object lookupInObject( obj: lang_object name: str ) + { + # LOG print( ' looking in ', obj->name, '\n' ) + + ol: map_list_lang_object_el = obj->objectMap->find( name ) + if ol { + # LOG print( ' * found an object: ', ol.head, '\n' ) + return ol->List->head->Obj + } + + return nil + } + + # Lookup in an object and all the objects beneath it in the inheritance + # tree. + lang_object lookupWithInheritance( obj: lang_object name: str ) + { + found: lang_object = lookupInObject( obj name ) + if found + return found + + localObjInherited: list_lang_object = obj->inherited + II: list_lang_object_el = localObjInherited->head + while II { + inh: lang_object = II->Obj + + # First check if the inherited object is the one we are after. + if inh->name == name && inh->typeId == ClassType { + # LOG print( ' * found a class name\n' ) + return inh + } + + # Otherwise look inside the inherited object. + found = lookupWithInheritance( inh name ) + if found + return found + + II = II->next + } + + return nil + } + + lang_object unqualifiedLookup( name: str ) + { + found: lang_object + + # Start with the objects in the templateParamNs. + localTemplateParamNs: list_lang_object = templateParamNs + TemplParaObjIter: list_lang_object_el = localTemplateParamNs->tail + while ( TemplParaObjIter ) { + found = lookupWithInheritance( TemplParaObjIter->Obj name ) + if found + break + TemplParaObjIter = TemplParaObjIter->prev + } + + if !found { + # Iterator over the objects starting at the head of the lookup stack + # and going up through the lookup parents. + lookupIn: lang_object = lookupNs->tail->Obj + while lookupIn { + found = lookupWithInheritance( lookupIn name ) + if found + break + lookupIn = lookupIn->lookupParent + } + } + + return found + } + + # The C++ scanner. + lex + rl fract_const / digit* '.' digit+ | digit+ '.' / + rl exponent / [eE] [+\-]? digit+ / + rl float_suffix / [flFL] / + + # Single and double literals. + token TK_SingleLit /( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )/ + token TK_DoubleLit /( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )/ + + literal `extern `namespace `friend `typedef `auto `register + `static `mutable `inline `virtual `explicit `const + `volatile `restrict `class `struct `union `template + `private `protected `public `using `void `char + `wchar_t `bool `int `float `double `short `long + `signed `unsigned `enum `new `delete `operator + `typename `export `throw `try `catch `sizeof + `dynamic_cast `static_cast `reinterpret_cast `const_cast + `typeid `this `true `false `switch `case `default + `if `else `while `do `for `break `continue + `return `goto + + # Extensions + literal `__typeof `__is_pod `__is_empty + + literal `{ `} `; `, `= `( `) `: `& `* `[ `] `~ `+ `- + `/ `< `> `| `^ `% `! `? `. + + literal `:: `== `!= `&& `|| `*= `/= `%= `+= `-= `&= + `^= `|= `++ `-- `-> `->* `.* `... `<<= `>>= + + # Token translation targets. + def unknown_id [lookup_id] + def class_id [lookup_id] + def namespace_id [lookup_id] + def templ_class_id [lookup_id] + def enum_id [lookup_id] + def typedef_id [lookup_id] + def identifier [lookup_id] + def template_id [lookup_id] + + # Identifiers + token lookup_id + obj: lang_object + qualObj: lang_object + + /( [a-zA-Z_] [a-zA-Z0-9_]* )/ + { + name: str = match_text + found: lang_object = nil + qualObj: lang_object = nil + if qualNs->tail->Obj { + # LOG print( 'qualified lookup of ', name, '\n' ) + + # Transfer the qualification to the token and reset it. + qualObj = qualNs->tail->Obj + qualNs->tail->Obj = nil + + # Lookup using the qualification. + found = lookupWithInheritance( qualObj name ) + } + else { + # No qualification, full search. + # LOG print( 'unqualified lookup of ', name, '\n' ) + found = unqualifiedLookup( name ) + } + + # If no match, return an Unknown ID + id: int = typeid<unknown_id> + if found + id = found->typeId + + LookupId: lookup_id = make_token( typeid<lookup_id> input->pull(match_length) ) + LookupId.obj = found + LookupId.qualObj = qualObj + + input->push( make_tree( id LookupId ) ) + } + + # Floats. + token TK_Float /( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? )/ + + # Integer decimal. Leading part buffered by float. + token TK_IntegerDecimal /( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} )/ + + # Integer octal. Leading part buffered by float. + token TK_IntegerOctal /( '0' [0-9]+ [ulUL]{0,2} )/ + + # Integer hex. Leading 0 buffered by float. + token TK_IntegerHex /( '0x' [0-9a-fA-F]+ [ulUL]{0,2} )/ + + # Preprocessor line. + ignore /'#' [^\n]* '\n'/ + + # Comments and whitespace. + ignore /( '/*' (any | '\n')* :>> '*/' )/ + ignore /( '//' any* :> '\n' )/ + ignore /( any - 33..126 )+/ + end + + # + # Support functions + # + + typeId: int + name: str + + # If the object is a typedef, this points to the real object. + typedefOf: lang_object + + objectMap: map_list_lang_object + inherited: list_lang_object + lookupParent: lang_object + specializationOf: lang_object + + lang_object createLangObject( typeId: int name: str lookupParent: lang_object ) + { + Obj: lang_object = new lang_object + + Obj->typeId = typeId + Obj->name = name + Obj->typedefOf = nil + Obj->objectMap = new map_list_lang_object + Obj->inherited = new list_lang_object + Obj->lookupParent = lookupParent + + return Obj + } + + # Building the language object tree. + int insertObject( definedIn: lang_object name: str obj: lang_object ) + { + ol: map_list_lang_object_el = definedIn->objectMap->find( name ) + if !ol { + # Element not in the map already + ol = new map_list_lang_object_el + ol->key = name + ol->List = new list_lang_object + definedIn->objectMap->insert( ol ) + } + E: list_lang_object_el = new list_lang_object_el + E->Obj = obj + ol->List->push_tail( E ) + } + + lang_object findClass( inObj: lang_object lang_objectname: str ) + { + ol: map_list_lang_object_el = inObj->objectMap->find( name ) + if ol { + ObjIter: list_lang_object_el = ol->List->head + while ( ObjIter ) { + obj: lang_object = ObjIter->Obj + if obj->typeId == ClassType { + return obj + } + ObjIter = ObjIter->next + } + } + return nil + } + + lang_object findTemplateClass( inObj: lang_object name: str ) + { + ol: map_list_lang_object_el = inObj->objectMap->find( name ) + if ol { + ObjIter: list_lang_object_el = ol->List->head + while ( ObjIter ) { + obj: lang_object = ObjIter->Obj + if obj->typeId == TemplateClassType + return obj + ObjIter = ObjIter->next + } + } + return nil + } + + def root_qual_opt + [] + | [`::] + + def nested_name_specifier_opt + [nested_name_specifier_opt qualifying_name `:: designated_qualifying_name `::] + | [nested_name_specifier_opt qualifying_name `::] + | [] + + def nested_name_specifier + [nested_name_specifier designated_qualifying_name `::] + | [nested_name_specifier qualifying_name `::] + | [qualifying_name `::] + + def qualifying_name + [class_name] + { + qualNs->tail->Obj = r1.lookupId.obj + } + + | [namespace_id] + { + match r1 [Id: lookup_id] + qualNs->tail->Obj = Id.obj + } + + | [typedef_id] + { + match r1 [Id: lookup_id] + qualNs->tail->Obj = Id.obj->typedefOf + } + + def designated_qualifying_name + [`template any_id] + { + # FIXME: nulling qualNs is not the right thing to do here. + qualNs->tail->Obj = nil + } + + | [`template any_id + templ_arg_open template_argument_list_opt templ_arg_close] + { + # FIXME: nulling qualNs is not the right thing to do here. + qualNs->tail->Obj = nil + } + + # + # Id Expression + # + + def id_expression + lookupId: lookup_id + + [root_qual_opt nested_name_specifier_opt unknown_id] + { + lhs.lookupId = lookup_id in r3 + } + + | [root_qual_opt nested_name_specifier_opt identifier] + { + lhs.lookupId = lookup_id in r3 + } + + | [root_qual_opt nested_name_specifier_opt operator_function_id] + { + # Normally the token translation transfers the qualification. Since + # the operator_function_id does not end in a lookup we must do it ourselves. + qualObj: lang_object = qualNs->tail->Obj + qualNs->tail->Obj = nil + + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<operator_function_id>' + lhs.lookupId.qualObj = qualObj + } + + | [root_qual_opt nested_name_specifier_opt conversion_function_id] + { + # Normally the token translation transfers the qualification. Since + # the operator_function_id does not } in a lookup we must do it ourselves. + qualObj: lang_object = qualNs->tail->Obj + qualNs->tail->Obj = nil + + # Do we need qual reset here becauase operator_function_id does not do it? + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<conversion_function_id>' + lhs.lookupId.qualObj = qualObj + } + + | [root_qual_opt nested_name_specifier_opt `~ class_name] + { + lhs.lookupId = r4.lookupId + } + + | [root_qual_opt nested_name_specifier_opt template_name] + { + lhs.lookupId = r3.lookupId + } + + def template_name + lookupId: lookup_id + + [template_id templ_arg_open template_argument_list_opt templ_arg_close] + { + lhs.lookupId = lookup_id in r1 + } + + | [template_id] + { + lhs.lookupId = lookup_id in r1 + } + + + # + # Class Names + # + + def class_name + lookupId: lookup_id + + [class_id] + { + lhs.lookupId = lookup_id in r1 + } + + | [templ_class_id] + { + lhs.lookupId = lookup_id in r1 + } + + | [templ_class_id templ_arg_open template_argument_list_opt templ_arg_close] + { + # TODO: Look for a specialization. + lhs.lookupId = lookup_id in r1 + } + + def templ_arg_open + [`<] + { + E: list_lang_object_el = new list_lang_object_el + E->Obj = nil + qualNs->push_tail( E ) + } + + def templ_arg_close + [`>] + { + qualNs->pop_tail() + } + + def declaration + [block_declaration] commit + | [function_definition] commit + | [template_declaration] commit + | [explicit_instantiation] commit + | [explicit_specialization] commit + | [linkage_specification] commit + | [namespace_definition] commit + + # + # Declarations + # + + def block_declaration + [simple_declaration] + | [using_declaration] + | [using_directive] + + def simple_declaration + [declaration_start simple_declaration_forms declaration_end `;] + + # Ordering is important for optimization. The form with the optional + # decl_specifier_sing should go second. + def simple_declaration_forms + [decl_specifier_mult_seq_opt decl_specifier_sing + decl_specifier_mult_seq_opt init_declarator_list_opt] + + | [decl_specifier_mult_seq_opt init_declarator_list_opt] + + def declaration_start + [] + { + # LOG print( 'opening new declaration_data with templDecl: ', templDecl.tail, '\n' ) + DD: declaration_data = new declaration_data + DD->isTypedef = 0 + DD->isFriend = 0 + DD->isTemplate = 0 + declarationData->push_tail( DD ) + + # Transfer the template flag and reset it. + declarationData->tail->isTemplate = templDecl->tail->Int + IntEl: list_int_el = new list_int_el + IntEl->Int = 0 + templDecl->push_tail( IntEl ) + } + + def declaration_end + [] + { + # LOG print( 'closing declaration_data\n' ) + declarationData->pop_tail() + templDecl->pop_tail() + } + + def decl_specifier_sing + [type_specifier_sing] + { + # Store the object type of the declaration (if any) for use + # by typedefs. + declarationData->tail->typeObj = r1.lookupId.obj + } + + def type_specifier_seq + lookupId: lookup_id + + [type_specifier_mult_seq_opt type_specifier_sing type_specifier_mult_seq_opt] + { + lhs.lookupId = r2.lookupId + } + + def type_specifier_sing + lookupId: lookup_id + + [simple_type_specifier] + { + lhs.lookupId = r1.lookupId + } + + | [class_specifier] + { + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<class_specifier>' + } + + | [enum_specifier] + { + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<enum_specifier>' + } + + | [elaborated_type_specifier] + { + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<elaborated_type_specifier>' + } + + # Type specifier sequence without enum specifier or class specifier. + def necs_type_specifier_seq + [type_specifier_mult_seq_opt necs_type_specifier_sing type_specifier_mult_seq_opt] + + # Type specifier singular without enum specifier or class specifier. + def necs_type_specifier_sing + [simple_type_specifier] + | [elaborated_type_specifier] + + def type_specifier_mult_seq_opt + [type_specifier_mult_seq_opt type_specifier_mult] + | [] + + def type_specifier_mult_seq + [type_specifier_mult_seq type_specifier_mult] + | [type_specifier_mult] + + def simple_type_specifier + lookupId: lookup_id + + [simple_type_specifier_name] + { + lhs.lookupId = r1.lookupId + } + + | [simple_type_specifier_kw_seq] + { + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<simple_type_specifier_kw_seq>' + } + + | [`typename root_qual_opt nested_name_specifier type_name] + { + lhs.lookupId = r4.lookupId + } + + | [`typename root_qual_opt nested_name_specifier identifier] + { + lhs.lookupId = lookup_id in r4 + } + + | [`typename root_qual_opt nested_name_specifier unknown_id] + { + lhs.lookupId = lookup_id in r4 + } + + # Extension. + | [`__typeof `( expression `)] + { + lhs.lookupId = construct lookup_id ["x"] + lhs.lookupId.data = '<simple_type_specifier_kw_seq>' + } + + def simple_type_specifier_name + lookupId: lookup_id + + [qual_type_name] + { + lhs.lookupId = r1.lookupId + } + + def simple_type_specifier_kw_seq + [simple_type_specifier_kw_seq simple_type_specifier_kw] + | [simple_type_specifier_kw] + + def simple_type_specifier_kw + [`void] + | [`char] + | [`wchar_t] + | [`bool] + | [`int] + | [`float] + | [`double] + | [`short] + | [`long] + | [`signed] + | [`unsigned] + + def qual_type_name + lookupId: lookup_id + + [root_qual_opt nested_name_specifier_opt type_name] + { + lhs.lookupId = r3.lookupId + } + + def type_name + lookupId: lookup_id + + [class_name] + { + lhs.lookupId = r1.lookupId + } + + | [enum_id] + { + lhs.lookupId = lookup_id in r1 + } + + | [typedef_id] + { + lhs.lookupId = lookup_id in r1 + } + + # NOTE: the typename case is moved to simple type specifier + # to take advantage of its conflict resolution. + def elaborated_type_specifier + [class_key nested_name_specifier_opt class_head_name] + { + Id: lookup_id = lookup_id in r3 + name: str = Id.data + + # Get the ns the class is declared in. + parentObj: lang_object = declNs->tail->Obj + if Id.qualObj + parentObj = Id.qualObj + + # Look for the class in the given scope. + declaredClass: lang_object = findClass( parentObj name ) + if !declaredClass + declaredClass = findTemplateClass( parentObj name ) + + if !declaredClass { + # LOG print( 'creating new class: ', name, '\n' ) + + # Class does not exist in the parent scope, create it. + nsType: int = declaredClassType() + + declaredClass = createLangObject( nsType name lookupNs->tail->Obj ) + + # FIXME: handle friends. Make the class visible only if we are NOT + # in a friend declaration. The new class object is necessary to + # properly process the body of the class. + if declarationData->tail->isFriend == 0 + insertObject( parentObj name declaredClass ) + } + } + + # TODO: Lookup type specialization. + | [class_key nested_name_specifier_opt templ_class_id + templ_arg_open template_argument_list_opt templ_arg_close] + + | [`enum nested_name_specifier_opt enum_head_name] + { + # TODO: should look for existing enums of the same name. + Id: lookup_id = lookup_id in r3 + # LOG print( 'creating enumeration ' Id.data '\n' ) + enum: lang_object = createLangObject( EnumType Id.data lookupNs->tail->Obj ) + insertObject( declNs->tail->Obj Id.data enum ) + } + + def decl_specifier_mult_seq_opt + [decl_specifier_mult_seq_opt decl_specifier_mult] + | [] + + def decl_specifier_mult_seq + [decl_specifier_mult_seq decl_specifier_mult] + | [decl_specifier_mult] + + def decl_specifier_mult + [type_specifier_mult] + | [storage_class_specifier] + | [function_specifier] + + | [`friend] + { + declarationData->tail->isFriend = 1 + } + + | [`typedef] + { + declarationData->tail->isTypedef = 1 + } + + def storage_class_specifier + [`auto] + | [`register] + | [`static] + | [`extern] + | [`mutable] + + def function_specifier + [`inline] + | [`virtual] + | [`explicit] + + def type_specifier_mult + [cv_qualifier] + + def cv_qualifier + [`const] + | [`volatile] + | [`restrict] + + def cv_qualifier_rep + [cv_qualifier_rep cv_qualifier] + | [] + + def namespace_definition + [named_namespace_definition] + | [unnamed_namespace_definition] + + def named_namespace_definition + [original_namespace_definition] + | [extension_namespace_definition] + + # + # Enumerations + # + + def enum_specifier + [`enum nested_name_specifier_opt + enum_head_name `{ enumerator_list_opt `}] + { + # TODO: should look for existing enums of the same name. + Id: lookup_id = lookup_id in r3 + # LOG print( 'creating enumeration ' Id.data '\n' ) + enum: lang_object = createLangObject( EnumType Id.data lookupNs->tail->Obj ) + insertObject( declNs->tail->Obj Id.data enum ) + } + + | [`enum `{ enumerator_list_opt `}] + + def enum_head_name + [class_id] + | [templ_class_id] + | [namespace_id] + | [typedef_id] + | [enum_id] + | [identifier] + | [template_id] + | [unknown_id] + + def enumerator_list_opt + [enumerator_list] + | [enumerator_list `,] + | [] + + def enumerator_list + [enumerator_list `, enumerator_definition] + | [enumerator_definition] + + def enumerator_definition + [enumerator_id] + { + Id: lookup_id = lookup_id in r1 + enumId: lang_object = createLangObject( IdType Id.data lookupNs->tail->Obj ) + insertObject( declNs->tail->Obj Id.data enumId ) + } + + | [enumerator_id `= constant_expression] + { + Id: lookup_id = lookup_id in r1 + enumId: lang_object = createLangObject( IdType Id.data lookupNs->tail->Obj ) + insertObject( declNs->tail->Obj Id.data enumId ) + } + + def enumerator_id + [namespace_id] + | [typedef_id] + | [enum_id] + | [class_id] + | [templ_class_id] + | [template_id] + | [identifier] + | [unknown_id] + + # + # Declarators + # + + def init_declarator_list_opt + [init_declarator_list] + | [] + + def init_declarator_list + [init_declarator_list `, init_declarator] + | [init_declarator] + + def init_declarator + [declarator initializer_opt] + + def initializer_opt + [`= initializer_clause] + | [`( expression `)] + | [] + + def initializer_clause + [assignment_expression] + | [`{ initializer_list `}] + | [`{ initializer_list `, `}] + | [`{ `}] + + def initializer_list + [initializer_list `, initializer_clause] + | [initializer_clause] + + # + # Expressions + # + + def expression + [expression `, assignment_expression] + | [assignment_expression] + + def expression_opt + [expression] + | [] + + def constant_expression + [conditional_expression] + + def constant_expression_opt + [constant_expression] + | [] + + def assignment_expression + [conditional_expression] + | [logical_or_expression assignment_op assignment_expression] + | [throw_expression] + + def assignment_op + [`=] + | [`*=] + | [`/=] + | [`%=] + | [`+=] + | [`-=] + | [`>>=] + | [`<<=] + | [`&=] + | [`^=] + | [`|=] + + def conditional_expression + [logical_or_expression] + | [logical_or_expression `? expression `: assignment_expression] + + def logical_or_expression + [logical_or_expression `|| logical_and_expression] + | [logical_and_expression] + + def logical_and_expression + [logical_and_expression `&& inclusive_or_expression] + | [inclusive_or_expression] + + def inclusive_or_expression + [inclusive_or_expression `| exclusive_or_expression] + | [exclusive_or_expression] + + def exclusive_or_expression + [exclusive_or_expression `^ and_expression] + | [and_expression] + + def and_expression + [and_expression `& equality_expression] + | [equality_expression] + + def equality_expression + [equality_expression `== relational_expression] + | [equality_expression `!= relational_expression] + | [relational_expression] + + def relational_expression + [relational_expression `< shift_expression] + | [relational_expression `> shift_expression] + | [relational_expression lt_eq shift_expression] + | [relational_expression gt_eq shift_expression] + | [shift_expression] + + def shift_expression + [shift_expression shift_left additive_expression] + | [shift_expression shift_right additive_expression] + | [additive_expression] + + def additive_expression + [additive_expression `+ multiplicative_expression] + | [additive_expression `- multiplicative_expression] + | [multiplicative_expression] + + def multiplicative_expression + [multiplicative_expression `* pm_expression] + | [multiplicative_expression `/ pm_expression] + | [multiplicative_expression `% pm_expression] + | [pm_expression] + + def pm_expression + [pm_expression `->* cast_expression] + | [pm_expression `.* cast_expression] + | [cast_expression] + + def cast_expression + [unary_expression] + | [`( type_id `) cast_expression] + + def delete_expression + [root_qual_opt `delete cast_expression] + | [root_qual_opt `delete `[ `] cast_expression] + + def new_initializer_opt + [new_initializer] + | [] + + def new_initializer + [`( expression_opt `)] + + def direct_new_declarator + [`[ expression `]] + | [direct_new_declarator `[ constant_expression `]] + + def new_declarator_opt + [new_declarator] + | [] + + def new_declarator + [direct_new_declarator] + | [ptr_operator_seq direct_new_declarator] + | [ptr_operator_seq] + + def new_type_id + [necs_type_specifier_seq new_declarator_opt] + + def new_placement + [`( expression `)] + + def new_expression + [root_qual_opt `new new_type_id new_initializer_opt] + | [root_qual_opt `new new_placement new_type_id new_initializer_opt] + | [root_qual_opt `new `( type_id `) new_initializer_opt] + | [root_qual_opt `new new_placement `( type_id `) new_initializer_opt] + + def unary_operator + [`*] + | [`&] + | [`+] + | [`-] + | [`!] + | [`~] + + def unary_expression + [postfix_expression] + | [`++ cast_expression] + | [`-- cast_expression] + | [unary_operator cast_expression] + | [`sizeof `( type_id `)] + | [`sizeof unary_expression] + | [new_expression] + | [delete_expression] + + def function_style_type_conv + [simple_type_specifier] + + + def postfix_expression + [primary_expression] + | [postfix_expression `[ expression `]] + | [postfix_expression `( expression_opt `)] + | [function_style_type_conv `( expression_opt `)] + | [member_request_expr dot_arrow id_expression] + | [member_request_expr dot_arrow pseudo_destructor_call] + | [postfix_expression `++] + | [postfix_expression `--] + | [`dynamic_cast templ_arg_open type_id templ_arg_close `( expression `)] + | [`static_cast templ_arg_open type_id templ_arg_close `( expression `)] + | [`reinterpret_cast templ_arg_open type_id templ_arg_close `( expression `)] + | [`const_cast templ_arg_open type_id templ_arg_close `( expression `)] + | [`typeid `( expression `)] + | [`typeid `( type_id `)] + + def pseudo_destructor_call + [root_qual_opt nested_name_specifier_opt `~ pdc_type_name] + + def primary_expression + [expr_lit] + | [`this] + | [`( expression `)] + | [id_expression] + # GNU extensions + | [`( `{ statement_rep `} `)] + | [`__is_pod `( type_id `)] + | [`__is_empty `( type_id `)] + + def expr_lit + [TK_IntegerDecimal] + | [TK_IntegerOctal] + | [TK_IntegerHex] + | [TK_SingleLit] + | [TK_Float] + | [double_lit_list] + | [`true] + | [`false] + + def double_lit_list + [TK_DoubleLit double_lit_list] + | [TK_DoubleLit] + + def member_request_expr + [postfix_expression] + # { + # # FIXME: If no proper type is found, we must fail. + # # LOG print( 'setting member request scope\n' ) + # # qualNs.set( $1->type != 0 ? $1->type->getObject() : 0 ); + # } + + def dot_arrow + [`->] + | [`.] + + def pdc_type_name + [enum_id] + | [typedef_id] + + # + # Statements + # + + def statement_rep + [statement_rep statement] + | [] + + def statement + [declaration_statement] + | [labeled_statement] + | [expression_statement] + | [compound_statement] + | [selection_statement] + | [iteration_statement] + | [jump_statement] + | [try_block] + + def labeled_statement + [label_id `: statement] + | [`case constant_expression `: statement] + | [`default `: statement] + + def label_id + [unknown_id] + | [identifier] + | [class_id] + | [templ_class_id] + | [namespace_id] + | [typedef_id] + | [enum_id] + | [template_id] + + def compound_statement + [`{ compound_begin statement_rep compound_end `}] + + def compound_begin + [] + { + newCompound: lang_object = createLangObject( 0 '<compound_begin>' lookupNs->tail->Obj ) + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = newCompound + lookupNs->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = newCompound + declNs->push_tail( E2 ) + # LOG print( 'opening <compound>\n' ) + } + + def compound_end + [] + { + lookupNs->pop_tail() + declNs->pop_tail() + # LOG print( 'closing <compound>\n' ) + } + + def selection_statement + [`if `( condition `) statement elseif_clauses else_clause] + | [`switch `( condition `) statement] + + def elseif_clauses + [elseif_clauses `else `if `( condition `) statement] + | [] + + def else_clause + [`else statement] + | [] + + def iteration_statement + [`while `( condition `) statement] + | [`do statement `while `( expression `) `;] + | [`for `( for_init_statement condition_opt `; expression_opt `) statement] + + def jump_statement + [`break `;] + | [`continue `;] + | [`return expression_opt `;] + | [`goto any_id `;] + + def any_id + [unknown_id] + | [class_id] + | [namespace_id] + | [templ_class_id] + | [enum_id] + | [typedef_id] + | [identifier] + | [template_id] + + + def for_init_statement + [expression_statement] + | [stmt_block_declaration_forms `;] + + def condition + [expression] + | [type_specifier_seq declarator `= assignment_expression] + + def condition_opt + [condition] + | [] + + def expression_statement + [expression `;] + | [`;] + + def declaration_statement + [stmt_block_declaration] + + def stmt_block_declaration + [declaration_start stmt_block_declaration_forms declaration_end `;] + | [using_declaration] + | [using_directive] + + def stmt_block_declaration_forms + [decl_specifier_mult_seq_opt decl_specifier_sing decl_specifier_mult_seq_opt + init_declarator_list_opt] + | [decl_specifier_mult_seq init_declarator_list_opt] + + # + # Declarators + # + + def declarator + lookupObj: lang_object + + [ptr_operator_seq_opt declarator_id decl_array_or_param_rep declarator_end] + { + lhs.lookupObj = r4.lookupObj + } + + | [ptr_operator_seq_opt `( sub_declarator `) decl_array_or_param_rep declarator_end] + { + lhs.lookupObj = r6.lookupObj + } + + def sub_declarator + [ptr_operator_seq declarator_id decl_array_or_param_rep] + | [ptr_operator_seq `( sub_declarator `) decl_array_or_param_rep] + | [`( sub_declarator `) decl_array_or_param_rep] + | [declarator_id decl_array_or_param_rep] + + def decl_array_or_param_rep + [decl_array_or_param_rep decl_array_or_param] + | [] + + def decl_array_or_param + [`[ constant_expression_opt `]] + | [`( parameter_declaration_clause `) cv_qualifier_rep exception_specification_opt] + + def declarator_id + [declarator_id_forms] + { + name: str = r1.lookupId.data + qualObj: lang_object = r1.lookupId.qualObj + + parentObj: lang_object = declNs->tail->Obj + if qualObj { + parentObj = qualObj + } + + # Decide if we are declaring a constructor/destructor. + isConstructor: bool + if parentObj == r1.lookupId.obj { + isConstructor = true + # LOG print( 'making declarator ' name ' a constructor/destructor\n' ) + } + + if parentObj->specializationOf && + parentObj->specializationOf == r1.lookupId.obj + { + isConstructor = true + # LOG print( 'making declarator ' name ' a constructor/destructor\n' ) + } + + obj: lang_object = nil + if name && !isConstructor && declarationData->tail->isFriend == 0 { + if declarationData->tail->isTypedef { + obj = createLangObject( TypedefType name lookupNs->tail->Obj ) + obj->typedefOf = declarationData->tail->typeObj + insertObject( parentObj name obj ) + + # LOG print( 'making declarator ' name ' a typedef\n' ) + } + else { + if !qualObj { + if declarationData->tail->isTemplate { + # If in a template declaration and the name is not qualified then + # create the template id. + obj = createLangObject( TemplateIdType name lookupNs->tail->Obj ) + #object->objType = declarationData.tail.type + insertObject( declNs->tail->Obj name obj ) + + # LOG print( 'making declarator ' name ' a template id\n' ) + } + else { + obj = createLangObject( IdType name lookupNs->tail->Obj ) + #object->objType = declarationData.tail().type; + insertObject( declNs->tail->Obj name obj ) + + # LOG print( 'making declarator ' name ' an id\n' ) + } + } + } + } + + + DD: declarator_data = new declarator_data + DD->qualObj = qualObj + DD->pdcScope = nil + DD->lookupObj = lookupNs->tail->Obj + + declaratorData->push_tail( DD ) + + # If the declarator is qualified, push the qualification to the lookup + # stack. Also save it in the declarator data so it can be passed to a + # function body if needed. + if qualObj { + E: list_lang_object_el = new list_lang_object_el + E->Obj = qualObj + lookupNs->push_tail( E ) + declaratorData->tail->lookupObj = qualObj + } + + # LOG print( 'reduced declarator_id: ' name '\n' ) + } + + # Undoes the setup done by declarator_id and pdc_start. + def declarator_end + lookupObj: lang_object + + [] + { + # Get the lookupObject from the scope and pass it up. If we are about to + # parse a function body it will be needed. + lhs.lookupObj = declaratorData->tail->lookupObj + + pdcScope: lang_object = declaratorData->tail->pdcScope + qualObj: lang_object = declaratorData->tail->qualObj + + declaratorData->pop_tail() + + if pdcScope { + # LOG print( 'closing <pdc_scope>\n' ) + lookupNs->pop_tail() + declNs->pop_tail() + } + + if qualObj { + # LOG print( 'popping lookupNs\n' ) + lookupNs->pop_tail() + } + } + + def declarator_id_forms + lookupId: lookup_id + + [id_expression] + { + lhs.lookupId = r1.lookupId + } + + | [root_qual_opt nested_name_specifier_opt type_name] + { + lhs.lookupId = r3.lookupId + } + + | [root_qual_opt nested_name_specifier_opt `~ class_id] + { + lhs.lookupId = lookup_id in r4 + } + + | [root_qual_opt nested_name_specifier_opt `~ templ_class_id] + { + lhs.lookupId = lookup_id in r4 + } + | [root_qual_opt nested_name_specifier_opt `~ unknown_id] + { + lhs.lookupId = lookup_id in r4 + } + + def type_id + lookupId: lookup_id + + [type_specifier_seq abstract_declarator_opt] + { + lhs.lookupId = r1.lookupId + } + + def abstract_declarator_opt + [abstract_declarator] + | [] + + def abstract_declarator + [ptr_operator_seq abstract_noid abstract_decl_array_or_param_seq_opt declarator_end] + | [ptr_operator_seq `( sub_abstract_declarator `) + abstract_decl_array_or_param_seq_opt declarator_end] + | [abstract_noid abstract_decl_array_or_param_seq declarator_end] + | [`( sub_abstract_declarator `) abstract_decl_array_or_param_seq_opt declarator_end] + + def sub_abstract_declarator + [ptr_operator_seq abstract_noid abstract_decl_array_or_param_seq_opt] + + | [ptr_operator_seq `( sub_abstract_declarator `) + abstract_decl_array_or_param_seq_opt] + + | [`( sub_abstract_declarator `) abstract_decl_array_or_param_seq_opt] + + def abstract_noid + [] + { + # Make scope for declarator. + DD: declarator_data = new declarator_data + declaratorData->push_tail( DD ) + } + + def abstract_decl_array_or_param_seq_opt + [abstract_decl_array_or_param_seq_opt abstract_decl_array_or_param] + | [] + + def abstract_decl_array_or_param_seq + [abstract_decl_array_or_param_seq abstract_decl_array_or_param] + | [abstract_decl_array_or_param] + + def abstract_decl_array_or_param + [`[ constant_expression_opt `]] + | [`( parameter_declaration_clause `) cv_qualifier_rep + exception_specification_opt] + + def parameter_declaration_clause + [pdc_start parameter_declaration_list] + | [pdc_start parameter_declaration_list `...] + | [pdc_start parameter_declaration_list `, `...] + | [pdc_start `...] + | [pdc_start] + + def pdc_start + [] + { + if !declaratorData->tail->pdcScope { + # We are going to need a scope for the declarator. + pdcScope: lang_object = createLangObject( 0 '<pdc_scope>' lookupNs->tail->Obj ) + + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = pdcScope + lookupNs->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = pdcScope + declNs->push_tail( E2 ) + + declaratorData->tail->pdcScope = pdcScope + declaratorData->tail->lookupObj = pdcScope + # LOG print( 'opening <pdc_scope>\n' ) + } + } + + def parameter_declaration_list + [parameter_declaration_list `, parameter_declaration] + | [parameter_declaration] + + def parameter_declaration + [declaration_start parameter_declaration_forms declaration_end] + + # Ordering the productions such that decl_specifier_sing is tried first is good + # for performance. + def parameter_declaration_forms + [decl_specifier_mult_seq_opt decl_specifier_sing decl_specifier_mult_seq_opt + param_maybe_declarator maybe_parameter_init] + + | [decl_specifier_mult_seq param_maybe_declarator maybe_parameter_init] + + def param_maybe_declarator + [abstract_declarator] + | [declarator] + | [] + + def maybe_parameter_init + [`= constant_expression] + | [] + + def ptr_operator + [`&] + | [root_qual_opt nested_name_specifier_opt `* cv_qualifier_rep] + + def ptr_operator_seq + [ptr_operator_seq ptr_operator] + | [ptr_operator] + + def ptr_operator_seq_opt + [ptr_operator_seq_opt ptr_operator] + | [] + + # + # Functions + # + + def function_definition + [function_def_declaration ctor_initializer_opt function_body function_def_end] + + def function_def_declaration + [declaration_start function_def_declaration_forms declaration_end] + + def function_def_declaration_forms + [decl_specifier_mult_seq_opt decl_specifier_sing + decl_specifier_mult_seq_opt function_def_declarator] + | [decl_specifier_mult_seq function_def_declarator] + | [function_def_declarator] + + def function_def_declarator + [declarator] + { + # The lookupObj from the declarator is the deepest lookup object found + # while parsing the declarator. Make it visible in the function body. + # This could be the args, the qualObj, or the parent to the function. + E: list_lang_object_el = new list_lang_object_el + E->Obj = r1.lookupObj + lookupNs->push_tail( E ) + } + + def function_def_end + [] + { + # Pop the lookup object. + lookupNs->pop_tail() + } + + def function_body + [function_body_begin `{ statement_rep function_body_end `}] + + def function_body_begin + [] + { + newFunctionBody: lang_object = createLangObject( 0 + '<function_body_begin>' lookupNs->tail->Obj ) + + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = newFunctionBody + lookupNs->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = newFunctionBody + declNs->push_tail( E2 ) + + IntEl: list_int_el = new list_int_el + IntEl->Int = 0 + templDecl->push_tail( IntEl ) + # LOG print( 'opening <function_body>\n' ) + } + + def function_body_end + [] + { + # First undoes the function body begin work. Then undoes the setup in + # function_def_declarator. + declNs->pop_tail() + lookupNs->pop_tail() + templDecl->pop_tail() + # LOG print( 'closing <function_body>\n' ) + } + + + + # + # Classs + # + + int declaredClassType() + { + if declarationData->tail->isTemplate { + return TemplateClassType + } else { + return ClassType + } + } + + def class_specifier + [class_head base_clause_opt `{ class_member_rep class_body_end `}] + { + # FIXME: reparse not implemented yet + # FIXME FIXME: reparse is actually implemented now implemented + # # Visit class function bodies, but skip nested classes. + # for CFB: class_function_body in lhs { + # skipping class_specifier + # + # # Reparse the text of the class function body as a function body + # function_body FB = parse function_body[ $CFB ] + # + # # Replace the class function body with the parsed function body. + # CFB = cons class_function_body [FB.tree] + # } + } + + def class_head + [class_key] + { + nsType: int = declaredClassType() + + # LOG print( 'creating new anonymous class\n' ) + newClass: lang_object = createLangObject( nsType + '<anon_class>' lookupNs->tail->Obj ) + + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = newClass + lookupNs->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = newClass + declNs->push_tail( E2 ) + } + + | [class_key nested_name_specifier_opt class_head_name] + { + Id: lookup_id = lookup_id in r3 + name: str = Id.data + + # Get the ns the class is declared in. + parentObj: lang_object = declNs->tail->Obj + if Id.qualObj + parentObj = Id.qualObj + + # Look for the class in the given scope. + declaredClass: lang_object = findClass( parentObj name ) + if !declaredClass + declaredClass = findTemplateClass( parentObj name ) + + if !declaredClass { + # LOG print( 'creating new class: ' name '\n' ) + + # Class does not exist in the parent scope, create it. + nsType: int = declaredClassType() + + declaredClass = createLangObject( nsType name lookupNs->tail->Obj ) + + # FIXME: handle friends. Make the class visible only if we are NOT + # in a friend declaration. The new class object is necessary to + # properly process the body of the class. + if declarationData->tail->isFriend == 0 + insertObject( parentObj name declaredClass ) + } + + # Push the found/new class. + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = declaredClass + lookupNs->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = declaredClass + declNs->push_tail( E2 ) + } + + | [class_key nested_name_specifier_opt templ_class_id + templ_arg_open template_argument_list_opt templ_arg_close] + { + match r3 [Id: lookup_id] + id: str = Id.data + classObj: lang_object = Id.obj + + # TODO: Try to find the specializaition in the template class object. + # TypeList typeList; + # makeTypeList( typeList $6->last ); + + declaredClass: lang_object + #declaredClass = classObj->findSpecExact( typeList ); + if !declaredClass { + # LOG print( 'making new template specialization\n' ) + nsType: int = declaredClassType() + declaredClass = createLangObject( nsType id lookupNs->tail->Obj ) + # LOG print( 'declaredClass: ' declaredClass '\n' ) + declaredClass->specializationOf = classObj + # $$->typeListMapEl = classObj->typeListMap.insert( typeList declaredClass ); + } + + # Push the found/new class. + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = declaredClass + lookupNs->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = declaredClass + declNs->push_tail( E2 ) + } + + def class_body_end + [] + { + # Pop the class ns. + lookupNs->pop_tail() + declNs->pop_tail() + + # LOG print( 'closing off class\n' ) + } + + def class_head_name + [class_id] + | [templ_class_id] + | [namespace_id] + | [typedef_id] + | [enum_id] + | [unknown_id] + | [identifier] + | [template_id] + + def class_key + [`class] + | [`struct] + | [`union] + + def class_member_rep + [class_member_rep class_member] + | [] + + def class_member + [member_declaration] + | [access_specifier `:] + + def member_declaration + [declaration_start member_declaration_forms declaration_end `;] + | [class_function_definition] + | [using_declaration] + | [template_declaration] + + def class_function_definition + [function_def_declaration ctor_initializer_opt class_function_body function_def_end] + + lex + token cfb_open /'{'/ + token cfb_close /'}'/ + token cfb_string / + "'" ( [^'\\\n] | '\\' any )* "'" | + '"' ( [^"\\\n] | '\\' any )* '"'/ + token cfb_comment / + ( '/*' (any | '\n')* :>> '*/' ) | + ( '//' any* :> '\n' )/ + token cfb_data /[^{}'"/]+ | '/'/ + end + + def cfb_item + [cfb_data] + | [cfb_string] + | [cfb_comment] + | [cfb_open cfb_item* cfb_close] + + def cfb_conts + [cfb_item* cfb_close] + + + + def class_function_body + # ['{' cfb_conts] + #| [function_body] + [function_body] + + # Get better performance if the form with decl_specifier_sing comes first. + def member_declaration_forms + [decl_specifier_mult_seq_opt decl_specifier_sing + decl_specifier_mult_seq_opt member_declarator_list_opt] + | [decl_specifier_mult_seq_opt member_declarator_list_opt] + + def member_declarator_list_opt + [member_declarator_list] + | [] + + def member_declarator_list + [member_declarator_list `, member_declarator] + | [member_declarator] + + def member_declarator + [declarator] + | [declarator `= constant_expression] + | [declarator `: constant_expression] + | [`: constant_expression] + + def access_specifier + [`private] + | [`protected] + | [`public] + + def access_specifier_opt + [access_specifier] + | [] + + def using_declaration + [`using id_expression `;] + { + obj: lang_object = r2.lookupId.obj + if obj + insertObject( declNs->tail->Obj obj->name obj ) + } + + | [`using type_id `;] + { + obj: lang_object = r2.lookupId.obj + if obj + insertObject( declNs->tail->Obj obj->name obj ) + } + + def using_directive + [`using `namespace root_qual_opt nested_name_specifier_opt + namespace_id `;] + { + # This uses a simple, incomplete guard against cycles in the graph of + # using namespaces. A more sophisticated and complete guard would look + # for longer cycles as well. Note that even gcc 3.3.5 does not bother. + match r5 [Id: lookup_id] + usingObject: lang_object = Id.obj + inObject: lang_object = declNs->tail->Obj + if usingObject != inObject { + E: list_lang_object_el = new list_lang_object_el + E->Obj = usingObject + inObject->inherited->push_tail( E ) + } + } + + + # + # Derived classes + # + + def base_clause_opt + [base_clause] + | [] + + def base_clause + [`: base_specifier_list] + + def base_specifier_list + [base_specifier_list `, base_specifier] + | [base_specifier] + + int addBaseSpecifier( inObject: lang_object inheritedObject: lang_object ) + { + # Resolve typedefs. + if inheritedObject->typeId == TypedefType + inheritedObject = inheritedObject->typedefOf + + E: list_lang_object_el = new list_lang_object_el + E->Obj = inheritedObject + inObject->inherited->push_tail( E ) + } + + def base_specifier + [root_qual_opt nested_name_specifier_opt type_name] + { + addBaseSpecifier( declNs->tail->Obj r3.lookupId.obj ) + } + + | [`virtual access_specifier_opt root_qual_opt nested_name_specifier_opt type_name] + { + addBaseSpecifier( declNs->tail->Obj r5.lookupId.obj ) + } + + | [access_specifier virtual_opt root_qual_opt nested_name_specifier_opt type_name] + { + addBaseSpecifier( declNs->tail->Obj r5.lookupId.obj ) + } + + def virtual_opt + [`virtual] + | [] + + # + # Special member functions + # + + def conversion_function_id + [`operator conversion_type_id] + + def conversion_type_id + [necs_type_specifier_seq ptr_operator_seq_opt] + + def ctor_initializer_opt + [ctor_initializer] + | [] + + def ctor_initializer + [`: mem_initializer_list] + + def mem_initializer_list + [mem_initializer_list `, mem_initializer] + | [mem_initializer] + + def mem_initializer + [mem_initializer_id `( expression_opt `)] + + def mem_initializer_id + [root_qual_opt nested_name_specifier_opt unknown_id] + | [root_qual_opt nested_name_specifier_opt identifier] + | [root_qual_opt nested_name_specifier_opt type_name] + | [root_qual_opt nested_name_specifier_opt template_name] + + + # + # Overloading + # + def operator_function_id + [`operator operator] + + def operator + [`+] | [`-] | [`*] | [`/] | [`=] | [`<] | [`>] | [`&] | [`|] | + [`^] | [`%] | [`~] | [`!] | [`( `)] | [`[ `]] | [`new] | + [`delete] | [`->] | [`++] | [`--] | [`*=] | [`/=] | [`%=] | + [`+=] | [`-=] | [`>>=] | [`<<=] | [`&=] | [`^=] | [`|=] | [`==] | + [`!=] | [`&&] | [`||] | [lt_eq] | [gt_eq] | [shift_left] | [shift_right] + + def lt_eq + [`< `=] + # try { + # if ( $2->leader != 0 ) { + # #ifdef LOG_REDUCE + # cerr << "rejecting less-than equals-to" << endl; + # #endif + # reject(); + # } + # }; + + def gt_eq + [`> `=] + # try { + # if ( $2->leader != 0 ) { + # #ifdef LOG_REDUCE + # cerr << "rejecting greater-than equals-to" << endl; + # #endif + # reject(); + # } + # }; + + def shift_left + [`< `<] + # try { + # if ( $2->leader != 0 ) { + # #ifdef LOG_REDUCE + # cerr << "rejecting shift left" << endl; + # #endif + # reject(); + # } + # }; + + def shift_right + [`> `>] + # try { + # if ( $2->leader != 0 ) { + # #ifdef LOG_REDUCE + # cerr << "rejecting shift right" << endl; + # #endif + # reject(); + # } + # }; + + # + # Templates + # + + def template_declaration + [template_declaration_params declaration] + { + templDecl->pop_tail() + templateParamNs->pop_tail() + } + + def template_declaration_params + [`template `< tpl_start template_parameter_list `>] + { + IntEl: list_int_el = new list_int_el + IntEl->Int = 1 + templDecl->push_tail( IntEl ) + } + + | [`export `template `< tpl_start template_parameter_list `>] + { + IntEl: list_int_el = new list_int_el + IntEl->Int = 1 + templDecl->push_tail( IntEl ) + } + + def tpl_start + [] + { + # Create a new scope for the template parameters. + newTemplateParamScope: lang_object = + createLangObject( 0 '<tpl_start>' lookupNs->tail->Obj ) + + E: list_lang_object_el = new list_lang_object_el + E->Obj = newTemplateParamScope + templateParamNs->push_tail( E ) + } + + def template_parameter_list + [template_parameter_list `, template_parameter] + | [template_parameter] + + def template_parameter + [type_parameter] + | [template_parameter_declaration] + + def template_parameter_declaration + [declaration_start template_parameter_declaration_forms declaration_end] + + def template_parameter_declaration_forms + [decl_specifier_mult_seq param_maybe_declarator maybe_parameter_init] + + | [temp_param_decl_specifier_sing decl_specifier_mult_seq_opt + param_maybe_declarator maybe_parameter_init] + + | [decl_specifier_mult_seq temp_param_decl_specifier_sing + decl_specifier_mult_seq_opt param_maybe_declarator maybe_parameter_init] + + def temp_param_decl_specifier_sing + [temp_param_type_specifier_sing] + + # Template parameters cannot support elaborated type specifer or class specifier. + def temp_param_type_specifier_sing + [templ_simple_type_specifier] + | [enum_specifier] + + def templ_simple_type_specifier + [simple_type_specifier_name] + | [simple_type_specifier_kw_seq] + + def type_parameter + [`class type_param_id type_param_init_opt] + { + Id: lookup_id = lookup_id in r2 + if Id { + # The lookup ns should be a template param scope. + newClass: lang_object = + createLangObject( ClassType Id.data lookupNs->tail->Obj ) + insertObject( templateParamNs->tail->Obj Id.data newClass ) + } + } + + | [`typename type_param_id type_param_init_opt] + { + Id: lookup_id = lookup_id in r2 + if Id { + # The lookup ns should be a template param scope. + newClass: lang_object = + createLangObject( ClassType Id.data lookupNs->tail->Obj ) + insertObject( templateParamNs->tail->Obj Id.data newClass ) + } + } + + | [`template `< tpl_start template_parameter_list `> + `class type_param_id templ_type_param_init_opt] + { + Id: lookup_id = lookup_id in r7 + if Id { + newClass: lang_object = + createLangObject( TemplateClassType Id.data lookupNs->tail->Obj ) + insertObject( templateParamNs->tail->Obj Id.data newClass ) + } + } + + def templ_type_param_init_opt + [`= id_expression] + | [] + + def type_param_init_opt + [`= type_id] + | [] + + def type_param_id + [namespace_id] + | [typedef_id] + | [enum_id] + | [class_id] + | [templ_class_id] + | [identifier] + | [template_id] + | [unknown_id] + | [] + + def template_argument_list_opt + [template_argument_list] + | [] + + def template_argument_list + [template_argument_list `, template_argument] + | [template_argument] + + def template_argument + [type_id] + | [assignment_expression] + + def explicit_instantiation + [`template declaration] + | [declaration_start decl_specifier_mult_seq `template declaration declaration_end] + + def explicit_specialization + [`template `< `> declaration] + + ## Not sure what this one is about? + #explicit_specialization: + # declaration_start decl_specifier_mult_seq KW_Template '<' '>' + # declaration declaration_end; + + + # + # Original namespace definition + # + + def original_namespace_definition + [orig_namespace_def_name `{ declaration* namespace_end `}] + + def orig_namespace_def_name [`namespace unknown_id] + { + match r2 [Id: lookup_id] + nspace: lang_object = createLangObject( + NamespaceType Id.data lookupNs->tail->Obj ) + + # Insert the new object into the dictionary of the parent. + insertObject( curNamespace->tail->Obj Id.data nspace ) + + # Push the namespace + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = nspace + curNamespace->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = nspace + declNs->push_tail( E2 ) + + E3: list_lang_object_el = new list_lang_object_el + E3->Obj = nspace + lookupNs->push_tail( E3 ) + + # LOG print( 'created original namespace: ' Id.data '\n' ) + } + + def namespace_end [] + { + # Pop the namespace. + curNamespace->pop_tail() + declNs->pop_tail() + lookupNs->pop_tail() + + # LOG print( 'closed namespace\n' ) + } + + # + # Extension namespace definition + # + + def extension_namespace_definition + [ext_namespace_def_name `{ declaration* namespace_end `}] + + def ext_namespace_def_name [`namespace namespace_id] + { + match r2 [Id: lookup_id] + nspace: lang_object = Id.obj + + # Push the namespace + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = nspace + curNamespace->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = nspace + declNs->push_tail( E2 ) + + E3: list_lang_object_el = new list_lang_object_el + E3->Obj = nspace + lookupNs->push_tail( E3 ) + + # LOG print( 'found extended namespace: ' Id.data '\n' ) + } + + # + # Unnamed namespace definition + # + def unnamed_namespace_definition + [unnamed_namespace_def_name `{ declaration* namespace_end `}] + + def unnamed_namespace_def_name [`namespace] + { + nspace: lang_object = createLangObject( + NamespaceType '<unnamed_namespace>' + lookupNs->tail->Obj ) + + # Push the namespace + E1: list_lang_object_el = new list_lang_object_el + E1->Obj = nspace + curNamespace->push_tail( E1 ) + + E2: list_lang_object_el = new list_lang_object_el + E2->Obj = nspace + declNs->push_tail( E2 ) + + E3: list_lang_object_el = new list_lang_object_el + E3->Obj = nspace + lookupNs->push_tail( E3 ) + + # LOG print( 'parsed unnamed namespace\n' ) + } + + # + # linkage_specification + # + def linkage_specification + [`extern TK_DoubleLit `{ declaration* `}] + | [`extern TK_DoubleLit declaration] + + # + # Exception Handling. + # + + def try_block + [`try compound_statement handler_seq] + + def handler_seq + [handler_seq handler] + | [handler] + + def handler + [`catch `( exception_declaration `) compound_statement] + + def exception_declaration + [type_specifier_seq declarator] + | [type_specifier_seq abstract_declarator] + | [type_specifier_seq] + | [`...] + + def throw_expression + [`throw assignment_expression] + | [`throw] + + def exception_specification_opt + [exception_specification] + | [] + + def exception_specification + [`throw `( type_id_list_opt `)] + + def type_id_list_opt + [type_id_list] + | [] + + def type_id_list + [type_id_list `, type_id] + | [type_id] + + def start + [declaration*] + + # + # Grammar done. + # + + int printObject( indent: str obj: lang_object ) + { + print( indent obj->name ) + + if obj->objectMap->length > 0 + print( ' {\n' ) + + ChildNames: map_list_lang_object = obj->objectMap + MapEl: map_list_lang_object_el = ChildNames->head + while ( MapEl ) { + El: list_lang_object_el = MapEl->List->head + while ( El ) { + printObject( indent + ' ' El->Obj ) + El = El->next + } + MapEl = MapEl->next + } + + if obj->objectMap->length > 0 + print( indent '}' ) + + print( '\n' ) + } + +end # lookup + +# +# Global data declarations +# + +Lookup: lookup = new lookup + +# Constants for language object types. +Lookup->NamespaceType = typeid<lookup::namespace_id> +Lookup->ClassType = typeid<lookup::class_id> +Lookup->TemplateClassType = typeid<lookup::templ_class_id> +Lookup->EnumType = typeid<lookup::enum_id> +Lookup->IdType = typeid<lookup::identifier> +Lookup->TypedefType = typeid<lookup::typedef_id> +Lookup->TemplateIdType = typeid<lookup::template_id> + + +# Object stacks. +Lookup->curNamespace = new lookup::list_lang_object +Lookup->declNs = new lookup::list_lang_object +Lookup->lookupNs = new lookup::list_lang_object +Lookup->qualNs = new lookup::list_lang_object +Lookup->templateParamNs = new lookup::list_lang_object + +# Declaration, declarator data. +Lookup->declarationData = new lookup::list_declaration_data +Lookup->declaratorData = new lookup::list_declarator_data + +# Template declarations +Lookup->templDecl = new lookup::list_int + +# Root namespace object +Lookup->rootNamespace = createLangObject( Lookup->NamespaceType '<root_namespace>' nil ) + +# Initialize the namespace and declaration stacks with the root namespace +E1: lookup::list_lang_object_el = new lookup::list_lang_object_el +E1->Obj = Lookup->rootNamespace +Lookup->curNamespace->push_tail( E1 ) + +E2: lookup::list_lang_object_el = new lookup::list_lang_object_el +E2->Obj = Lookup->rootNamespace +Lookup->declNs->push_tail( E2 ) + +E3: lookup::list_lang_object_el = new lookup::list_lang_object_el +E3->Obj = Lookup->rootNamespace +Lookup->lookupNs->push_tail( E3 ) + +# Start with no qualification (note variables are initialized to zero) +E4: lookup::list_lang_object_el = new lookup::list_lang_object_el +E4->Obj = nil +Lookup->qualNs->push_tail( E4 ) + +IntEl: lookup::list_int_el = new lookup::list_int_el +IntEl->Int = 0 +Lookup->templDecl->push_tail( IntEl ) + +DD: lookup::declaration_data = new lookup::declaration_data +DD->isTypedef = 0 +DD->isFriend = 0 +DD->isTemplate = 0 +Lookup->declarationData->push_tail( DD ) + +parse S: lookup::start( Lookup )[ stdin ] +if ! S { + print( error ) + exit( 1 ) +} + +print( '***** NAMSPACES *****\n' ) +printObject( '' Lookup->rootNamespace ) +print( '***** UNKNOWN DECLARATORS *****\n' ) +for DI: lookup::declarator_id in S { + if match DI + [lookup::root_qual_opt lookup::nested_name_specifier_opt lookup::`~ UID: lookup::unknown_id] + { + print( UID '\n' ) + } +} +##### IN ##### +namespace ns1 +{ + namespace sub1 { class A {}; } + namespace sub2 { class B {}; } +} + +namespace ns2 +{ + int i = b; + class C + { + }; + + using namespace ns1; +} + +ns2::sub1::A a; + +struct A +{ + struct B {}; +}; + +struct C +{ + struct D : virtual public A {}; +}; + +C::D::A d; + +C c; + +struct C +{ + +}; + +enum E +{ + C, + b +}; + +E e; + +enum E +{ + C, + b +}; + + +int i; +class C +{ + int j; +}; + +class D +{ + int ~D(); +}; + +int C::k; +int C::~C; + +typedef int Int; + +class C {}; +void ~C( ); +void C::operator +( int i ); + +int i; + +//void operator C( void k ); + +class C +{ + +}; + +int C::f( int i, int j( void v ) ); +class C +{ + class D {}; + + typedef C I; + + I::D i; +}; + +C c; + +void function( int i, int j ) +{ + function(); +} + + + +class B { class Find {}; }; + +typedef B T; + +class C : public T +{ + Find find; +}; + + +template <class X> struct Y +{ + X t; + void f(); +}; + +template <class X> void Y<X>::f(); +template <class X> struct Y +{ + class Z {}; +}; + +class Y<int> +{ + int i; +}; + +//void f( class C<int> i, int j ); + +int f( int (*) [](), void ); +void f(); +class C +{ + class D {}; + void g(); +}; + +//typename C c; + +class C +{ + class D {}; + int f(); +}; + +int f() +{ +} + +int C::f() +{ + D d; +} +##### EXP ##### +***** NAMSPACES ***** +<root_namespace> { + A { + B + } + B { + Find + } + C { + D + } + C + C + C + C { + j + } + C + C + C + C { + D + I + i + } + C { + find + } + C { + D + g + } + C { + D + f + } + D + E + E + T + Y { + Z + f + t + } + a + b + b + c + c + d + e + f + f + f + i + i + Int + ns1 { + sub1 { + A + } + sub2 { + B + } + } + ns2 { + C + i + } + function +} +***** UNKNOWN DECLARATORS ***** +C |